Skip to content

Commit 456186e

Browse files
committed
tests for compound filters
1 parent 377ae88 commit 456186e

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed

src/Query/Filters/Operators.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ class Operators
3030
const NEXT_MONTH = 'next_month';
3131
const NEXT_YEAR = 'next_year';
3232

33+
CONST AND = 'and';
34+
CONST OR = 'or';
35+
3336
// TODO: Formula filter condition
3437

3538
public static function getValidComparisonOperators($filterType)

tests/FilterTest.php

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use FiveamCode\LaravelNotionApi\Exceptions\HandlingException;
44
use FiveamCode\LaravelNotionApi\Query\Filters\Filter;
5+
use FiveamCode\LaravelNotionApi\Query\Filters\FilterBag;
56
use FiveamCode\LaravelNotionApi\Query\Filters\Operators;
67

78
it('creates a text filter with the given data', function () {
@@ -26,6 +27,140 @@
2627
$this->assertEquals('9000', $filter->toQuery()['number']['greater_than_or_equal_to']);
2728
});
2829

30+
it('creates a filter bag with the AND operator and two conditions', function () {
31+
$filterBag = new FilterBag(Operators::AND);
32+
33+
# Filter for all entries that are
34+
# (Known for == UNIVAC && Known for == ENIAC)
35+
36+
$filterBag->addFilter(
37+
Filter::rawFilter("Known for", [
38+
"multi_select" => ["contains" => "UNIVAC"],
39+
])
40+
);
41+
42+
$filterBag->addFilter(
43+
Filter::rawFilter("Known for", [
44+
"multi_select" => ["contains" => "ENIAC"],
45+
])
46+
);
47+
48+
$filterBagQuery = $filterBag->toQuery();
49+
$this->assertArrayHasKey(Operators::AND, $filterBagQuery);
50+
$this->assertCount(2, $filterBagQuery[Operators::AND]);
51+
52+
// check structure of first filter compound
53+
$filterQuery = $filterBagQuery[Operators::AND][0];
54+
$this->assertArrayHasKey('property', $filterQuery);
55+
$this->assertEquals('Known for', $filterQuery['property']);
56+
$this->assertArrayHasKey('multi_select', $filterQuery);
57+
$this->assertArrayHasKey('contains', $filterQuery['multi_select']);
58+
$this->assertEquals('UNIVAC', $filterQuery['multi_select']['contains']);
59+
60+
// check structure of second filter compound
61+
$filterQuery = $filterBagQuery[Operators::AND][1];
62+
$this->assertArrayHasKey('property', $filterQuery);
63+
$this->assertEquals('Known for', $filterQuery['property']);
64+
$this->assertArrayHasKey('multi_select', $filterQuery);
65+
$this->assertArrayHasKey('contains', $filterQuery['multi_select']);
66+
$this->assertEquals('COBOL', $filterQuery['multi_select']['contains']);
67+
});
68+
69+
it('creates a filter bag with the OR operator and three conditions', function () {
70+
$filterBag = new FilterBag(Operators::OR);
71+
72+
73+
# Filter for all entries that have
74+
# (Name == Grace || Name == Jean || Name == Ada)
75+
76+
$filterBag
77+
->addFilter(Filter::textFilter("Name", Operators::CONTAINS, "Grace"))
78+
->addFilter(Filter::textFilter("Name", Operators::CONTAINS, "Jean"))
79+
->addFilter(Filter::textFilter("Name", Operators::CONTAINS, "Ada"));
80+
81+
82+
$filterBagQuery = $filterBag->toQuery();
83+
84+
$this->assertArrayHasKey(Operators::OR, $filterBagQuery);
85+
$this->assertCount(3, $filterBagQuery[Operators::OR]);
86+
87+
// check structure of first filter compound
88+
$filterQuery = $filterBagQuery[Operators::OR][0];
89+
$this->assertArrayHasKey('property', $filterQuery);
90+
$this->assertEquals('Name', $filterQuery['property']);
91+
$this->assertArrayHasKey('text', $filterQuery);
92+
$this->assertArrayHasKey('contains', $filterQuery['text']);
93+
$this->assertEquals('Grace', $filterQuery['text']['contains']);
94+
95+
96+
// check value of second filter compound
97+
$filterQuery = $filterBagQuery[Operators::OR][1];
98+
$this->assertEquals('Jean', $filterQuery['text']['contains']);
99+
100+
// check value of third filter compound
101+
$filterQuery = $filterBagQuery[Operators::OR][2];
102+
$this->assertEquals('Ada', $filterQuery['text']['contains']);
103+
104+
});
105+
106+
it('creates a filter bag with with the AND operator and a nested OR condition', function() {
107+
108+
# Filter for all entries that are
109+
# (KnownFor == Univac && (Name == Grace || Name == Jean))
110+
111+
$filterBag = new FilterBag(Operators::AND);
112+
113+
$filterBag->addFilter(
114+
Filter::rawFilter("Known for", [
115+
"multi_select" => ["contains" => "UNIVAC"],
116+
])
117+
);
118+
119+
$nameFilterBag = new FilterBag(Operators::OR);
120+
$nameFilterBag
121+
->addFilter(Filter::textFilter("Name", Operators::CONTAINS, "Grace"))
122+
->addFilter(Filter::textFilter("Name", Operators::CONTAINS, "Jean"));
123+
124+
$filterBag->addFilterBag($nameFilterBag);
125+
126+
$this->assertInstanceOf(FilterBag::class, $filterBag);
127+
$this->assertInstanceOf(FilterBag::class, $nameFilterBag);
128+
129+
$filterBagQuery = $filterBag->toQuery();
130+
131+
$this->assertArrayHasKey(Operators::AND, $filterBagQuery);
132+
133+
// check structure of first AND filter component
134+
$multiSelectFilterQuery = $filterBagQuery[Operators::AND][0];
135+
$this->assertArrayHasKey('property', $multiSelectFilterQuery);
136+
$this->assertEquals('Known for', $multiSelectFilterQuery['property']);
137+
$this->assertArrayHasKey('multi_select', $multiSelectFilterQuery);
138+
$this->assertArrayHasKey('contains', $multiSelectFilterQuery['multi_select']);
139+
$this->assertEquals('UNIVAC', $multiSelectFilterQuery['multi_select']['contains']);
140+
141+
// check structure of second AND filter component, which is another filter bag
142+
// with an OR operator
143+
$nameFilterBagQuery = $filterBagQuery[Operators::AND][1];
144+
$this->assertArrayHasKey(Operators::OR, $nameFilterBagQuery);
145+
$this->assertCount(2, $nameFilterBagQuery[Operators::OR]);
146+
147+
// check structure of the first filter inside the OR filter bag
148+
$filterQuery = $nameFilterBagQuery[Operators::OR][0];
149+
$this->assertArrayHasKey('property', $filterQuery);
150+
$this->assertEquals('Name', $filterQuery['property']);
151+
$this->assertArrayHasKey('text', $filterQuery);
152+
$this->assertArrayHasKey('contains', $filterQuery['text']);
153+
$this->assertEquals('Grace', $filterQuery['text']['contains']);
154+
155+
// check structure of the second filter inside the OR filter bag
156+
$filterQuery = $nameFilterBagQuery[Operators::OR][1];
157+
$this->assertArrayHasKey('property', $filterQuery);
158+
$this->assertEquals('Name', $filterQuery['property']);
159+
$this->assertArrayHasKey('text', $filterQuery);
160+
$this->assertArrayHasKey('contains', $filterQuery['text']);
161+
$this->assertEquals('Jean', $filterQuery['text']['contains']);
162+
});
163+
29164
it('throws an HandlingException for an invalid comparison operator', function () {
30165
$this->expectException(HandlingException::class);
31166
$this->expectExceptionMessage('Invalid comparison operator');
@@ -39,3 +174,28 @@
39174
$this->expectExceptionMessage('Invalid filter definition.');
40175
$filter->toArray();
41176
});
177+
178+
it('throws an exception for nesting too many filter bags', function() {
179+
180+
$this->expectException(HandlingException::class);
181+
$this->expectExceptionMessage('The maximum nesting level of compound filters must not exceed 2.');
182+
183+
$filterBag = new FilterBag(Operators::AND);
184+
185+
$filterBag->addFilter(
186+
Filter::rawFilter("Known for", [
187+
"multi_select" => ["contains" => "UNIVAC"],
188+
])
189+
);
190+
191+
$nameFilterBag = new FilterBag(Operators::OR);
192+
$nameFilterBag
193+
->addFilter(Filter::textFilter("Name", Operators::CONTAINS, "Grace"))
194+
->addFilter(Filter::textFilter("Name", Operators::CONTAINS, "Jean"));
195+
196+
$anotherBag = new FilterBag();
197+
$nameFilterBag->addFilterBag($anotherBag);
198+
199+
// that's one nested bag too much
200+
$filterBag->addFilterBag($nameFilterBag);
201+
});

0 commit comments

Comments
 (0)