ILIAS  trunk Revision v12.0_alpha-377-g3641b37b9db
RequestProcessorTestCase.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
23use PHPUnit\Framework\TestCase;
39
40abstract class RequestProcessorTestCase extends TestCase
41{
42 protected function getDate(string $string): \DateTimeImmutable
43 {
44 return new \DateTimeImmutable($string, new \DateTimeZone('UTC'));
45 }
46
47 protected function getURI(string $string): URI
48 {
49 $url = $this->createMock(URI::class);
50 $url->method('__toString')->willReturn($string);
51 return $url;
52 }
53
57 protected function getRequest(
58 string $base_url,
59 Verb $verb,
60 array $arguments_with_values,
61 bool $correct_arguments = true
63 $base_url = $this->getURI($base_url);
64
65 return new class ($base_url, $verb, $arguments_with_values, $correct_arguments) extends NullRequest {
66 public function __construct(
67 protected URI $base_url,
68 protected Verb $verb,
69 protected array $arguments_with_values,
70 protected bool $correct_values
71 ) {
72 }
73
74 public function baseURL(): URI
75 {
76 return $this->base_url;
77 }
78
79 public function verb(): Verb
80 {
81 return $this->verb;
82 }
83
84 public function argumentKeys(): \Generator
85 {
86 foreach ($this->arguments_with_values as $argument_key => $argument_value) {
87 if (!is_null($r = Argument::tryFrom($argument_key))) {
88 yield $r;
89 }
90 }
91 }
92
93 public function hasArgument(Argument $argument): bool
94 {
95 return in_array($argument->value, array_keys($this->arguments_with_values));
96 }
97
98 public function argumentValue(Argument $argument): string
99 {
100 return $this->arguments_with_values[$argument->value] ?? '';
101 }
102
103 public function hasCorrectArguments(
104 array $required,
105 array $optional,
106 array $exclusive
107 ): bool {
108 return $this->correct_values;
109 }
110 };
111 }
112
113 protected function getWriter(): WriterInterface
114 {
115 return new class () extends NullWriter {
116 public function writeError(Error $error, string $message): \DOMDocument
117 {
118 $doc = new \DOMDocument();
119 $doc->appendChild($doc->createElement('error', $error->value));
120 return $doc;
121 }
122
123 public function writeIdentifyElements(
124 string $repository_name,
125 URI $base_url,
126 \DateTimeImmutable $earliest_datestamp,
127 string $first_admin_email,
128 string ...$further_admin_emails
129 ): \Generator {
130 $els = [
131 $repository_name,
132 (string) $base_url,
133 $earliest_datestamp->format('Y-m-d'),
134 $first_admin_email
135 ];
136 foreach ($els as $idx => $el) {
137 $doc = new \DOMDocument();
138 $doc->appendChild($doc->createElement('info', $el));
139 yield $doc;
140 }
141 }
142
146 public function writeMetadataFormat(): \DOMDocument
147 {
148 $doc = new \DOMDocument();
149 $doc->appendChild($doc->createElement('md_format', 'some metadata'));
150 return $doc;
151 }
152
153 public function writeRecordHeader(
154 string $identifier,
155 \DateTimeImmutable $datestamp,
156 bool $deleted = false
157 ): \DOMDocument {
158 $doc = new \DOMDocument();
159 $doc->appendChild($doc->createElement(
160 $deleted ? 'deleted_header' : 'header',
161 $identifier . ':' . $datestamp->format('Y-m-d')
162 ));
163 return $doc;
164 }
165
169 public function writeRecord(
170 string $identifier,
171 \DateTimeImmutable $datestamp,
172 \DOMDocument $metadata
173 ): \DOMDocument {
174 $doc = new \DOMDocument();
175 $doc->appendChild($root = $doc->createElement('record'));
176 $root->appendChild(
177 $doc->createElement(
178 'record_info',
179 $identifier . ':' . $datestamp->format('Y-m-d')
180 )
181 );
182 $root->appendChild($doc->importNode($metadata->documentElement, true));
183 return $doc;
184 }
185
186 public function writeDeletedRecord(
187 string $identifier,
188 \DateTimeImmutable $datestamp
189 ): \DOMDocument {
190 $doc = new \DOMDocument();
191 $doc->appendChild($root = $doc->createElement('deleted_record'));
192 $root->appendChild(
193 $doc->createElement(
194 'record_info',
195 $identifier . ':' . $datestamp->format('Y-m-d')
196 )
197 );
198 return $doc;
199 }
200
201 public function writeSet(string $spec, string $name): \DOMDocument
202 {
203 $doc = new \DOMDocument();
204 $doc->appendChild($doc->createElement('set', $spec . ':' . $name));
205 return $doc;
206 }
207
208 public function writeResumptionToken(
209 string $token,
210 int $complete_list_size,
211 int $cursor
212 ): \DOMDocument {
213 $doc = new \DOMDocument();
214 $doc->appendChild($doc->createElement(
215 'token',
216 $token . ',fullsize=' . $complete_list_size . ',cursor=' . $cursor
217 ));
218 return $doc;
219 }
220
221 public function writeResponse(
222 RequestInterface $request,
223 \DOMDocument ...$contents
224 ): \DOMDocument {
225 return $this->writeResponseOrErrorResponse(
226 'response',
227 $request,
228 ...$contents
229 );
230 }
231
232 public function writeErrorResponse(
233 RequestInterface $request,
234 \DOMDocument ...$errors
235 ): \DOMDocument {
236 return $this->writeResponseOrErrorResponse(
237 'error_response',
238 $request,
239 ...$errors
240 );
241 }
242
243 protected function writeResponseOrErrorResponse(
244 string $root_name,
245 RequestInterface $request,
246 \DOMDocument ...$contents
247 ): \DOMDocument {
248 $args = [];
249 foreach ($request->argumentKeys() as $key) {
250 $args[] = $key->value . '=' . $request->argumentValue($key);
251 }
252
253 $doc = new \DOMDocument();
254 $doc->appendChild($root = $doc->createElement($root_name));
255 $root->appendChild($doc->createElement(
256 'response_info',
257 $request->baseURL() . ':' . $request->verb()->value . ':' . implode(',', $args)
258 ));
259 foreach ($contents as $content) {
260 $root->appendChild($doc->importNode($content->documentElement, true));
261 }
262 return $doc;
263 }
264 };
265 }
266
267 protected function getSettings(
268 string $prefix = '',
269 string $repo_name = '',
270 string $contact_mail = ''
272 return new class ($prefix, $repo_name, $contact_mail) extends NullSettings {
273 public function __construct(
274 protected string $prefix,
275 protected string $repo_name,
276 protected string $contact_mail
277 ) {
278 }
279
280 public function getOAIIdentifierPrefix(): string
281 {
282 return $this->prefix;
283 }
284
285 public function getOAIContactMail(): string
286 {
287 return $this->contact_mail;
288 }
289
290 public function getOAIRepositoryName(): string
291 {
292 return $this->repo_name;
293 }
294 };
295 }
296
301 protected function getRepository(
302 ?string $earliest_datestamp = null,
303 int $record_count = 0,
304 string ...$identifiers
306 $earliest_datestamp = $this->getDate($earliest_datestamp ?? '@0');
307 $records = [];
308 foreach ($identifiers as $identifier) {
309 $records[$identifier] = new class ($identifier) extends NullRecord {
310 public function __construct(protected string $identifier)
311 {
312 }
313
314 public function infos(): RecordInfosInterface
315 {
316 return new class ($this->identifier) extends NullRecordInfos {
317 public function __construct(protected string $identifier)
318 {
319 }
320
321 public function isDeleted(): bool
322 {
323 return substr($this->identifier, 0, 3) === 'del';
324 }
325
326 public function datestamp(): \DateTimeImmutable
327 {
328 return new \DateTimeImmutable(
329 explode('+', $this->identifier)[1],
330 new \DateTimeZone('UTC')
331 );
332 }
333
334 public function identfifier(): string
335 {
336 return $this->identifier;
337 }
338 };
339 }
340
341 public function metadata(): \DOMDocument
342 {
343 $doc = new \DOMDocument();
344 $doc->appendChild($doc->createElement('md', 'md for ' . $this->identifier));
345 return $doc;
346 }
347 };
348 }
349
350 return new class ($earliest_datestamp, $record_count, $records) extends NullRepository {
351 public array $exposed_parameters = [];
352
353 public function __construct(
354 protected \DateTimeImmutable $earliest_datestamp,
355 protected int $record_count,
356 protected array $records
357 ) {
358 }
359
360 public function getEarliestDatestamp(): \DateTimeImmutable
361 {
362 return $this->earliest_datestamp;
363 }
364
365 public function doesRecordWithIdentifierExist(string $identifier): bool
366 {
367 return in_array($identifier, array_keys($this->records));
368 }
369
370 public function getRecordByIdentifier(string $identifier): ?RecordInterface
371 {
372 return $this->records[$identifier] ?? null;
373 }
374
375 public function getRecords(
376 ?\DateTimeImmutable $from = null,
377 ?\DateTimeImmutable $until = null,
378 ?int $limit = null,
379 ?int $offset = null
380 ): \Generator {
381 $this->exposed_parameters[] = [
382 'from' => $from?->format('Y-m-d'),
383 'until' => $until?->format('Y-m-d'),
384 'limit' => $limit,
385 'offset' => $offset,
386 ];
387 yield from $this->records;
388 }
389
390 public function getRecordInfos(
391 ?\DateTimeImmutable $from = null,
392 ?\DateTimeImmutable $until = null,
393 ?int $limit = null,
394 ?int $offset = null
395 ): \Generator {
396 $this->exposed_parameters[] = [
397 'from' => $from?->format('Y-m-d'),
398 'until' => $until?->format('Y-m-d'),
399 'limit' => $limit,
400 'offset' => $offset,
401 ];
402 foreach ($this->records as $record) {
403 yield $record->infos();
404 }
405 }
406
407 public function getRecordCount(
408 ?\DateTimeImmutable $from = null,
409 ?\DateTimeImmutable $until = null
410 ): int {
411 return $this->record_count;
412 }
413 };
414 }
415
416 protected function getTokenHandler(
417 bool $valid_token = true,
418 ?RequestInterface $appended_request = null
420 return new class ($valid_token, $appended_request) extends NullTokenHandler {
421 public function __construct(
422 protected bool $valid_token,
423 protected ?RequestInterface $appended_request
424 ) {
425 }
426
427 public function generateToken(
428 int $offset,
429 ?\DateTimeImmutable $from_date,
430 ?\DateTimeImmutable $until_date
431 ): string {
432 return 'next_offset=' . $offset . ':' .
433 'from=' . $from_date?->format('Y-m-d') . ':' .
434 'until=' . $until_date?->format('Y-m-d');
435 }
436
437 public function isTokenValid(string $token): bool
438 {
439 return $this->valid_token;
440 }
441
442 public function appendArgumentsFromTokenToRequest(
443 RequestInterface $request,
444 string $token
445 ): RequestInterface {
446 return $this->appended_request;
447 }
448
449 public function getOffsetFromToken(string $token): int
450 {
451 return (int) str_replace('next_offset=', '', explode(':', $token)[0]);
452 }
453 };
454 }
455}
The scope of this class is split ilias-conform URI's into components.
Definition: URI.php:35
getRequest(string $base_url, Verb $verb, array $arguments_with_values, bool $correct_arguments=true)
Argument names are keys, their values values (all as strings)
getSettings(string $prefix='', string $repo_name='', string $contact_mail='')
getRepository(?string $earliest_datestamp=null, int $record_count=0, string ... $identifiers)
Append datestamps to identifiers with +YYYY-MM-DD Mark identifiers of deleted records with the prefix...
getTokenHandler(bool $valid_token=true, ?RequestInterface $appended_request=null)
__construct()
Constructor setup ILIAS global object @access public.
Definition: class.ilias.php:76
ilErrorHandling $error
Definition: class.ilias.php:69
return['delivery_method'=> 'php',]
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$url
Definition: shib_logout.php:68
$token
Definition: xapitoken.php:67