Skip to content

Commit 40473f8

Browse files
author
Abdalrhman Emad Saad
committed
test: add tests for Tree engine
1 parent b4c760c commit 40473f8

File tree

1 file changed

+336
-0
lines changed

1 file changed

+336
-0
lines changed
Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
1+
<?php
2+
3+
namespace Kettasoft\Filterable\Tests\Unit\Engines;
4+
5+
use Kettasoft\Filterable\Filterable;
6+
use Illuminate\Support\Facades\Config;
7+
use Kettasoft\Filterable\Engines\Tree;
8+
use Kettasoft\Filterable\Tests\TestCase;
9+
use Kettasoft\Filterable\Tests\Models\Tag;
10+
use Kettasoft\Filterable\Tests\Models\Post;
11+
use Illuminate\Foundation\Testing\RefreshDatabase;
12+
use Illuminate\Http\Request;
13+
use Kettasoft\Filterable\Exceptions\InvalidDataFormatException;
14+
use Kettasoft\Filterable\Exceptions\InvalidOperatorException;
15+
use Kettasoft\Filterable\Exceptions\NotAllowedFieldException;
16+
use Symfony\Component\HttpFoundation\InputBag;
17+
18+
class TreeEngineTest extends TestCase
19+
{
20+
use RefreshDatabase;
21+
22+
protected $request;
23+
24+
public function setUp(): void
25+
{
26+
parent::setUp();
27+
28+
$total = 15;
29+
30+
Post::factory($total)->create([
31+
'status' => 'stopped',
32+
]);
33+
34+
Post::factory($total)->create([
35+
'status' => 'active',
36+
'content' => null
37+
]);
38+
39+
Post::factory($total)->create([
40+
'status' => 'pending',
41+
'content' => null
42+
]);
43+
44+
Tag::factory()->create([
45+
'post_id' => 1,
46+
'name' => 'stopped'
47+
]);
48+
49+
config()->set('filterable.default_engine', 'tree');
50+
51+
$this->request = Request::capture()->setJson(new InputBag([
52+
"filter" => [
53+
"and" => [
54+
[
55+
"field" => "status",
56+
"operator" => "eq",
57+
"value" => "stopped"
58+
],
59+
['or' => []]
60+
]
61+
]
62+
]));
63+
}
64+
65+
/**
66+
* @test
67+
*/
68+
public function it_use_tree__engine_with_simple_filtering()
69+
{
70+
$filter = Filterable::create($this->request)
71+
->setAllowedFields(['*'])
72+
->apply(Post::query());
73+
74+
$this->assertEquals(15, $filter->count());
75+
}
76+
77+
/**
78+
* @test
79+
*/
80+
public function it_use_tree_engine_with_force_set_data()
81+
{
82+
$filter = Filterable::create()
83+
->setData($this->request->json()->all())
84+
->setAllowedFields(['*'])
85+
->apply(Post::query());
86+
87+
$this->assertEquals(15, $filter->count());
88+
}
89+
90+
/**
91+
* @test
92+
*/
93+
public function it_use_tree_based_engin_with_field_mapping()
94+
{
95+
$filter = Filterable::create($this->request)
96+
->setFieldsMap(['filter_by_status' => 'status'])
97+
->setAllowedFields(['*'])
98+
->apply(Post::query());
99+
100+
$this->assertEquals(15, $filter->count());
101+
}
102+
103+
/**
104+
* It filter with tree based engin and enable strict mode option.
105+
* @test
106+
*/
107+
public function it_make_filter_with_tree_engine_and_enable_strict_mode_globally()
108+
{
109+
Config::set('filterable.engines.tree.options.strict', true);
110+
111+
$this->assertThrows(function () {
112+
Filterable::create($this->request)
113+
->setAllowedFields([])
114+
->apply(Post::query());
115+
}, NotAllowedFieldException::class);
116+
117+
// Try after define allowed fields.
118+
$filter = Filterable::create($this->request)
119+
->setAllowedFields(['status'])
120+
->apply(Post::query());
121+
122+
$this->assertEquals(15, $filter->count());
123+
}
124+
125+
/**
126+
* It filter with tree based engin and enable strict mode option.
127+
* @test
128+
*/
129+
public function it_make_filter_with_tree_engine_and_enable_strict_mode_locally()
130+
{
131+
132+
Config::set('filterable.engines.tree.strict', false);
133+
134+
$this->assertThrows(function () {
135+
Filterable::create($this->request)
136+
->strict()
137+
->setAllowedFields([])
138+
->apply(Post::query());
139+
}, NotAllowedFieldException::class);
140+
141+
// Try after define allowed fields.
142+
$filter = Filterable::create($this->request)
143+
->strict()
144+
->setAllowedFields(['status'])
145+
->apply(Post::query());
146+
147+
$this->assertEquals(15, $filter->count());
148+
}
149+
150+
/**
151+
* It filter with tree based engin and enable strict mode option.
152+
* @test
153+
*/
154+
public function it_can_filter_with_allowed_operators_only()
155+
{
156+
$data = [
157+
"filter" => [
158+
"and" => [
159+
["field" => "status", "operator" => "eq", "value" => "pending"],
160+
['or' => []]
161+
]
162+
]
163+
];
164+
165+
// Try after define allowed fields.
166+
$filter = Filterable::create()->strict()
167+
->allowdOperators(['eq'])
168+
->setAllowedFields(['status'])
169+
->setData($data)
170+
->apply(Post::query());
171+
172+
$this->assertEquals(15, $filter->count());
173+
}
174+
175+
/**
176+
* It filter with tree based engin and enable strict mode option.
177+
* @test
178+
*/
179+
public function it_cant_filter_with_tree_engine_and_not_allowed_operator()
180+
{
181+
$data = [
182+
"filter" => [
183+
"and" => [
184+
["field" => "status", "operator" => "like", "value" => "pending"],
185+
['or' => []]
186+
]
187+
]
188+
];
189+
190+
$this->assertThrows(function () use ($data) {
191+
Filterable::create()
192+
->strict()
193+
->setAllowedFields(['*'])
194+
->allowdOperators(['eq'])
195+
->setData($data)
196+
->apply(Post::query());
197+
}, InvalidOperatorException::class);
198+
199+
// Try after define allowed operator.
200+
$filter = Filterable::create()
201+
->strict()
202+
->setAllowedFields(['status'])
203+
->allowdOperators(['like'])
204+
->setData($data)
205+
->apply(Post::query());
206+
207+
$this->assertEquals(15, $filter->count());
208+
}
209+
210+
/**
211+
* It filter with tree based engin and enable strict mode option.
212+
* @test
213+
*/
214+
public function it_can_use_default_operator_when_receved_operator_is_not_allowed_with_permissive_option()
215+
{
216+
$data = [
217+
"filter" => [
218+
"and" => [
219+
["field" => "status", "operator" => "like", "value" => "pending"],
220+
['or' => []]
221+
]
222+
]
223+
];
224+
225+
$filter = Filterable::create()
226+
->permissive()
227+
->setAllowedFields(['*'])
228+
->allowdOperators(['in'])
229+
->setData($data)
230+
->apply(Post::query());
231+
232+
$this->assertEquals(15, $filter->count());
233+
}
234+
235+
/**
236+
* It filter with tree based engin and enable strict mode option.
237+
* @test
238+
*/
239+
public function it_can_use_default_operator_when_receved_operator_is_null_with_permissive_option()
240+
{
241+
$data = [
242+
"filter" => [
243+
"and" => [
244+
["field" => "status", "operator" => null, "value" => "pending"],
245+
['or' => []]
246+
]
247+
]
248+
];
249+
250+
$filter = Filterable::create()
251+
->permissive()
252+
->setAllowedFields(['*'])
253+
->setData($data)
254+
->apply(Post::query());
255+
256+
$this->assertEquals(15, $filter->count());
257+
}
258+
259+
/**
260+
* It filter with tree based engin and enable strict mode option.
261+
* @test
262+
*/
263+
public function it_throw_error_when_data_is_incorrectly()
264+
{
265+
$data = [
266+
"filter" => [
267+
"and" => [
268+
["incorrectly" => "status", "value" => "pending"],
269+
['or' => []]
270+
]
271+
]
272+
];
273+
274+
$this->assertThrows(function () use ($data) {
275+
Filterable::create()
276+
->permissive()
277+
->setAllowedFields(['*'])
278+
->setData($data)
279+
->apply(Post::query());
280+
}, InvalidDataFormatException::class);
281+
}
282+
283+
/**
284+
* It filter with tree based engin and enable strict mode option.
285+
* @test
286+
*/
287+
public function it_filter_with_tree_based_engin_relations_and_allowed_specific_relation_path()
288+
{
289+
$data = [
290+
"filter" => [
291+
"and" => [
292+
// ["field" => "status", "operator" => "eq", "value" => "stopped"],
293+
["field" => "tags.name", "operator" => "eq", "value" => "stopped"],
294+
['or' => []]
295+
]
296+
]
297+
];
298+
299+
// Config::set('filterable.engines.tree.strict', true);
300+
301+
// Try after define allowed fields.
302+
$filter = Filterable::create()
303+
->setRelations(['tags' => ['name']])
304+
->setAllowedFields(['status'])
305+
->setData($data)
306+
->apply(Post::query());
307+
308+
$this->assertEquals(1, $filter->count());
309+
}
310+
311+
/**
312+
* It filter with tree based engin and enable strict mode option.
313+
* @test
314+
*/
315+
public function it_can_filter_with_or_and_logical_operator()
316+
{
317+
$data = [
318+
"filter" => [
319+
"and" => [
320+
["field" => "status", "operator" => "eq", "value" => "stopped"],
321+
['or' => [
322+
["field" => "status", "operator" => "eq", "value" => "active"],
323+
["field" => "status", "operator" => "eq", "value" => "pending"],
324+
]]
325+
]
326+
]
327+
];
328+
329+
$filter = Filterable::create()
330+
->setData($data, true)
331+
->setAllowedFields(['*'])
332+
->apply(Post::query());
333+
334+
$this->assertEquals(45, $filter->count());
335+
}
336+
}

0 commit comments

Comments
 (0)