Skip to content

Commit

Permalink
Merge branch '1.x'
Browse files Browse the repository at this point in the history
Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>
  • Loading branch information
crynobone committed Jul 25, 2020
2 parents cabc04c + 5dceadd commit e84a34e
Show file tree
Hide file tree
Showing 15 changed files with 689 additions and 45 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ env:
- laravel=^8.0
- setup=stable laravel=^6.0
- setup=stable laravel=^7.0
- setup=stable laravel=^8.0
- setup=lowest laravel=^6.0
- setup=lowest laravel=^7.0
- setup=lowest laravel=^8.0
Expand Down
16 changes: 16 additions & 0 deletions CHANGELOG-1.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

This changelog references the relevant changes (bug and security fixes) done to `laravie/query-filter`.

## 1.7.0

Released: 2020-07-25

### Changes

* Avoid ambigous column name when search with related fields using Eloquent.

## 1.6.2

Released: 2020-06-19

### Fixes

* Avoid sanitizing unicode characters. [#4](https://github.com/laravie/query-filter/pull/4)

## 1.6.1

Released: 2020-02-16
Expand Down
15 changes: 10 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@
"email": "crynobone@gmail.com"
}
],
"autoload": {
"psr-4": {
"Laravie\\QueryFilter\\" : "src/"
}
},
"autoload-dev": {
"psr-4": {
"Laravie\\QueryFilter\\Tests\\" : "tests/"
}
},
"require": {
"php": ">=7.3",
"illuminate/database": "^6.0 || ^7.0 || ^8.0",
Expand All @@ -18,11 +28,6 @@
"mockery/mockery": "^1.3.1",
"orchestra/testbench": "^4.5 || ^5.0 || ^6.0"
},
"autoload": {
"psr-4": {
"Laravie\\QueryFilter\\" : "src/"
}
},
"config": {
"sort-packages": true
},
Expand Down
8 changes: 8 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,12 @@
<directory suffix=".php">src/</directory>
</whitelist>
</filter>

<php>
<env name="APP_ENV" value="testing"/>
<env name="APP_KEY" value="AckfSECXIvnK5r28GVIWUAxmbBSjTsmF"/>
<env name="DB_CONNECTION" value="testing"/>

