ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
SearcherTest.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
23use PHPUnit\Framework\TestCase;
30use ILIAS\MetaData\Paths\NullFactory as NullPathFactory;
35use ILIAS\MetaData\Search\Clauses\NullFactory as NullClauseFactory;
36use ILIAS\MetaData\Search\Filters\NullFactory as NullFilterFactory;
47
48class SearcherTest extends TestCase
49{
50 protected function getRessourceID(int $idx): RessourceIDInterface
51 {
52 return new class ($idx) extends NullRessourceID {
53 public function __construct(public int $idx)
54 {
55 }
56 };
57 }
58
59 protected function assertCorrectSearchResults(RessourceIDInterface ...$ids): void
60 {
61 $this->assertCount(3, $ids);
62 $this->assertSame(1, $ids[0]->idx);
63 $this->assertSame(2, $ids[1]->idx);
64 $this->assertSame(3, $ids[2]->idx);
65 }
66
68 {
69 $returns = [
70 $this->getRessourceID(1),
71 $this->getRessourceID(2),
72 $this->getRessourceID(3)
73 ];
74
75 return new class ($returns) extends NullRepository {
76 public array $exposed_searches = [];
77
78 public function __construct(protected array $returns)
79 {
80 }
81
82 public function searchMD(
83 ClauseInterface $clause,
84 ?int $limit,
85 ?int $offset,
86 FilterInterface ...$filters
87 ): \Generator {
88 $filter_data = [];
89 foreach ($filters as $filter) {
90 $filter_data[] = $filter->exposed_data;
91 }
92 $this->exposed_searches[] = [
93 'clause' => $clause->exposed_data,
94 'limit' => $limit,
95 'offset' => $offset,
96 'filters' => $filter_data
97 ];
98
99 yield from $this->returns;
100 }
101 };
102 }
103
104 protected function getSearchFilterFactory(): FilterFactory
105 {
106 return new class () extends NullFilterFactory {
107 public function get(
108 Placeholder|int $obj_id = Placeholder::ANY,
109 Placeholder|int $sub_id = Placeholder::ANY,
110 Placeholder|string $type = Placeholder::ANY
111 ): FilterInterface {
112 $exposed = ['obj_id' => $obj_id, 'sub_id' => $sub_id, 'type' => $type];
113 return new class ($exposed) extends NullFilter {
114 public function __construct(public array $exposed_data)
115 {
116 }
117 };
118 }
119 };
120 }
121
122 protected function getSearchClauseFactory(): ClauseFactory
123 {
124 return new class () extends NullClauseFactory {
125 public function getBasicClause(
127 Mode $mode,
128 string $value,
129 bool $is_mode_negated = false
130 ): ClauseInterface {
131 $exposed = [
132 'path' => $path->toString(),
133 'mode' => $mode,
134 'value' => $value,
135 'is_mode_negated' => $is_mode_negated,
136 ];
137 return new class ($exposed) extends NullClause {
138 public function __construct(public array $exposed_data)
139 {
140 }
141 };
142 }
143
144 public function getJoinedClauses(
145 Operator $operator,
146 ClauseInterface $first_clause,
147 ClauseInterface ...$further_clauses
148 ): ClauseInterface {
149 $clause_data = [];
150 foreach ([$first_clause, ...$further_clauses] as $clause) {
151 $clause_data[] = $clause->exposed_data;
152 }
153 $exposed = [
154 'operator' => $operator,
155 'subclauses' => $clause_data
156 ];
157 return new class ($exposed) extends NullClause {
158 public function __construct(public array $exposed_data)
159 {
160 }
161 };
162 }
163 };
164 }
165
166 protected function getPathFactory(): PathFactory
167 {
168 return new class () extends NullPathFactory {
169 public function custom(): BuilderInterface
170 {
171 return new class () extends NullBuilder {
172 protected array $path = [];
173
174 public function withNextStep(string $name, bool $add_as_first = false): BuilderInterface
175 {
176 $clone = clone $this;
177 $clone->path[] = $name;
178 return $clone;
179 }
180
181 public function get(): PathInterface
182 {
183 $string = implode('>', $this->path);
184 return new class ($string) extends NullPath {
185 public function __construct(protected string $string)
186 {
187 }
188
189 public function toString(): string
190 {
191 return $this->string;
192 }
193 };
194 }
195 };
196 }
197 };
198 }
199
200 protected function getIdentifierHandler(): IdentifierHandler
201 {
202 return new class () extends NullHandler {
203 public function buildIdentifierFromEntryID(int $entry_id): string
204 {
205 return 'identifier_' . $entry_id;
206 }
207 };
208 }
209
210 public function testSearch(): void
211 {
212 $searcher = new Searcher(
213 $this->getSearchFilterFactory(),
214 $this->getSearchClauseFactory(),
215 $this->getPathFactory(),
216 $this->getIdentifierHandler()
217 );
218
219 $results = $searcher->search($repo = $this->getLOMRepository(), 32);
220
222 $this->assertEquals(
223 [[
224 'clause' => [
225 'operator' => Operator::OR,
226 'subclauses' => [[
227 'path' => 'rights>description>string',
228 'mode' => Mode::EQUALS,
229 'value' => 'identifier_32',
230 'is_mode_negated' => false
231 ]]
232 ],
233 'limit' => null,
234 'offset' => null,
235 'filters' => []
236 ]],
237 $repo->exposed_searches
238 );
239 }
240
241 public function testSearchWithMultipleEntries(): void
242 {
243 $searcher = new Searcher(
244 $this->getSearchFilterFactory(),
245 $this->getSearchClauseFactory(),
246 $this->getPathFactory(),
247 $this->getIdentifierHandler()
248 );
249
250 $results = $searcher->search($repo = $this->getLOMRepository(), 32, 9, 1234);
251
253 $this->assertEquals(
254 [[
255 'clause' => [
256 'operator' => Operator::OR,
257 'subclauses' => [
258 [
259 'path' => 'rights>description>string',
260 'mode' => Mode::EQUALS,
261 'value' => 'identifier_32',
262 'is_mode_negated' => false
263 ],
264 [
265 'path' => 'rights>description>string',
266 'mode' => Mode::EQUALS,
267 'value' => 'identifier_9',
268 'is_mode_negated' => false
269 ],
270 [
271 'path' => 'rights>description>string',
272 'mode' => Mode::EQUALS,
273 'value' => 'identifier_1234',
274 'is_mode_negated' => false
275 ]
276 ]
277 ],
278 'limit' => null,
279 'offset' => null,
280 'filters' => []
281 ]],
282 $repo->exposed_searches
283 );
284 }
285
287 {
288 $searcher = new Searcher(
289 $this->getSearchFilterFactory(),
290 $this->getSearchClauseFactory(),
291 $this->getPathFactory(),
292 $this->getIdentifierHandler()
293 );
294
295 $results = $searcher->withRestrictionToRepositoryObjects(true)
296 ->search($repo = $this->getLOMRepository(), 32);
297
299 $this->assertEquals(
300 [[
301 'clause' => [
302 'operator' => Operator::OR,
303 'subclauses' => [[
304 'path' => 'rights>description>string',
305 'mode' => Mode::EQUALS,
306 'value' => 'identifier_32',
307 'is_mode_negated' => false
308 ]]
309 ],
310 'limit' => null,
311 'offset' => null,
312 'filters' => [
313 [
314 'obj_id' => Placeholder::ANY,
315 'sub_id' => Placeholder::OBJ_ID,
316 'type' => Placeholder::ANY
317 ]
318 ]
319 ]],
320 $repo->exposed_searches
321 );
322 }
323
324 public function testSearchRestrictedToObjectType(): void
325 {
326 $searcher = new Searcher(
327 $this->getSearchFilterFactory(),
328 $this->getSearchClauseFactory(),
329 $this->getPathFactory(),
330 $this->getIdentifierHandler()
331 );
332
333 $results = $searcher->withAdditionalTypeFilter('some type')
334 ->search($repo = $this->getLOMRepository(), 32);
335
337 $this->assertEquals(
338 [[
339 'clause' => [
340 'operator' => Operator::OR,
341 'subclauses' => [[
342 'path' => 'rights>description>string',
343 'mode' => Mode::EQUALS,
344 'value' => 'identifier_32',
345 'is_mode_negated' => false
346 ]]
347 ],
348 'limit' => null,
349 'offset' => null,
350 'filters' => [
351 [
352 'obj_id' => Placeholder::ANY,
353 'sub_id' => Placeholder::ANY,
354 'type' => 'some type'
355 ]
356 ]
357 ]],
358 $repo->exposed_searches
359 );
360 }
361
363 {
364 $searcher = new Searcher(
365 $this->getSearchFilterFactory(),
366 $this->getSearchClauseFactory(),
367 $this->getPathFactory(),
368 $this->getIdentifierHandler()
369 );
370
371 $results = $searcher->withAdditionalTypeFilter('some type')
372 ->withAdditionalTypeFilter('some other type')
373 ->withAdditionalTypeFilter('a third type')
374 ->search($repo = $this->getLOMRepository(), 32);
375
377 $this->assertEquals(
378 [[
379 'clause' => [
380 'operator' => Operator::OR,
381 'subclauses' => [[
382 'path' => 'rights>description>string',
383 'mode' => Mode::EQUALS,
384 'value' => 'identifier_32',
385 'is_mode_negated' => false
386 ]]
387 ],
388 'limit' => null,
389 'offset' => null,
390 'filters' => [
391 [
392 'obj_id' => Placeholder::ANY,
393 'sub_id' => Placeholder::ANY,
394 'type' => 'some type'
395 ],
396 [
397 'obj_id' => Placeholder::ANY,
398 'sub_id' => Placeholder::ANY,
399 'type' => 'some other type'
400 ],
401 [
402 'obj_id' => Placeholder::ANY,
403 'sub_id' => Placeholder::ANY,
404 'type' => 'a third type'
405 ]
406 ]
407 ]],
408 $repo->exposed_searches
409 );
410 }
411
413 {
414 $searcher = new Searcher(
415 $this->getSearchFilterFactory(),
416 $this->getSearchClauseFactory(),
417 $this->getPathFactory(),
418 $this->getIdentifierHandler()
419 );
420
421 $results = $searcher->withAdditionalTypeFilter('some type')
422 ->withAdditionalTypeFilter('some other type')
423 ->withAdditionalTypeFilter('a third type')
424 ->withRestrictionToRepositoryObjects(true)
425 ->search($repo = $this->getLOMRepository(), 32);
426
428 $this->assertEquals(
429 [[
430 'clause' => [
431 'operator' => Operator::OR,
432 'subclauses' => [[
433 'path' => 'rights>description>string',
434 'mode' => Mode::EQUALS,
435 'value' => 'identifier_32',
436 'is_mode_negated' => false
437 ]]
438 ],
439 'limit' => null,
440 'offset' => null,
441 'filters' => [
442 [
443 'obj_id' => Placeholder::ANY,
444 'sub_id' => Placeholder::OBJ_ID,
445 'type' => 'some type'
446 ],
447 [
448 'obj_id' => Placeholder::ANY,
449 'sub_id' => Placeholder::OBJ_ID,
450 'type' => 'some other type'
451 ],
452 [
453 'obj_id' => Placeholder::ANY,
454 'sub_id' => Placeholder::OBJ_ID,
455 'type' => 'a third type'
456 ]
457 ]
458 ]],
459 $repo->exposed_searches
460 );
461 }
462}
assertCorrectSearchResults(RessourceIDInterface ... $ids)
__construct()
Constructor setup ILIAS global object @access public.
Definition: class.ilias.php:76
$path
Definition: ltiservices.php:30
$results