Skip to content

Commit

Permalink
Merge pull request #3 from trendwerk/empty-search
Browse files Browse the repository at this point in the history
Empty search SQL
  • Loading branch information
haroldangenent authored Jun 2, 2017
2 parents 269bba4 + e50afd0 commit bb1c106
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 21 deletions.
4 changes: 4 additions & 0 deletions src/Hook/Posts.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ public function search($sql, WP_Query $query)

$searches = array_filter($searches);

if (count($searches) === 0) {
continue;
}

$search = '(' . implode($or, $searches) . ')' . $or;

$clause = preg_replace('/' . $or . '/', $or . $search, $clause, 1);
Expand Down
104 changes: 83 additions & 21 deletions tests/Search/Hook/PostsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
use Mockery;
use Trendwerk\Search\Dimension\Dimensions;
use Trendwerk\Search\Dimension\Meta;
use Trendwerk\Search\Dimension\Term;
use Trendwerk\Search\Hook\Posts;
use WP_Mock;

final class PostsTest extends TestCase
{
private $metaKey = 'lastName';
private $posts;
private $taxonomy = 'taxonomyName';
private $wpdb;

public function setUp()
Expand All @@ -20,12 +22,18 @@ public function setUp()
$this->wpdb = Mockery::mock('wpdb');
$this->wpdb->postmeta = 'wp_postmeta';
$this->wpdb->posts = 'wp_posts';
$this->wpdb->term_relationships = 'wp_term_relationships';
$this->wpdb->term_taxonomy = 'wp_term_taxonomy';
$this->wpdb->terms = 'wp_terms';

$dimensions = new Dimensions();
$dimensions->add(new Meta($this->wpdb, [
'compare' => '=',
'key' => $this->metaKey,
]));
$dimensions->add(new Term($this->wpdb, [
'taxonomy' => $this->taxonomy,
]));

$this->posts = new Posts($dimensions);
}
Expand Down Expand Up @@ -76,10 +84,13 @@ public function testJoin()
$expectation = [];

foreach ($searchTerms as $index => $searchTerm) {
$tableAlias = 'searchMeta' . $index;
$metaAlias = 'searchMeta' . $index;
$termAlias = 'searchTerm' . $index;

$wordExpectation = "INNER JOIN {$this->wpdb->postmeta} AS {$tableAlias} ";
$wordExpectation .= "ON ({$this->wpdb->posts}.ID = {$tableAlias}.post_id)";
$wordExpectation = "INNER JOIN {$this->wpdb->postmeta} AS {$metaAlias} ";
$wordExpectation .= "ON ({$this->wpdb->posts}.ID = {$metaAlias}.post_id) ";
$wordExpectation .= "INNER JOIN {$this->wpdb->term_relationships} AS {$termAlias} ";
$wordExpectation .= "ON ({$this->wpdb->posts}.ID = {$termAlias}.object_id)";

$expectation[] = $wordExpectation;
}
Expand All @@ -101,41 +112,36 @@ public function testJoinWithoutSearch()

public function testSearch()
{
$and = " AND ";
$or = " OR ";

$searchTerms = ['Testman', 'theTester'];
$baseSql = $and . "(";

foreach ($searchTerms as $searchTerm) {
$baseSql .= "(";
$baseSql .= "({$this->wpdb->posts}.post_title LIKE '%{$searchTerm}%')";
$baseSql .= $or;
$baseSql .= "({$this->wpdb->posts}.post_content LIKE '%{$searchTerm}%')";
$baseSql .= ")" . $and;
}

$baseSql = mb_substr($baseSql, 0, mb_strlen($baseSql) - mb_strlen($or));
$baseSql .= ")";

$fakeTermIds = [1, 9];
$expectations = [];

foreach ($searchTerms as $index => $searchTerm) {
$expectations[] = "searchMeta{$index}.meta_key %s AND searchMeta{$index}.meta_value LIKE %s";

$termIds = implode(',', $fakeTermIds);
$expectations[] = "searchTerm{$index}.term_taxonomy_id IN ({$termIds})";
}

WP_Mock::wpPassthruFunction('absint', ['times' => (count($fakeTermIds) * count($searchTerms))]);

$this->wpdb->shouldReceive('esc_like')
->times((count($searchTerms) * 2))
->andReturnUsing(function ($searchWord) {
return $searchWord;
});

$this->wpdb->shouldReceive('prepare')
->times(count($searchTerms))
->times((count($searchTerms) * 2))
->andReturnUsing(function ($sql) {
return $sql;
});

$result = $this->posts->search($baseSql, $this->getQuery(true, $searchTerms));
$this->wpdb->shouldReceive('get_col')
->times(count($searchTerms))
->andReturn($fakeTermIds);

$result = $this->search($searchTerms);

foreach ($expectations as $expectation) {
$this->assertContains($expectation, $result);
Expand All @@ -150,6 +156,62 @@ public function testSearchWithoutSearch()
$this->assertEquals($expectation, $result);
}

public function testSearchWithoutTermHit()
{
$dimensions = new Dimensions();
$dimensions->add(new Term($this->wpdb, [
'taxonomy' => $this->taxonomy,
]));

$fakeTermIds = [];
$searchTerms = ['Testterm', 'AnotherQuery'];

$this->wpdb->shouldReceive('esc_like')
->times(count($searchTerms))
->andReturnUsing(function ($searchWord) {
return $searchWord;
});

$this->wpdb->shouldReceive('prepare')
->times(count($searchTerms))
->andReturnUsing(function ($sql) {
return $sql;
});

$this->wpdb->shouldReceive('get_col')
->times(count($searchTerms))
->andReturn($fakeTermIds);

$result = $this->search(['Testman', 'theTester'], new Posts($dimensions));

$this->assertNotContains('OR ()', $result);
}

private function search(array $searchTerms, Posts $posts = null)
{
if (! $posts) {
$posts = $this->posts;
}

$and = " AND ";
$or = " OR ";

$baseSql = $and . "(";

foreach ($searchTerms as $searchTerm) {
$baseSql .= "(";
$baseSql .= "({$this->wpdb->posts}.post_title LIKE '%{$searchTerm}%')";
$baseSql .= $or;
$baseSql .= "({$this->wpdb->posts}.post_content LIKE '%{$searchTerm}%')";
$baseSql .= ")" . $and;
}

$baseSql = mb_substr($baseSql, 0, mb_strlen($baseSql) - mb_strlen($or));
$baseSql .= ")";

return $posts->search($baseSql, $this->getQuery(true, $searchTerms));
}

private function getQuery($isSearch = true, $terms = ['Testman', 'mcTest'])
{
$wpQuery = Mockery::mock('WP_Query');
Expand Down

0 comments on commit bb1c106

Please sign in to comment.