From 6dc662431a8cb6705fc358ccd3857a718285c0b4 Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Thu, 2 Oct 2014 01:07:20 +0000 Subject: [PATCH] Improve unit tests for WP_Tax_Query. * Exhaustive tests for publicly available functionality of WP_Tax_Query. * For tests that are related to the tax_query argument as used in WP_Query, move to tests/post/query.php. * Add some tax_query tests to cover single vs multiple queries using AND and OR; various values for 'field'; various values for 'operator'. * Improve test names. * Correct @group annotations. * Improve performance of some WP_Query-related tests by declaring 'update_post_meta/term_cache' false. Fixes #29718 git-svn-id: https://develop.svn.wordpress.org/trunk@29805 602fd350-edb4-49c9-b593-d223f7449a82 --- tests/phpunit/tests/post/query.php | 1030 +++++++++++++++++++++++++++- tests/phpunit/tests/term/query.php | 385 +++++------ 2 files changed, 1184 insertions(+), 231 deletions(-) diff --git a/tests/phpunit/tests/post/query.php b/tests/phpunit/tests/post/query.php index 45b1abcf96..fb1d977810 100644 --- a/tests/phpunit/tests/post/query.php +++ b/tests/phpunit/tests/post/query.php @@ -772,37 +772,6 @@ class Tests_Post_Query extends WP_UnitTestCase { $this->assertEqualSets( array( $post_4, $post_3, $post_2, $post_1 ), $query->posts ); } - /** - * @ticket 20604 - */ - function test_taxonomy_empty_or() { - // An empty tax query should return an empty array, not all posts. - - $this->factory->post->create_many( 10 ); - - $query = new WP_Query( array( - 'fields' => 'ids', - 'tax_query' => array( - 'relation' => 'OR', - array( - 'taxonomy' => 'post_tag', - 'field' => 'id', - 'terms' => false, - 'operator' => 'IN' - ), - array( - 'taxonomy' => 'category', - 'field' => 'id', - 'terms' => false, - 'operator' => 'IN' - ) - ) - ) ); - - $posts = $query->get_posts(); - $this->assertEquals( 0 , count( $posts ) ); - } - function test_meta_between_not_between() { $post_id = $this->factory->post->create(); add_post_meta( $post_id, 'time', 500 ); @@ -983,7 +952,534 @@ class Tests_Post_Query extends WP_UnitTestCase { $this->assertEqualSets( array( $post_id, $post_id3, $post_id4, $post_id5, $post_id6 ), $posts ); } - function test_taxonomy_include_children() { + /** + * @group taxonomy + */ + public function test_tax_query_single_query_single_term_field_slug() { + $t = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'foo', + 'name' => 'Foo', + ) ); + $p1 = $this->factory->post->create(); + $p2 = $this->factory->post->create(); + + wp_set_post_terms( $p1, $t, 'category' ); + + $q = new WP_Query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( + array( + 'taxonomy' => 'category', + 'terms' => array( 'foo' ), + 'field' => 'slug', + ), + ), + ) ); + + $this->assertEquals( array( $p1 ), $q->posts ); + } + + /** + * @group taxonomy + */ + public function test_tax_query_single_query_single_term_field_name() { + $t = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'foo', + 'name' => 'Foo', + ) ); + $p1 = $this->factory->post->create(); + $p2 = $this->factory->post->create(); + + wp_set_post_terms( $p1, $t, 'category' ); + + $q = new WP_Query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( + array( + 'taxonomy' => 'category', + 'terms' => array( 'Foo' ), + 'field' => 'name', + ), + ), + ) ); + + $this->assertEquals( array( $p1 ), $q->posts ); + } + + /** + * @group taxonomy + */ + public function test_tax_query_single_query_single_term_field_term_taxonomy_id() { + $t = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'foo', + 'name' => 'Foo', + ) ); + $p1 = $this->factory->post->create(); + $p2 = $this->factory->post->create(); + + $tt_ids = wp_set_post_terms( $p1, $t, 'category' ); + + $q = new WP_Query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( + array( + 'taxonomy' => 'category', + 'terms' => $tt_ids, + 'field' => 'term_taxonomy_id', + ), + ), + ) ); + + $this->assertEquals( array( $p1 ), $q->posts ); + } + + /** + * @group taxonomy + */ + public function test_tax_query_single_query_single_term_field_term_id() { + $t = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'foo', + 'name' => 'Foo', + ) ); + $p1 = $this->factory->post->create(); + $p2 = $this->factory->post->create(); + + wp_set_post_terms( $p1, $t, 'category' ); + + $q = new WP_Query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( + array( + 'taxonomy' => 'category', + 'terms' => array( $t ), + 'field' => 'term_id', + ), + ), + ) ); + + $this->assertEquals( array( $p1 ), $q->posts ); + } + + /** + * @group taxonomy + */ + public function test_tax_query_single_query_single_term_operator_in() { + $t = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'foo', + 'name' => 'Foo', + ) ); + $p1 = $this->factory->post->create(); + $p2 = $this->factory->post->create(); + + wp_set_post_terms( $p1, $t, 'category' ); + + $q = new WP_Query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( + array( + 'taxonomy' => 'category', + 'terms' => array( 'foo' ), + 'field' => 'slug', + 'operator' => 'IN', + ), + ), + ) ); + + $this->assertEquals( array( $p1 ), $q->posts ); + } + + /** + * @group taxonomy + */ + public function test_tax_query_single_query_single_term_operator_not_in() { + $t = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'foo', + 'name' => 'Foo', + ) ); + $p1 = $this->factory->post->create(); + $p2 = $this->factory->post->create(); + + wp_set_post_terms( $p1, $t, 'category' ); + + $q = new WP_Query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( + array( + 'taxonomy' => 'category', + 'terms' => array( 'foo' ), + 'field' => 'slug', + 'operator' => 'NOT IN', + ), + ), + ) ); + + $this->assertEquals( array( $p2 ), $q->posts ); + } + + /** + * @group taxonomy + */ + public function test_tax_query_single_query_single_term_operator_and() { + $t = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'foo', + 'name' => 'Foo', + ) ); + $p1 = $this->factory->post->create(); + $p2 = $this->factory->post->create(); + + wp_set_post_terms( $p1, $t, 'category' ); + + $q = new WP_Query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( + array( + 'taxonomy' => 'category', + 'terms' => array( 'foo' ), + 'field' => 'slug', + 'operator' => 'AND', + ), + ), + ) ); + + $this->assertEquals( array( $p1 ), $q->posts ); + } + + /** + * @group taxonomy + */ + public function test_tax_query_single_query_multiple_terms_operator_in() { + $t1 = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'foo', + 'name' => 'Foo', + ) ); + $t2 = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'bar', + 'name' => 'Bar', + ) ); + $p1 = $this->factory->post->create(); + $p2 = $this->factory->post->create(); + $p3 = $this->factory->post->create(); + + wp_set_post_terms( $p1, $t1, 'category' ); + wp_set_post_terms( $p2, $t2, 'category' ); + + $q = new WP_Query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( + array( + 'taxonomy' => 'category', + 'terms' => array( 'foo', 'bar' ), + 'field' => 'slug', + 'operator' => 'IN', + ), + ), + ) ); + + $this->assertEquals( array( $p1, $p2 ), $q->posts ); + } + + /** + * @group taxonomy + */ + public function test_tax_query_single_query_multiple_terms_operator_not_in() { + $t1 = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'foo', + 'name' => 'Foo', + ) ); + $t2 = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'bar', + 'name' => 'Bar', + ) ); + $p1 = $this->factory->post->create(); + $p2 = $this->factory->post->create(); + $p3 = $this->factory->post->create(); + + wp_set_post_terms( $p1, $t1, 'category' ); + wp_set_post_terms( $p2, $t2, 'category' ); + + $q = new WP_Query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( + array( + 'taxonomy' => 'category', + 'terms' => array( 'foo', 'bar' ), + 'field' => 'slug', + 'operator' => 'NOT IN', + ), + ), + ) ); + + $this->assertEquals( array( $p3 ), $q->posts ); + } + + /** + * @group taxonomy + */ + public function test_tax_query_single_query_multiple_terms_operator_and() { + $t1 = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'foo', + 'name' => 'Foo', + ) ); + $t2 = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'bar', + 'name' => 'Bar', + ) ); + $p1 = $this->factory->post->create(); + $p2 = $this->factory->post->create(); + $p3 = $this->factory->post->create(); + + wp_set_object_terms( $p1, $t1, 'category' ); + wp_set_object_terms( $p2, array( $t1, $t2 ), 'category' ); + + $q = new WP_Query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( + array( + 'taxonomy' => 'category', + 'terms' => array( 'foo', 'bar' ), + 'field' => 'slug', + 'operator' => 'AND', + ), + ), + ) ); + + $this->assertEquals( array( $p2 ), $q->posts ); + } + + /** + * @group taxonomy + */ + public function test_tax_query_multiple_queries_relation_and() { + $t1 = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'foo', + 'name' => 'Foo', + ) ); + $t2 = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'bar', + 'name' => 'Bar', + ) ); + $p1 = $this->factory->post->create(); + $p2 = $this->factory->post->create(); + $p3 = $this->factory->post->create(); + + wp_set_object_terms( $p1, $t1, 'category' ); + wp_set_object_terms( $p2, array( $t1, $t2 ), 'category' ); + + $q = new WP_Query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( + 'relation' => 'AND', + array( + 'taxonomy' => 'category', + 'terms' => array( 'foo' ), + 'field' => 'slug', + ), + array( + 'taxonomy' => 'category', + 'terms' => array( 'bar' ), + 'field' => 'slug', + ), + ), + ) ); + + $this->assertEquals( array( $p2 ), $q->posts ); + } + + /** + * @group taxonomy + */ + public function test_tax_query_multiple_queries_relation_or() { + $t1 = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'foo', + 'name' => 'Foo', + ) ); + $t2 = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'bar', + 'name' => 'Bar', + ) ); + $p1 = $this->factory->post->create(); + $p2 = $this->factory->post->create(); + $p3 = $this->factory->post->create(); + + wp_set_object_terms( $p1, $t1, 'category' ); + wp_set_object_terms( $p2, array( $t1, $t2 ), 'category' ); + + $q = new WP_Query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( + 'relation' => 'OR', + array( + 'taxonomy' => 'category', + 'terms' => array( 'foo' ), + 'field' => 'slug', + ), + array( + 'taxonomy' => 'category', + 'terms' => array( 'bar' ), + 'field' => 'slug', + ), + ), + ) ); + + $this->assertEquals( array( $p1, $p2 ), $q->posts ); + } + + /** + * @group taxonomy + */ + public function test_tax_query_multiple_queries_different_taxonomies() { + $t1 = $this->factory->term->create( array( + 'taxonomy' => 'post_tag', + 'slug' => 'foo', + 'name' => 'Foo', + ) ); + $t2 = $this->factory->term->create( array( + 'taxonomy' => 'category', + 'slug' => 'bar', + 'name' => 'Bar', + ) ); + $p1 = $this->factory->post->create(); + $p2 = $this->factory->post->create(); + $p3 = $this->factory->post->create(); + + wp_set_object_terms( $p1, $t1, 'post_tag' ); + wp_set_object_terms( $p2, $t2, 'category' ); + + $q = new WP_Query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( + 'relation' => 'OR', + array( + 'taxonomy' => 'post_tag', + 'terms' => array( 'foo' ), + 'field' => 'slug', + ), + array( + 'taxonomy' => 'category', + 'terms' => array( 'bar' ), + 'field' => 'slug', + ), + ), + ) ); + + $this->assertEquals( array( $p1, $p2 ), $q->posts ); + } + + /** + * @ticket 20604 + * @group taxonomy + */ + public function test_tax_query_relation_or_both_clauses_empty_terms() { + // An empty tax query should return an empty array, not all posts. + + $this->factory->post->create_many( 10 ); + + $query = new WP_Query( array( + 'fields' => 'ids', + 'update_post_term_cache' => false, + 'update_post_meta_cache' => false, + 'tax_query' => array( + 'relation' => 'OR', + array( + 'taxonomy' => 'post_tag', + 'field' => 'id', + 'terms' => false, + 'operator' => 'IN' + ), + array( + 'taxonomy' => 'category', + 'field' => 'id', + 'terms' => false, + 'operator' => 'IN' + ), + ) + ) ); + + $posts = $query->get_posts(); + $this->assertEquals( 0 , count( $posts ) ); + } + + /** + * @ticket 20604 + * @group taxonomy + */ + public function test_tax_query_relation_or_one_clause_empty_terms() { + // An empty tax query should return an empty array, not all posts. + + $this->factory->post->create_many( 10 ); + + $query = new WP_Query( array( + 'fields' => 'ids', + 'update_post_term_cache' => false, + 'update_post_meta_cache' => false, + 'tax_query' => array( + 'relation' => 'OR', + array( + 'taxonomy' => 'post_tag', + 'field' => 'id', + 'terms' => array( 'foo' ), + 'operator' => 'IN' + ), + array( + 'taxonomy' => 'category', + 'field' => 'id', + 'terms' => false, + 'operator' => 'IN' + ), + ) + ) ); + + $posts = $query->get_posts(); + $this->assertEquals( 0 , count( $posts ) ); + } + + /** + * @group taxonomy + */ + public function test_tax_query_include_children() { $cat_a = $this->factory->term->create( array( 'taxonomy' => 'category', 'name' => 'Australia' ) ); $cat_b = $this->factory->term->create( array( 'taxonomy' => 'category', 'name' => 'Sydney', 'parent' => $cat_a ) ); $cat_c = $this->factory->term->create( array( 'taxonomy' => 'category', 'name' => 'East Syndney', 'parent' => $cat_b ) ); @@ -995,6 +1491,9 @@ class Tests_Post_Query extends WP_UnitTestCase { $post_d = $this->factory->post->create( array( 'post_category' => array( $cat_d ) ) ); $posts = get_posts( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, 'tax_query' => array( array( 'taxonomy' => 'category', @@ -1007,6 +1506,9 @@ class Tests_Post_Query extends WP_UnitTestCase { $this->assertEquals( 4 , count( $posts ) ); $posts = get_posts( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, 'tax_query' => array( array( 'taxonomy' => 'category', @@ -1020,6 +1522,9 @@ class Tests_Post_Query extends WP_UnitTestCase { $this->assertEquals( 1 , count( $posts ) ); $posts = get_posts( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, 'tax_query' => array( array( 'taxonomy' => 'category', @@ -1032,6 +1537,9 @@ class Tests_Post_Query extends WP_UnitTestCase { $this->assertEquals( 3 , count( $posts ) ); $posts = get_posts( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, 'tax_query' => array( array( 'taxonomy' => 'category', @@ -1045,6 +1553,9 @@ class Tests_Post_Query extends WP_UnitTestCase { $this->assertEquals( 1 , count( $posts ) ); $posts = get_posts( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, 'tax_query' => array( array( 'taxonomy' => 'category', @@ -1057,6 +1568,9 @@ class Tests_Post_Query extends WP_UnitTestCase { $this->assertEquals( 1 , count( $posts ) ); $posts = get_posts( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, 'tax_query' => array( array( 'taxonomy' => 'category', @@ -1070,6 +1584,458 @@ class Tests_Post_Query extends WP_UnitTestCase { $this->assertEquals( 1 , count( $posts ) ); } + /** + * @group taxonomy + */ + function test_category__and_var() { + $q = new WP_Query(); + + $term_id = $this->factory->category->create( array( 'slug' => 'woo', 'name' => 'WOO!' ) ); + $term_id2 = $this->factory->category->create( array( 'slug' => 'hoo', 'name' => 'HOO!' ) ); + $post_id = $this->factory->post->create(); + + wp_set_post_categories( $post_id, $term_id ); + + $posts = $q->query( array( 'category__and' => array( $term_id ) ) ); + + $this->assertEmpty( $q->get( 'category__and' ) ); + $this->assertCount( 0, $q->get( 'category__and' ) ); + $this->assertNotEmpty( $q->get( 'category__in' ) ); + $this->assertCount( 1, $q->get( 'category__in' ) ); + + $this->assertNotEmpty( $posts ); + $this->assertEquals( array( $post_id ), wp_list_pluck( $posts, 'ID' ) ); + + $posts2 = $q->query( array( 'category__and' => array( $term_id, $term_id2 ) ) ); + $this->assertNotEmpty( $q->get( 'category__and' ) ); + $this->assertCount( 2, $q->get( 'category__and' ) ); + $this->assertEmpty( $q->get( 'category__in' ) ); + $this->assertCount( 0, $q->get( 'category__in' ) ); + + $this->assertEmpty( $posts2 ); + } + + /** + * @group taxonomy + */ + public function test_tax_query_taxonomy_with_attachments() { + $q = new WP_Query(); + + register_taxonomy_for_object_type( 'post_tag', 'attachment:image' ); + $tag_id = $this->factory->term->create( array( 'slug' => rand_str(), 'name' => rand_str() ) ); + $image_id = $this->factory->attachment->create_object( 'image.jpg', 0, array( + 'post_mime_type' => 'image/jpeg', + 'post_type' => 'attachment' + ) ); + wp_set_object_terms( $image_id, $tag_id, 'post_tag' ); + + $posts = $q->query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'post_type' => 'attachment', + 'post_status' => 'inherit', + 'tax_query' => array( + array( + 'taxonomy' => 'post_tag', + 'field' => 'term_id', + 'terms' => array( $tag_id ) + ) + ) + ) ); + + $this->assertEquals( array( $image_id ), $posts ); + } + + /** + * @ticket 27193 + * @group taxonomy + */ + function test_cat_or_tag() { + $category1 = $this->factory->term->create( array( 'taxonomy' => 'category', 'name' => 'alpha' ) ); + $category2 = $this->factory->term->create( array( 'taxonomy' => 'category', 'name' => 'beta' ) ); + + $tag1 = $this->factory->term->create( array( 'taxonomy' => 'post_tag', 'name' => 'gamma' ) ); + $tag2 = $this->factory->term->create( array( 'taxonomy' => 'post_tag', 'name' => 'delta' ) ); + + $post_id1 = $this->factory->post->create( array( 'post_title' => 'alpha', 'post_category' => array( $category1 ) ) ); + $terms1 = get_the_category( $post_id1 ); + $this->assertEquals( array( get_category( $category1 ) ), $terms1 ); + + $post_id2 = $this->factory->post->create( array( 'post_title' => 'beta', 'post_category' => array( $category2 ) ) ); + $terms2 = get_the_category( $post_id2 ); + $this->assertEquals( array( get_category( $category2 ) ), $terms2 ); + + $post_id3 = $this->factory->post->create( array( 'post_title' => 'gamma', 'post_tag' => array( $tag1 ) ) ); + $post_id4 = $this->factory->post->create( array( 'post_title' => 'delta', 'post_tag' => array( $tag2 ) ) ); + + $query = new WP_Query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( + //'relation' => 'OR', + array( + 'taxonomy' => 'category', + 'field' => 'term_id', + 'terms' => array( $category1, $category2 ) + ) + ) + ) ); + $ids = $query->get_posts(); + $this->assertEquals( array( $post_id1, $post_id2 ), $ids ); + } + + /** + * @group taxonomy + */ + function test_tax_query_no_taxonomy() { + $cat_id = $this->factory->category->create( array( 'name' => 'alpha' ) ); + $this->factory->post->create( array( 'post_title' => 'alpha', 'post_category' => array( $cat_id ) ) ); + + $response1 = new WP_Query( array( + 'tax_query' => array( + array( 'terms' => array( $cat_id ) ) + ) + ) ); + $this->assertEmpty( $response1->posts ); + + $response2 = new WP_Query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( + array( + 'taxonomy' => 'category', + 'terms' => array( $cat_id ) + ) + ) + ) ); + $this->assertNotEmpty( $response2->posts ); + + $term = get_category( $cat_id ); + $response3 = new WP_Query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( + array( + 'field' => 'term_taxonomy_id', + 'terms' => array( $term->term_taxonomy_id ) + ) + ) + ) ); + $this->assertNotEmpty( $response3->posts ); + } + + /** + * @group taxonomy + */ + function test_term_taxonomy_id_field_no_taxonomy() { + $q = new WP_Query(); + + $posts = $this->factory->post->create_many( 5 ); + + $cats = $tags = array(); + + // need term_taxonomy_ids in addition to term_ids, so no factory + for ( $i = 0; $i < 5; $i++ ) { + $cats[$i] = wp_insert_term( 'category-' . $i , 'category' ); + $tags[$i] = wp_insert_term( 'tag-' . $i, 'post_tag' ); + + // post 0 gets all terms + wp_set_object_terms( $posts[0], array( $cats[$i]['term_id'] ), 'category', true ); + wp_set_object_terms( $posts[0], array( $tags[$i]['term_id'] ), 'post_tag', true ); + } + + wp_set_object_terms( $posts[1], array( $cats[0]['term_id'], $cats[2]['term_id'], $cats[4]['term_id'] ), 'category' ); + wp_set_object_terms( $posts[1], array( $tags[0]['term_id'], $tags[2]['term_id'], $cats[4]['term_id'] ), 'post_tag' ); + + wp_set_object_terms( $posts[2], array( $cats[1]['term_id'], $cats[3]['term_id'] ), 'category' ); + wp_set_object_terms( $posts[2], array( $tags[1]['term_id'], $tags[3]['term_id'] ), 'post_tag' ); + + wp_set_object_terms( $posts[3], array( $cats[0]['term_id'], $cats[2]['term_id'], $cats[4]['term_id'] ), 'category' ); + wp_set_object_terms( $posts[3], array( $tags[1]['term_id'], $tags[3]['term_id'] ), 'post_tag' ); + + $results1 = $q->query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'orderby' => 'ID', + 'order' => 'ASC', + 'tax_query' => array( + 'relation' => 'OR', + array( + 'field' => 'term_taxonomy_id', + 'terms' => array( $cats[0]['term_taxonomy_id'], $cats[2]['term_taxonomy_id'], $cats[4]['term_taxonomy_id'], $tags[0]['term_taxonomy_id'], $tags[2]['term_taxonomy_id'], $cats[4]['term_taxonomy_id'] ), + 'operator' => 'AND', + 'include_children' => false, + ), + array( + 'field' => 'term_taxonomy_id', + 'terms' => array( $cats[1]['term_taxonomy_id'], $cats[3]['term_taxonomy_id'], $tags[1]['term_taxonomy_id'], $tags[3]['term_taxonomy_id'] ), + 'operator' => 'AND', + 'include_children' => false, + ) + ) + ) ); + + $this->assertEquals( array( $posts[0], $posts[1], $posts[2] ), $results1, 'Relation: OR; Operator: AND' ); + + $results2 = $q->query( array( + 'fields' => 'ids', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'orderby' => 'ID', + 'order' => 'ASC', + 'tax_query' => array( + 'relation' => 'AND', + array( + 'field' => 'term_taxonomy_id', + 'terms' => array( $cats[0]['term_taxonomy_id'], $tags[0]['term_taxonomy_id'] ), + 'operator' => 'IN', + 'include_children' => false, + ), + array( + 'field' => 'term_taxonomy_id', + 'terms' => array( $cats[3]['term_taxonomy_id'], $tags[3]['term_taxonomy_id'] ), + 'operator' => 'IN', + 'include_children' => false, + ) + ) + ) ); + + $this->assertEquals( array( $posts[0], $posts[3] ), $results2, 'Relation: AND; Operator: IN' ); + } + + /** + * @ticket 28099 + * @group taxonomy + */ + function test_empty_category__in() { + $cat_id = $this->factory->category->create(); + $post_id = $this->factory->post->create(); + wp_set_post_categories( $post_id, $cat_id ); + + $q1 = get_posts( array( 'category__in' => array( $cat_id ) ) ); + $this->assertNotEmpty( $q1 ); + $q2 = get_posts( array( 'category__in' => array() ) ); + $this->assertNotEmpty( $q2 ); + + $tag = wp_insert_term( 'woo', 'post_tag' ); + $tag_id = $tag['term_id']; + $slug = get_tag( $tag_id )->slug; + wp_set_post_tags( $post_id, $slug ); + + $q3 = get_posts( array( 'tag__in' => array( $tag_id ) ) ); + $this->assertNotEmpty( $q3 ); + $q4 = get_posts( array( 'tag__in' => array() ) ); + $this->assertNotEmpty( $q4 ); + + $q5 = get_posts( array( 'tag_slug__in' => array( $slug ) ) ); + $this->assertNotEmpty( $q5 ); + $q6 = get_posts( array( 'tag_slug__in' => array() ) ); + $this->assertNotEmpty( $q6 ); + } + + /** + * @group taxonomy + * @ticket 29718 + */ + public function test_populate_taxonomy_query_var_from_tax_query() { + register_taxonomy( 'foo', 'post' ); + $t = $this->factory->term->create( array( + 'taxonomy' => 'foo', + ) ); + $c = $this->factory->term->create( array( + 'taxonomy' => 'category', + ) ); + + $q = new WP_Query( array( + 'tax_query' => array( + // Empty terms mean that this one should be skipped + array( + 'taxonomy' => 'bar', + 'terms' => array(), + ), + + // Category and post tags should be skipped + array( + 'taxonomy' => 'category', + 'terms' => array( $c ), + ), + + array( + 'taxonomy' => 'foo', + 'terms' => array( $t ), + ), + ), + ) ); + + $this->assertSame( 'foo', $q->get( 'taxonomy' ) ); + + _unregister_taxonomy( 'foo' ); + } + + /** + * @group taxonomy + */ + public function test_populate_taxonomy_query_var_from_tax_query_taxonomy_already_set() { + register_taxonomy( 'foo', 'post' ); + register_taxonomy( 'foo1', 'post' ); + $t = $this->factory->term->create( array( + 'taxonomy' => 'foo', + ) ); + + $q = new WP_Query( array( + 'taxonomy' => 'bar', + 'tax_query' => array( + array( + 'taxonomy' => 'foo', + 'terms' => array( $t ), + ), + ), + ) ); + + $this->assertSame( 'bar', $q->get( 'taxonomy' ) ); + + _unregister_taxonomy( 'foo' ); + _unregister_taxonomy( 'foo1' ); + } + + /** + * @group taxonomy + */ + public function test_populate_term_query_var_from_tax_query() { + register_taxonomy( 'foo', 'post' ); + $t = $this->factory->term->create( array( + 'taxonomy' => 'foo', + 'slug' => 'bar', + ) ); + + $q = new WP_Query( array( + 'tax_query' => array( + array( + 'taxonomy' => 'foo', + 'terms' => array( 'bar' ), + 'field' => 'slug', + ), + ), + ) ); + + $this->assertSame( 'bar', $q->get( 'term' ) ); + + _unregister_taxonomy( 'foo' ); + } + + /** + * @group taxonomy + */ + public function test_populate_term_id_query_var_from_tax_query() { + register_taxonomy( 'foo', 'post' ); + $t = $this->factory->term->create( array( + 'taxonomy' => 'foo', + 'slug' => 'bar', + ) ); + + $q = new WP_Query( array( + 'tax_query' => array( + array( + 'taxonomy' => 'foo', + 'terms' => array( $t ), + 'field' => 'term_id', + ), + ), + ) ); + + $this->assertEquals( $t, $q->get( 'term_id' ) ); + + _unregister_taxonomy( 'foo' ); + } + + /** + * @group taxonomy + * @ticket 29718 + */ + public function test_populate_cat_category_name_query_var_from_tax_query() { + register_taxonomy( 'foo', 'post' ); + $t = $this->factory->term->create( array( + 'taxonomy' => 'foo', + ) ); + $c = $this->factory->term->create( array( + 'taxonomy' => 'foo', + 'slug' => 'bar', + ) ); + + $q = new WP_Query( array( + 'tax_query' => array( + // Non-category should be skipped + array( + 'taxonomy' => 'foo', + 'terms' => array( $t ), + ), + + // Empty terms mean that this one should be skipped + array( + 'taxonomy' => 'category', + 'terms' => array(), + ), + + // Category and post tags should be skipped + array( + 'taxonomy' => 'category', + 'terms' => array( $c ), + ), + ), + ) ); + + $this->assertEquals( $c, $q->get( 'cat' ) ); + $this->assertEquals( 'bar', $q->get( 'category_name' ) ); + + _unregister_taxonomy( 'foo' ); + } + + /** + * @group taxonomy + * @ticket 29718 + */ + public function test_populate_tag_id_query_var_from_tax_query() { + register_taxonomy( 'foo', 'post' ); + $t = $this->factory->term->create( array( + 'taxonomy' => 'foo', + ) ); + $tag = $this->factory->term->create( array( + 'taxonomy' => 'post_tag', + 'slug' => 'bar', + ) ); + + $q = new WP_Query( array( + 'tax_query' => array( + // Non-tag should be skipped + array( + 'taxonomy' => 'foo', + 'terms' => array( $t ), + ), + + // Empty terms mean that this one should be skipped + array( + 'taxonomy' => 'post_tag', + 'terms' => array(), + ), + + // Category and post tags should be skipped + array( + 'taxonomy' => 'post_tag', + 'terms' => array( $tag ), + ), + ), + ) ); + + $this->assertEquals( $tag, $q->get( 'tag_id' ) ); + + _unregister_taxonomy( 'foo' ); + } + /** * @ticket 22448 */ diff --git a/tests/phpunit/tests/term/query.php b/tests/phpunit/tests/term/query.php index 0a3c724d5a..5d839cb5c9 100644 --- a/tests/phpunit/tests/term/query.php +++ b/tests/phpunit/tests/term/query.php @@ -6,229 +6,216 @@ class Tests_Tax_Query extends WP_UnitTestCase { protected $q; - function setUp() { + public function setUp() { parent::setUp(); unset( $this->q ); $this->q = new WP_Query(); } - function test_category__and_var() { - $term_id = $this->factory->category->create( array( 'slug' => 'woo', 'name' => 'WOO!' ) ); - $term_id2 = $this->factory->category->create( array( 'slug' => 'hoo', 'name' => 'HOO!' ) ); - $post_id = $this->factory->post->create(); - - wp_set_post_categories( $post_id, $term_id ); - - $posts = $this->q->query( array( 'category__and' => array( $term_id ) ) ); - - $this->assertEmpty( $this->q->get( 'category__and' ) ); - $this->assertCount( 0, $this->q->get( 'category__and' ) ); - $this->assertNotEmpty( $this->q->get( 'category__in' ) ); - $this->assertCount( 1, $this->q->get( 'category__in' ) ); - - $this->assertNotEmpty( $posts ); - $this->assertEquals( array( $post_id ), wp_list_pluck( $posts, 'ID' ) ); - - $posts2 = $this->q->query( array( 'category__and' => array( $term_id, $term_id2 ) ) ); - $this->assertNotEmpty( $this->q->get( 'category__and' ) ); - $this->assertCount( 2, $this->q->get( 'category__and' ) ); - $this->assertEmpty( $this->q->get( 'category__in' ) ); - $this->assertCount( 0, $this->q->get( 'category__in' ) ); - - $this->assertEmpty( $posts2 ); + public function test_construct_with_relation_default() { + $tq = new WP_Tax_Query( array() ); + $this->assertSame( 'AND', $tq->relation ); } - function test_taxonomy_with_attachments() { - register_taxonomy_for_object_type( 'post_tag', 'attachment:image' ); - $tag_id = $this->factory->term->create( array( 'slug' => rand_str(), 'name' => rand_str() ) ); - $image_id = $this->factory->attachment->create_object( 'image.jpg', 0, array( - 'post_mime_type' => 'image/jpeg', - 'post_type' => 'attachment' + public function test_construct_with_relation_or_lowercase() { + $tq = new WP_Tax_Query( array( + 'relation' => 'or', ) ); - wp_set_object_terms( $image_id, $tag_id, 'post_tag' ); - - $posts = $this->q->query( array( - 'fields' => 'ids', - 'post_type' => 'attachment', - 'post_status' => 'inherit', - 'tax_query' => array( - array( - 'taxonomy' => 'post_tag', - 'field' => 'term_id', - 'terms' => array( $tag_id ) - ) - ) - ) ); - - $this->assertEquals( array( $image_id ), $posts ); + $this->assertSame( 'OR', $tq->relation ); } - /** - * @ticket 27193 - */ - function test_cat_or_tag() { - $category1 = $this->factory->term->create( array( 'taxonomy' => 'category', 'name' => 'alpha' ) ); - $category2 = $this->factory->term->create( array( 'taxonomy' => 'category', 'name' => 'beta' ) ); - - $tag1 = $this->factory->term->create( array( 'taxonomy' => 'post_tag', 'name' => 'gamma' ) ); - $tag2 = $this->factory->term->create( array( 'taxonomy' => 'post_tag', 'name' => 'delta' ) ); - - $post_id1 = $this->factory->post->create( array( 'post_title' => 'alpha', 'post_category' => array( $category1 ) ) ); - $terms1 = get_the_category( $post_id1 ); - $this->assertEquals( array( get_category( $category1 ) ), $terms1 ); - - $post_id2 = $this->factory->post->create( array( 'post_title' => 'beta', 'post_category' => array( $category2 ) ) ); - $terms2 = get_the_category( $post_id2 ); - $this->assertEquals( array( get_category( $category2 ) ), $terms2 ); - - $post_id3 = $this->factory->post->create( array( 'post_title' => 'gamma', 'post_tag' => array( $tag1 ) ) ); - $post_id4 = $this->factory->post->create( array( 'post_title' => 'delta', 'post_tag' => array( $tag2 ) ) ); - - $query = new WP_Query( array( - 'fields' => 'ids', - 'tax_query' => array( - //'relation' => 'OR', - array( - 'taxonomy' => 'category', - 'field' => 'term_id', - 'terms' => array( $category1, $category2 ) - ) - ) + public function test_construct_with_relation_or_uppercase() { + $tq = new WP_Tax_Query( array( + 'relation' => 'OR', ) ); - $ids = $query->get_posts(); - $this->assertEquals( array( $post_id1, $post_id2 ), $ids ); + $this->assertSame( 'OR', $tq->relation ); } - function test_tax_query_no_taxonomy() { - $cat_id = $this->factory->category->create( array( 'name' => 'alpha' ) ); - $this->factory->post->create( array( 'post_title' => 'alpha', 'post_category' => array( $cat_id ) ) ); - - $response1 = new WP_Query( array( - 'tax_query' => array( - array( 'terms' => array( $cat_id ) ) - ) + public function test_construct_with_relation_other() { + $tq = new WP_Tax_Query( array( + 'relation' => 'foo', ) ); - $this->assertEmpty( $response1->posts ); - - $response2 = new WP_Query( array( - 'tax_query' => array( - array( - 'taxonomy' => 'category', - 'terms' => array( $cat_id ) - ) - ) - ) ); - $this->assertNotEmpty( $response2->posts ); - - $term = get_category( $cat_id ); - $response3 = new WP_Query( array( - 'tax_query' => array( - array( - 'field' => 'term_taxonomy_id', - 'terms' => array( $term->term_taxonomy_id ) - ) - ) - ) ); - $this->assertNotEmpty( $response3->posts ); + $this->assertSame( 'AND', $tq->relation ); } - function test_term_taxonomy_id_field_no_taxonomy() { - $posts = $this->factory->post->create_many( 5 ); - - $cats = $tags = array(); - - // need term_taxonomy_ids in addition to term_ids, so no factory - for ( $i = 0; $i < 5; $i++ ) { - $cats[$i] = wp_insert_term( 'category-' . $i , 'category' ); - $tags[$i] = wp_insert_term( 'tag-' . $i, 'post_tag' ); - - // post 0 gets all terms - wp_set_object_terms( $posts[0], array( $cats[$i]['term_id'] ), 'category', true ); - wp_set_object_terms( $posts[0], array( $tags[$i]['term_id'] ), 'post_tag', true ); - } - - wp_set_object_terms( $posts[1], array( $cats[0]['term_id'], $cats[2]['term_id'], $cats[4]['term_id'] ), 'category' ); - wp_set_object_terms( $posts[1], array( $tags[0]['term_id'], $tags[2]['term_id'], $cats[4]['term_id'] ), 'post_tag' ); - - wp_set_object_terms( $posts[2], array( $cats[1]['term_id'], $cats[3]['term_id'] ), 'category' ); - wp_set_object_terms( $posts[2], array( $tags[1]['term_id'], $tags[3]['term_id'] ), 'post_tag' ); - - wp_set_object_terms( $posts[3], array( $cats[0]['term_id'], $cats[2]['term_id'], $cats[4]['term_id'] ), 'category' ); - wp_set_object_terms( $posts[3], array( $tags[1]['term_id'], $tags[3]['term_id'] ), 'post_tag' ); - - $results1 = $this->q->query( array( - 'fields' => 'ids', - 'orderby' => 'ID', - 'order' => 'ASC', - 'tax_query' => array( - 'relation' => 'OR', - array( - 'field' => 'term_taxonomy_id', - 'terms' => array( $cats[0]['term_taxonomy_id'], $cats[2]['term_taxonomy_id'], $cats[4]['term_taxonomy_id'], $tags[0]['term_taxonomy_id'], $tags[2]['term_taxonomy_id'], $cats[4]['term_taxonomy_id'] ), - 'operator' => 'AND', - 'include_children' => false, - ), - array( - 'field' => 'term_taxonomy_id', - 'terms' => array( $cats[1]['term_taxonomy_id'], $cats[3]['term_taxonomy_id'], $tags[1]['term_taxonomy_id'], $tags[3]['term_taxonomy_id'] ), - 'operator' => 'AND', - 'include_children' => false, - ) - ) + public function test_construct_fill_missing_query_params() { + $tq = new WP_Tax_Query( array( + array(), ) ); - $this->assertEquals( array( $posts[0], $posts[1], $posts[2] ), $results1, 'Relation: OR; Operator: AND' ); + $expected = array( + 'taxonomy' => '', + 'terms' => array(), + 'include_children' => true, + 'field' => 'term_id', + 'operator' => 'IN', + ); - $results2 = $this->q->query( array( - 'fields' => 'ids', - 'orderby' => 'ID', - 'order' => 'ASC', - 'tax_query' => array( - 'relation' => 'AND', - array( - 'field' => 'term_taxonomy_id', - 'terms' => array( $cats[0]['term_taxonomy_id'], $tags[0]['term_taxonomy_id'] ), - 'operator' => 'IN', - 'include_children' => false, - ), - array( - 'field' => 'term_taxonomy_id', - 'terms' => array( $cats[3]['term_taxonomy_id'], $tags[3]['term_taxonomy_id'] ), - 'operator' => 'IN', - 'include_children' => false, - ) - ) - ) ); - - $this->assertEquals( array( $posts[0], $posts[3] ), $results2, 'Relation: AND; Operator: IN' ); + $this->assertEquals( $expected, $tq->queries[0] ); } - /** - * @ticket 28099 - */ - function test_empty__in() { - $cat_id = $this->factory->category->create(); - $post_id = $this->factory->post->create(); - wp_set_post_categories( $post_id, $cat_id ); + public function test_construct_fill_missing_query_params_merge_with_passed_values() { + $tq = new WP_Tax_Query( array( + array( + 'taxonomy' => 'foo', + 'include_children' => false, + 'foo' => 'bar', + ), + ) ); - $q1 = get_posts( array( 'category__in' => array( $cat_id ) ) ); - $this->assertNotEmpty( $q1 ); - $q2 = get_posts( array( 'category__in' => array() ) ); - $this->assertNotEmpty( $q2 ); + $expected = array( + 'taxonomy' => 'foo', + 'terms' => array(), + 'include_children' => false, + 'field' => 'term_id', + 'operator' => 'IN', + 'foo' => 'bar', + ); - $tag = wp_insert_term( 'woo', 'post_tag' ); - $tag_id = $tag['term_id']; - $slug = get_tag( $tag_id )->slug; - wp_set_post_tags( $post_id, $slug ); + $this->assertEquals( $expected, $tq->queries[0] ); + } - $q3 = get_posts( array( 'tag__in' => array( $tag_id ) ) ); - $this->assertNotEmpty( $q3 ); - $q4 = get_posts( array( 'tag__in' => array() ) ); - $this->assertNotEmpty( $q4 ); + public function test_construct_cast_terms_to_array() { + $tq = new WP_Tax_Query( array( + array( + 'terms' => 'foo', + ), + ) ); - $q5 = get_posts( array( 'tag_slug__in' => array( $slug ) ) ); - $this->assertNotEmpty( $q5 ); - $q6 = get_posts( array( 'tag_slug__in' => array() ) ); - $this->assertNotEmpty( $q6 ); + $this->assertEquals( array( 'foo', ), $tq->queries[0]['terms'] ); + } + + public function test_transform_query_terms_empty() { + $tq = new WP_Tax_Query( array( + array(), + ) ); + $query = $tq->queries[0]; + + $tq->transform_query( $tq->queries[0], 'term_id' ); + + $this->assertSame( $query, $tq->queries[0] ); + } + + public function test_transform_query_field_same_as_resulting_field() { + $tq = new WP_Tax_Query( array( + array( + 'field' => 'term_id', + ), + ) ); + $query = $tq->queries[0]; + + $tq->transform_query( $tq->queries[0], 'term_id' ); + + $this->assertSame( $query, $tq->queries[0] ); + } + + public function test_transform_query_resulting_field_sanitized() { + $t1 = $this->factory->category->create( array( 'slug' => 'foo', ) ); + $t2 = $this->factory->category->create( array( 'slug' => 'bar', ) ); + $p = $this->factory->post->create(); + wp_set_post_categories( $p, $t1 ); + + $tq1 = new WP_Tax_Query( array( + array( + 'terms' => array( 'foo' ), + 'field' => 'slug', + ), + ) ); + $tq1->transform_query( $tq1->queries[0], 'term_taxonomy_id' ); + + $tq2 = new WP_Tax_Query( array( + array( + 'terms' => array( 'foo' ), + 'field' => 'slug', + ), + ) ); + $tq2->transform_query( $tq2->queries[0], 'TERM_ ta%xonomy_id' ); + + $this->assertSame( $tq1->queries[0], $tq2->queries[0] ); + } + + public function test_transform_query_field_slug() { + $t1 = $this->factory->category->create( array( 'slug' => 'foo', ) ); + $p = $this->factory->post->create(); + $tt_ids = wp_set_post_categories( $p, $t1 ); + + $tq = new WP_Tax_Query( array( + array( + 'taxonomy' => 'category', + 'terms' => array( 'foo' ), + 'field' => 'slug', + ), + ) ); + $tq->transform_query( $tq->queries[0], 'term_taxonomy_id' ); + + $this->assertSame( $tt_ids, $tq->queries[0]['terms'] ); + $this->assertSame( 'term_taxonomy_id', $tq->queries[0]['field'] ); + } + + public function test_transform_query_field_name() { + $t1 = $this->factory->category->create( array( 'slug' => 'foo', 'name' => 'Foo', ) ); + $p = $this->factory->post->create(); + $tt_ids = wp_set_post_categories( $p, $t1 ); + + $tq = new WP_Tax_Query( array( + array( + 'taxonomy' => 'category', + 'terms' => array( 'Foo' ), + 'field' => 'name', + ), + ) ); + $tq->transform_query( $tq->queries[0], 'term_taxonomy_id' ); + + $this->assertSame( $tt_ids, $tq->queries[0]['terms'] ); + $this->assertSame( 'term_taxonomy_id', $tq->queries[0]['field'] ); + } + + public function test_transform_query_field_term_taxonomy_id() { + $t1 = $this->factory->category->create( array( 'slug' => 'foo', 'name' => 'Foo', ) ); + $p = $this->factory->post->create(); + $tt_ids = wp_set_post_categories( $p, $t1 ); + + $tq = new WP_Tax_Query( array( + array( + 'taxonomy' => 'category', + 'terms' => $tt_ids, + 'field' => 'term_taxonomy_id', + ), + ) ); + $tq->transform_query( $tq->queries[0], 'term_id' ); + + $this->assertEquals( array( $t1 ), $tq->queries[0]['terms'] ); + $this->assertSame( 'term_id', $tq->queries[0]['field'] ); + } + + public function test_transform_query_field_term_taxonomy_default() { + $t1 = $this->factory->category->create( array( 'slug' => 'foo', 'name' => 'Foo', ) ); + $p = $this->factory->post->create(); + $tt_ids = wp_set_post_categories( $p, $t1 ); + + $tq = new WP_Tax_Query( array( + array( + 'taxonomy' => 'category', + 'terms' => array( $t1 ), + 'field' => 'foo', // Anything defaults to term_id + ), + ) ); + $tq->transform_query( $tq->queries[0], 'term_taxonomy_id' ); + + $this->assertEquals( $tt_ids, $tq->queries[0]['terms'] ); + $this->assertSame( 'term_taxonomy_id', $tq->queries[0]['field'] ); + } + + public function test_transform_query_nonexistent_terms() { + $tq = new WP_Tax_Query( array( + array( + 'terms' => array( 'foo' ), + 'field' => 'slug', + 'operator' => 'AND', + ), + ) ); + $tq->transform_query( $tq->queries[0], 'term_taxonomy_id' ); + + $this->assertTrue( is_wp_error( $tq->queries[0] ) ); } }