<server name="APP_KEY" value="AckfSECXIvnK5r28GVIWUAxmbBSjTsmF"/>
</php>
</phpunit>
4 changes: 4 additions & 0 deletions src/Searchable.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ protected function queryOnColumnUsing(

$keywords = $this->keyword->all();

if ($query instanceof EloquentBuilder) {
$column = $query->qualifyColumn((string) $column);
}

return $query->{$whereOperator}(static function ($query) use ($column, $keywords, $likeOperator) {
foreach ($keywords as $keyword) {
$query->orWhere((string) $column, $likeOperator, $keyword);
Expand Down
180 changes: 180 additions & 0 deletions tests/Feature/EloquentSearchableTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
<?php

namespace Laravie\QueryFilter\Tests\Feature;

use Illuminate\Database\Query\Expression;
use Illuminate\Support\Facades\DB;
use Laravie\QueryFilter\Searchable;
use Laravie\QueryFilter\Tests\Models\User;
use Laravie\QueryFilter\Tests\TestCase;

class EloquentSearchableTest extends TestCase
{
/** @test */
public function it_can_build_search_query()
{
$stub = new Searchable(
'hello', ['name']
);

$query = User::query();
$stub->apply($query);

$this->assertSame(
'select * from "users" where (("users"."name" like ? or "users"."name" like ? or "users"."name" like ? or "users"."name" like ?))',
$query->toSql()
);

$this->assertSame(
['hello', 'hello%', '%hello', '%hello%'],
$query->getBindings()
);
}

/** @test */
public function it_ignores_build_search_query_when_columns_is_not_provided()
{
$stub = new Searchable(
'hello', []
);

$query = User::query();
$stub->apply($query);

$this->assertSame(
'select * from "users"',
$query->toSql()
);

$this->assertSame(
[],
$query->getBindings()
);
}

/** @test */
public function it_ignores_build_search_query_when_columns_is_invalid()
{
$stub = new Searchable(
'hello', ['']
);

$query = User::query();
$stub->apply($query);

$this->assertSame(
'select * from "users"',
$query->toSql()
);

$this->assertSame(
[],
$query->getBindings()
);
}

/** @test */
public function it_ignores_build_search_query_when_keyword_is_empty()
{
$stub = new Searchable(
'', ['name']
);

$query = User::query();
$stub->apply($query);

$this->assertSame(
'select * from "users"',
$query->toSql()
);

$this->assertSame(
[],
$query->getBindings()
);
}

/** @test */
public function it_can_build_search_query_with_expression_value()
{
$stub = new Searchable(
'hello', [new Expression('users.name')]
);

$query = User::query();
$stub->apply($query);

$this->assertSame(
'select * from "users" where (("users"."name" like ? or "users"."name" like ? or "users"."name" like ? or "users"."name" like ?))',
$query->toSql()
);

$this->assertSame(
['hello', 'hello%', '%hello', '%hello%'],
$query->getBindings()
);
}

/** @test */
public function it_can_build_search_query_with_json_selector()
{
$stub = new Searchable(
'hello', ['address->postcode']
);

$query = User::query();
$stub->apply($query);

$this->assertSame(
'select * from "users" where ((lower(address->\'$.postcode\') like ? or lower(address->\'$.postcode\') like ? or lower(address->\'$.postcode\') like ? or lower(address->\'$.postcode\') like ?))',
$query->toSql()
);

$this->assertSame(
['hello', 'hello%', '%hello', '%hello%'],
$query->getBindings()
);
}

/** @test */
public function it_cant_build_search_query_with_invalid_column_name()
{
$stub = new Searchable(
'hello', ['email->"%27))%23injectedSQL']
);

$query = User::query();
$stub->apply($query);

$this->assertSame(
'select * from "users"',
$query->toSql()
);

$this->assertSame(
[],
$query->getBindings()
);
}

/** @test */
public function it_can_build_search_query_with_relation_field()
{
$stub = new Searchable(
'hello', ['name', 'posts.title']
);

$query = User::query();
$stub->apply($query);

$this->assertSame(
'select * from "users" where (("users"."name" like ? or "users"."name" like ? or "users"."name" like ? or "users"."name" like ?) or exists (select * from "posts" where "users"."id" = "posts"."user_id" and ("posts"."title" like ? or "posts"."title" like ? or "posts"."title" like ? or "posts"."title" like ?)))',
$query->toSql()
);

$this->assertSame(
['hello', 'hello%', '%hello', '%hello%', 'hello', 'hello%', '%hello', '%hello%'],
$query->getBindings()
);
}
}
115 changes: 115 additions & 0 deletions tests/Feature/EloquentTaxanomyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php

namespace Laravie\QueryFilter\Tests\Feature;

use Illuminate\Support\Facades\DB;
use Laravie\QueryFilter\Taxonomy;
use Laravie\QueryFilter\Tests\Models\User;
use Laravie\QueryFilter\Tests\TestCase;

class EloquentTaxonomyTest extends TestCase
{
/** @test */
public function it_can_build_match_query()
{
$stub = new Taxonomy(
'name:hello email:crynobone@gmail.com email:crynobone@orchestraplatform.com is:active', [
'name:*' => static function ($query, $value) {
return $query->where('name', '=', $value);
},
'email:[]' => static function ($query, $value) {
return $query->whereIn('email', $value);
},
'is:active' => static function ($query) {
return $query->whereNotNull('deleted_at');
},
], ['name']
);

$query = User::query();
$stub->apply($query);

$this->assertSame(
'select * from "users" where "name" = ? and "email" in (?, ?) and "deleted_at" is not null',
$query->toSql()
);

$this->assertSame(
['hello', 'crynobone@gmail.com', 'crynobone@orchestraplatform.com'],
$query->getBindings()
);
}

/** @test */
public function it_cant_build_match_query_given_empty_taxanomy()
{
$stub = new Taxonomy(
'name: email: email: is:', [
'name:*' => static function ($query, $value) {
return $query->where('name', '=', $value);
},
'email:[]' => static function ($query, $value) {
return $query->whereIn('email', $value);
},
'is:active' => static function ($query) {
return $query->whereNotNull('deleted_at');
},
], ['name']
);

$query = User::query();
$stub->apply($query);

$this->assertSame(
'select * from "users"',
$query->toSql()
);

$this->assertSame(
[],
$query->getBindings()
);
}

/** @test */
public function it_can_build_match_query_with_basic_search()
{
$stub = new Taxonomy(
'hello', [], ['name']
);

$query = User::query();
$stub->apply($query);

$this->assertSame(
'select * from "users" where (("users"."name" like ? or "users"."name" like ? or "users"."name" like ? or "users"."name" like ?))',
$query->toSql()
);

$this->assertSame(
['hello', 'hello%', '%hello', '%hello%'],
$query->getBindings()
);
}

/** @test */
public function it_can_build_match_query_with_basic_search_with_related_field()
{
$stub = new Taxonomy(
'hello', [], ['name', 'posts.title']
);

$query = User::query();
$stub->apply($query);

$this->assertSame(
'select * from "users" where (("users"."name" like ? or "users"."name" like ? or "users"."name" like ? or "users"."name" like ?) or exists (select * from "posts" where "users"."id" = "posts"."user_id" and ("posts"."title" like ? or "posts"."title" like ? or "posts"."title" like ? or "posts"."title" like ?)))',
$query->toSql()
);

$this->assertSame(
['hello', 'hello%', '%hello', '%hello%', 'hello', 'hello%', '%hello', '%hello%'],
$query->getBindings()
);
}
}
Loading

0 comments on commit e84a34e

Please sign in to comment.