b5020d05ef56ec6d35dcf531297a43bc9c86ba84
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Tests / Unit / ContentObject / FilesContentObjectTest.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Frontend\Tests\Unit\ContentObject;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use TYPO3\CMS\Core\Resource\Collection\StaticFileCollection;
19 use TYPO3\CMS\Core\Resource\File;
20 use TYPO3\CMS\Core\Resource\FileCollectionRepository;
21 use TYPO3\CMS\Core\Resource\FileReference;
22 use TYPO3\CMS\Core\Resource\Folder;
23 use TYPO3\CMS\Core\Resource\ResourceFactory;
24 use TYPO3\CMS\Core\TypoScript\TemplateService;
25 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
26 use TYPO3\CMS\Frontend\ContentObject\FilesContentObject;
27 use TYPO3\CMS\Frontend\ContentObject\TextContentObject;
28 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
29 use TYPO3\CMS\Frontend\Resource\FileCollector;
30 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
31
32 /**
33 * Test case
34 */
35 class FilesContentObjectTest extends UnitTestCase
36 {
37
38 /**
39 * @var bool Reset singletons created by subject
40 */
41 protected $resetSingletonInstances = true;
42
43 /**
44 * @var \TYPO3\CMS\Frontend\ContentObject\FilesContentObject|\PHPUnit_Framework_MockObject_MockObject
45 */
46 protected $subject;
47
48 /**
49 * Set up
50 */
51 protected function setUp()
52 {
53 $GLOBALS['SIM_ACCESS_TIME'] = 0;
54 $templateService = $this->getMockBuilder(TemplateService::class)
55 ->setMethods(['getFileName', 'linkData'])
56 ->getMock();
57 $tsfe = $this->getMockBuilder(TypoScriptFrontendController::class)
58 ->setMethods(['dummy'])
59 ->disableOriginalConstructor()
60 ->getMock();
61 $tsfe->tmpl = $templateService;
62
63 $contentObjectRenderer = new ContentObjectRenderer($tsfe);
64 $contentObjectRenderer->setContentObjectClassMap([
65 'FILES' => FilesContentObject::class,
66 'TEXT' => TextContentObject::class,
67 ]);
68 $this->subject = $this->getMockBuilder(FilesContentObject::class)
69 ->setMethods(['getFileCollector'])
70 ->setConstructorArgs([$contentObjectRenderer])
71 ->getMock();
72 }
73
74 /**
75 * @return array
76 */
77 public function renderReturnsFilesForFileReferencesDataProvider(): array
78 {
79 return [
80 'One file reference' => [
81 [
82 'references' => '1',
83 'renderObj' => 'TEXT',
84 'renderObj.' => [
85 'data' => 'file:current:name',
86 'wrap' => '<p>|</p>',
87 ],
88 ],
89 '<p>File 1</p>',
90 ],
91 'One file reference with begin higher than allowed' => [
92 [
93 'references' => '1',
94 'begin' => '1',
95 'renderObj' => 'TEXT',
96 'renderObj.' => [
97 'data' => 'file:current:name',
98 'wrap' => '<p>|</p>',
99 ],
100 ],
101 '',
102 ],
103 'One file reference with maxItems higher than allowed' => [
104 [
105 'references' => '1',
106 'maxItems' => '2',
107 'renderObj' => 'TEXT',
108 'renderObj.' => [
109 'data' => 'file:current:name',
110 'wrap' => '<p>|</p>',
111 ],
112 ],
113 '<p>File 1</p>',
114 ],
115 'Multiple file references' => [
116 [
117 'references' => '1,2,3',
118 'renderObj' => 'TEXT',
119 'renderObj.' => [
120 'data' => 'file:current:name',
121 'wrap' => '<p>|</p>',
122 ],
123 ],
124 '<p>File 1</p><p>File 2</p><p>File 3</p>',
125 ],
126 'Multiple file references with begin' => [
127 [
128 'references' => '1,2,3',
129 'begin' => '1',
130 'renderObj' => 'TEXT',
131 'renderObj.' => [
132 'data' => 'file:current:name',
133 'wrap' => '<p>|</p>',
134 ],
135 ],
136 '<p>File 2</p><p>File 3</p>',
137 ],
138 'Multiple file references with negative begin' => [
139 [
140 'references' => '1,2,3',
141 'begin' => '-1',
142 'renderObj' => 'TEXT',
143 'renderObj.' => [
144 'data' => 'file:current:name',
145 'wrap' => '<p>|</p>',
146 ],
147 ],
148 '<p>File 1</p><p>File 2</p><p>File 3</p>',
149 ],
150 'Multiple file references with maxItems' => [
151 [
152 'references' => '1,2,3',
153 'maxItems' => '2',
154 'renderObj' => 'TEXT',
155 'renderObj.' => [
156 'data' => 'file:current:name',
157 'wrap' => '<p>|</p>',
158 ],
159 ],
160 '<p>File 1</p><p>File 2</p>',
161 ],
162 'Multiple file references with negative maxItems' => [
163 [
164 'references' => '1,2,3',
165 'maxItems' => '-2',
166 'renderObj' => 'TEXT',
167 'renderObj.' => [
168 'data' => 'file:current:name',
169 'wrap' => '<p>|</p>',
170 ],
171 ],
172 '',
173 ],
174 'Multiple file references with begin and maxItems' => [
175 [
176 'references' => '1,2,3',
177 'begin' => '1',
178 'maxItems' => '1',
179 'renderObj' => 'TEXT',
180 'renderObj.' => [
181 'data' => 'file:current:name',
182 'wrap' => '<p>|</p>',
183 ],
184 ],
185 '<p>File 2</p>',
186 ],
187 'Multiple file references unsorted' => [
188 [
189 'references' => '1,3,2',
190 'renderObj' => 'TEXT',
191 'renderObj.' => [
192 'data' => 'file:current:name',
193 'wrap' => '<p>|</p>',
194 ],
195 ],
196 '<p>File 1</p><p>File 3</p><p>File 2</p>',
197 ],
198 'Multiple file references sorted by name' => [
199 [
200 'references' => '3,1,2',
201 'sorting' => 'name',
202 'renderObj' => 'TEXT',
203 'renderObj.' => [
204 'data' => 'file:current:name',
205 'wrap' => '<p>|</p>',
206 ],
207 ],
208 '<p>File 1</p><p>File 2</p><p>File 3</p>',
209 ],
210 ];
211 }
212
213 /**
214 * @test
215 * @dataProvider renderReturnsFilesForFileReferencesDataProvider
216 * @param array $configuration
217 * @param string $expected
218 */
219 public function renderReturnsFilesForFileReferences(array $configuration, string $expected): void
220 {
221 $fileReferenceMap = [];
222 for ($i = 1; $i < 4; $i++) {
223 $fileReference = $this->createMock(FileReference::class);
224 $fileReference->expects($this->any())
225 ->method('getName')
226 ->will($this->returnValue('File ' . $i));
227 $fileReference->expects($this->any())
228 ->method('hasProperty')
229 ->with('name')
230 ->will($this->returnValue(true));
231 $fileReference->expects($this->any())
232 ->method('getProperty')
233 ->with('name')
234 ->will($this->returnValue('File ' . $i));
235
236 $fileReferenceMap[] = [$i, $fileReference];
237 }
238
239 $fileRepository = $this->getMockBuilder(\TYPO3\CMS\Core\Resource\FileRepository::class)->getMock();
240 $fileRepository->expects($this->any())
241 ->method('findFileReferenceByUid')
242 ->will($this->returnValueMap($fileReferenceMap));
243 $fileCollector = $this->getMockBuilder(FileCollector::class)
244 ->setMethods(['getFileRepository'])
245 ->getMock();
246 $fileCollector->expects($this->any())
247 ->method('getFileRepository')
248 ->will($this->returnValue($fileRepository));
249
250 $this->subject->expects($this->any())
251 ->method('getFileCollector')
252 ->will($this->returnValue($fileCollector));
253
254 $this->assertSame($expected, $this->subject->render($configuration));
255 }
256
257 /**
258 * @return array
259 */
260 public function renderReturnsFilesForFilesDataProvider(): array
261 {
262 return [
263 'One file' => [
264 [
265 'files' => '1',
266 'renderObj' => 'TEXT',
267 'renderObj.' => [
268 'data' => 'file:current:name',
269 'wrap' => '<p>|</p>',
270 ],
271 ],
272 '<p>File 1</p>',
273 ],
274 'One file with begin higher than allowed' => [
275 [
276 'files' => '1',
277 'begin' => '1',
278 'renderObj' => 'TEXT',
279 'renderObj.' => [
280 'data' => 'file:current:name',
281 'wrap' => '<p>|</p>',
282 ],
283 ],
284 '',
285 ],
286 'One file with maxItems higher than allowed' => [
287 [
288 'files' => '1',
289 'maxItems' => '2',
290 'renderObj' => 'TEXT',
291 'renderObj.' => [
292 'data' => 'file:current:name',
293 'wrap' => '<p>|</p>',
294 ],
295 ],
296 '<p>File 1</p>',
297 ],
298 'Multiple files' => [
299 [
300 'files' => '1,2,3',
301 'renderObj' => 'TEXT',
302 'renderObj.' => [
303 'data' => 'file:current:name',
304 'wrap' => '<p>|</p>',
305 ],
306 ],
307 '<p>File 1</p><p>File 2</p><p>File 3</p>',
308 ],
309 'Multiple files with begin' => [
310 [
311 'files' => '1,2,3',
312 'begin' => '1',
313 'renderObj' => 'TEXT',
314 'renderObj.' => [
315 'data' => 'file:current:name',
316 'wrap' => '<p>|</p>',
317 ],
318 ],
319 '<p>File 2</p><p>File 3</p>',
320 ],
321 'Multiple files with negative begin' => [
322 [
323 'files' => '1,2,3',
324 'begin' => '-1',
325 'renderObj' => 'TEXT',
326 'renderObj.' => [
327 'data' => 'file:current:name',
328 'wrap' => '<p>|</p>',
329 ],
330 ],
331 '<p>File 1</p><p>File 2</p><p>File 3</p>',
332 ],
333 'Multiple files with maxItems' => [
334 [
335 'files' => '1,2,3',
336 'maxItems' => '2',
337 'renderObj' => 'TEXT',
338 'renderObj.' => [
339 'data' => 'file:current:name',
340 'wrap' => '<p>|</p>',
341 ],
342 ],
343 '<p>File 1</p><p>File 2</p>',
344 ],
345 'Multiple files with negative maxItems' => [
346 [
347 'files' => '1,2,3',
348 'maxItems' => '-2',
349 'renderObj' => 'TEXT',
350 'renderObj.' => [
351 'data' => 'file:current:name',
352 'wrap' => '<p>|</p>',
353 ],
354 ],
355 '',
356 ],
357 'Multiple files with begin and maxItems' => [
358 [
359 'files' => '1,2,3',
360 'begin' => '1',
361 'maxItems' => '1',
362 'renderObj' => 'TEXT',
363 'renderObj.' => [
364 'data' => 'file:current:name',
365 'wrap' => '<p>|</p>',
366 ],
367 ],
368 '<p>File 2</p>',
369 ],
370 'Multiple files unsorted' => [
371 [
372 'files' => '1,3,2',
373 'renderObj' => 'TEXT',
374 'renderObj.' => [
375 'data' => 'file:current:name',
376 'wrap' => '<p>|</p>',
377 ],
378 ],
379 '<p>File 1</p><p>File 3</p><p>File 2</p>',
380 ],
381 'Multiple files sorted by name' => [
382 [
383 'files' => '3,1,2',
384 'sorting' => 'name',
385 'renderObj' => 'TEXT',
386 'renderObj.' => [
387 'data' => 'file:current:name',
388 'wrap' => '<p>|</p>',
389 ],
390 ],
391 '<p>File 1</p><p>File 2</p><p>File 3</p>',
392 ],
393 ];
394 }
395
396 /**
397 * @test
398 * @dataProvider renderReturnsFilesForFilesDataProvider
399 * @param array $configuration
400 * @param string $expected
401 */
402 public function renderReturnsFilesForFiles(array $configuration, string $expected): void
403 {
404 $fileMap = [];
405 for ($i = 1; $i < 4; $i++) {
406 $file = $this->createMock(File::class);
407 $file->expects($this->any())
408 ->method('getName')
409 ->will($this->returnValue('File ' . $i));
410 $file->expects($this->any())
411 ->method('hasProperty')
412 ->with('name')
413 ->will($this->returnValue(true));
414 $file->expects($this->any())
415 ->method('getProperty')
416 ->with('name')
417 ->will($this->returnValue('File ' . $i));
418
419 $fileMap[] = [$i, [], $file];
420 }
421
422 $resourceFactory = $this->getMockBuilder(ResourceFactory::class)->getMock();
423 $resourceFactory->expects($this->any())
424 ->method('getFileObject')
425 ->will($this->returnValueMap($fileMap));
426 $fileCollector = $this->getMockBuilder(FileCollector::class)
427 ->setMethods(['getResourceFactory'])
428 ->getMock();
429 $fileCollector->expects($this->any())
430 ->method('getResourceFactory')
431 ->will($this->returnValue($resourceFactory));
432
433 $this->subject->expects($this->any())
434 ->method('getFileCollector')
435 ->will($this->returnValue($fileCollector));
436
437 $this->assertSame($expected, $this->subject->render($configuration));
438 }
439
440 /**
441 * @return array
442 */
443 public function renderReturnsFilesForCollectionsDataProvider(): array
444 {
445 return [
446 'One collection' => [
447 [
448 'collections' => '1',
449 'renderObj' => 'TEXT',
450 'renderObj.' => [
451 'data' => 'file:current:name',
452 'wrap' => '<p>|</p>',
453 ],
454 ],
455 '<p>File 1</p><p>File 2</p><p>File 3</p>',
456 ],
457 'One collection with begin' => [
458 [
459 'collections' => '1',
460 'begin' => '1',
461 'renderObj' => 'TEXT',
462 'renderObj.' => [
463 'data' => 'file:current:name',
464 'wrap' => '<p>|</p>',
465 ],
466 ],
467 '<p>File 2</p><p>File 3</p>',
468 ],
469 'One collection with begin higher than allowed' => [
470 [
471 'collections' => '1',
472 'begin' => '3',
473 'renderObj' => 'TEXT',
474 'renderObj.' => [
475 'data' => 'file:current:name',
476 'wrap' => '<p>|</p>',
477 ],
478 ],
479 '',
480 ],
481 'One collection with maxItems' => [
482 [
483 'collections' => '1',
484 'maxItems' => '2',
485 'renderObj' => 'TEXT',
486 'renderObj.' => [
487 'data' => 'file:current:name',
488 'wrap' => '<p>|</p>',
489 ],
490 ],
491 '<p>File 1</p><p>File 2</p>',
492 ],
493 'One collection with maxItems higher than allowed' => [
494 [
495 'collections' => '1',
496 'maxItems' => '4',
497 'renderObj' => 'TEXT',
498 'renderObj.' => [
499 'data' => 'file:current:name',
500 'wrap' => '<p>|</p>',
501 ],
502 ],
503 '<p>File 1</p><p>File 2</p><p>File 3</p>',
504 ],
505 'One collections with begin and maxItems' => [
506 [
507 'collections' => '1',
508 'begin' => '1',
509 'maxItems' => '1',
510 'renderObj' => 'TEXT',
511 'renderObj.' => [
512 'data' => 'file:current:name',
513 'wrap' => '<p>|</p>',
514 ],
515 ],
516 '<p>File 2</p>',
517 ],
518 'Multiple collections' => [
519 [
520 'collections' => '1,2,3',
521 'renderObj' => 'TEXT',
522 'renderObj.' => [
523 'data' => 'file:current:name',
524 'wrap' => '<p>|</p>',
525 ],
526 ],
527 '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
528 ],
529 'Multiple collections with begin' => [
530 [
531 'collections' => '1,2,3',
532 'begin' => '3',
533 'renderObj' => 'TEXT',
534 'renderObj.' => [
535 'data' => 'file:current:name',
536 'wrap' => '<p>|</p>',
537 ],
538 ],
539 '<p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
540 ],
541 'Multiple collections with negative begin' => [
542 [
543 'collections' => '1,2,3',
544 'begin' => '-3',
545 'renderObj' => 'TEXT',
546 'renderObj.' => [
547 'data' => 'file:current:name',
548 'wrap' => '<p>|</p>',
549 ],
550 ],
551 '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
552 ],
553 'Multiple collections with maxItems' => [
554 [
555 'collections' => '1,2,3',
556 'maxItems' => '5',
557 'renderObj' => 'TEXT',
558 'renderObj.' => [
559 'data' => 'file:current:name',
560 'wrap' => '<p>|</p>',
561 ],
562 ],
563 '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p>',
564 ],
565 'Multiple collections with negative maxItems' => [
566 [
567 'collections' => '1,2,3',
568 'maxItems' => '-5',
569 'renderObj' => 'TEXT',
570 'renderObj.' => [
571 'data' => 'file:current:name',
572 'wrap' => '<p>|</p>',
573 ],
574 ],
575 '',
576 ],
577 'Multiple collections with begin and maxItems' => [
578 [
579 'collections' => '1,2,3',
580 'begin' => '4',
581 'maxItems' => '3',
582 'renderObj' => 'TEXT',
583 'renderObj.' => [
584 'data' => 'file:current:name',
585 'wrap' => '<p>|</p>',
586 ],
587 ],
588 '<p>File 5</p><p>File 6</p><p>File 7</p>',
589 ],
590 'Multiple collections unsorted' => [
591 [
592 'collections' => '1,3,2',
593 'renderObj' => 'TEXT',
594 'renderObj.' => [
595 'data' => 'file:current:name',
596 'wrap' => '<p>|</p>',
597 ],
598 ],
599 '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 7</p><p>File 8</p><p>File 9</p><p>File 4</p><p>File 5</p><p>File 6</p>',
600 ],
601 'Multiple collections sorted by name' => [
602 [
603 'collections' => '3,1,2',
604 'sorting' => 'name',
605 'renderObj' => 'TEXT',
606 'renderObj.' => [
607 'data' => 'file:current:name',
608 'wrap' => '<p>|</p>',
609 ],
610 ],
611 '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
612 ],
613 ];
614 }
615
616 /**
617 * @test
618 * @dataProvider renderReturnsFilesForCollectionsDataProvider
619 * @param array $configuration
620 * @param string $expected
621 */
622 public function renderReturnsFilesForCollections(array $configuration, string $expected): void
623 {
624 $collectionMap = [];
625 $fileCount = 1;
626 for ($i = 1; $i < 4; $i++) {
627 $fileReferenceArray = [];
628 for ($j = 1; $j < 4; $j++) {
629 $fileReference = $this->createMock(FileReference::class);
630 $fileReference->expects($this->any())
631 ->method('getName')
632 ->will($this->returnValue('File ' . $fileCount));
633 $fileReference->expects($this->any())
634 ->method('hasProperty')
635 ->with('name')
636 ->will($this->returnValue(true));
637 $fileReference->expects($this->any())
638 ->method('getProperty')
639 ->with('name')
640 ->will($this->returnValue('File ' . $fileCount));
641
642 $fileReferenceArray[] = $fileReference;
643 $fileCount++;
644 }
645
646 $collection = $this->createMock(StaticFileCollection::class);
647 $collection->expects($this->any())
648 ->method('getItems')
649 ->will($this->returnValue($fileReferenceArray));
650
651 $collectionMap[] = [$i, $collection];
652 }
653
654 $collectionRepository = $this->getMockBuilder(FileCollectionRepository::class)->getMock();
655 $collectionRepository->expects($this->any())
656 ->method('findByUid')
657 ->will($this->returnValueMap($collectionMap));
658 $fileCollector = $this->getMockBuilder(FileCollector::class)
659 ->setMethods(['getFileCollectionRepository'])
660 ->getMock();
661 $fileCollector->expects($this->any())
662 ->method('getFileCollectionRepository')
663 ->will($this->returnValue($collectionRepository));
664 $this->subject->expects($this->any())
665 ->method('getFileCollector')
666 ->will($this->returnValue($fileCollector));
667
668 $this->assertSame($expected, $this->subject->render($configuration));
669 }
670
671 /**
672 * @return array
673 */
674 public function renderReturnsFilesForFoldersDataProvider(): array
675 {
676 return [
677 'One folder' => [
678 [
679 'folders' => '1:myfolder/',
680 'renderObj' => 'TEXT',
681 'renderObj.' => [
682 'data' => 'file:current:name',
683 'wrap' => '<p>|</p>',
684 ],
685 ],
686 '<p>File 1</p><p>File 2</p><p>File 3</p>',
687 ],
688 'One folder with begin' => [
689 [
690 'folders' => '1:myfolder/',
691 'begin' => '1',
692 'renderObj' => 'TEXT',
693 'renderObj.' => [
694 'data' => 'file:current:name',
695 'wrap' => '<p>|</p>',
696 ],
697 ],
698 '<p>File 2</p><p>File 3</p>',
699 ],
700 'One folder with begin higher than allowed' => [
701 [
702 'folders' => '1:myfolder/',
703 'begin' => '3',
704 'renderObj' => 'TEXT',
705 'renderObj.' => [
706 'data' => 'file:current:name',
707 'wrap' => '<p>|</p>',
708 ],
709 ],
710 '',
711 ],
712 'One folder with maxItems' => [
713 [
714 'folders' => '1:myfolder/',
715 'maxItems' => '2',
716 'renderObj' => 'TEXT',
717 'renderObj.' => [
718 'data' => 'file:current:name',
719 'wrap' => '<p>|</p>',
720 ],
721 ],
722 '<p>File 1</p><p>File 2</p>',
723 ],
724 'One folder with maxItems higher than allowed' => [
725 [
726 'folders' => '1:myfolder/',
727 'maxItems' => '4',
728 'renderObj' => 'TEXT',
729 'renderObj.' => [
730 'data' => 'file:current:name',
731 'wrap' => '<p>|</p>',
732 ],
733 ],
734 '<p>File 1</p><p>File 2</p><p>File 3</p>',
735 ],
736 'One folder with begin and maxItems' => [
737 [
738 'folders' => '1:myfolder/',
739 'begin' => '1',
740 'maxItems' => '1',
741 'renderObj' => 'TEXT',
742 'renderObj.' => [
743 'data' => 'file:current:name',
744 'wrap' => '<p>|</p>',
745 ],
746 ],
747 '<p>File 2</p>',
748 ],
749 'Multiple folders' => [
750 [
751 'folders' => '1:myfolder/,2:myfolder/,3:myfolder/',
752 'renderObj' => 'TEXT',
753 'renderObj.' => [
754 'data' => 'file:current:name',
755 'wrap' => '<p>|</p>',
756 ],
757 ],
758 '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
759 ],
760 'Multiple folders with begin' => [
761 [
762 'folders' => '1:myfolder/,2:myfolder/,3:myfolder/',
763 'begin' => '3',
764 'renderObj' => 'TEXT',
765 'renderObj.' => [
766 'data' => 'file:current:name',
767 'wrap' => '<p>|</p>',
768 ],
769 ],
770 '<p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
771 ],
772 'Multiple folders with negative begin' => [
773 [
774 'folders' => '1:myfolder/,2:myfolder/,3:myfolder/',
775 'begin' => '-3',
776 'renderObj' => 'TEXT',
777 'renderObj.' => [
778 'data' => 'file:current:name',
779 'wrap' => '<p>|</p>',
780 ],
781 ],
782 '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
783 ],
784 'Multiple folders with maxItems' => [
785 [
786 'folders' => '1:myfolder/,2:myfolder/,3:myfolder/',
787 'maxItems' => '5',
788 'renderObj' => 'TEXT',
789 'renderObj.' => [
790 'data' => 'file:current:name',
791 'wrap' => '<p>|</p>',
792 ],
793 ],
794 '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p>',
795 ],
796 'Multiple folders with negative maxItems' => [
797 [
798 'folders' => '1:myfolder/,2:myfolder/,3:myfolder/',
799 'maxItems' => '-5',
800 'renderObj' => 'TEXT',
801 'renderObj.' => [
802 'data' => 'file:current:name',
803 'wrap' => '<p>|</p>',
804 ],
805 ],
806 '',
807 ],
808 'Multiple folders with begin and maxItems' => [
809 [
810 'folders' => '1:myfolder/,2:myfolder/,3:myfolder/',
811 'begin' => '4',
812 'maxItems' => '3',
813 'renderObj' => 'TEXT',
814 'renderObj.' => [
815 'data' => 'file:current:name',
816 'wrap' => '<p>|</p>',
817 ],
818 ],
819 '<p>File 5</p><p>File 6</p><p>File 7</p>',
820 ],
821 'Multiple folders unsorted' => [
822 [
823 'folders' => '1:myfolder/,3:myfolder/,2:myfolder/',
824 'renderObj' => 'TEXT',
825 'renderObj.' => [
826 'data' => 'file:current:name',
827 'wrap' => '<p>|</p>',
828 ],
829 ],
830 '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 7</p><p>File 8</p><p>File 9</p><p>File 4</p><p>File 5</p><p>File 6</p>',
831 ],
832 'Multiple folders sorted by name' => [
833 [
834 'folders' => '3:myfolder/,1:myfolder/,2:myfolder/',
835 'sorting' => 'name',
836 'renderObj' => 'TEXT',
837 'renderObj.' => [
838 'data' => 'file:current:name',
839 'wrap' => '<p>|</p>',
840 ],
841 ],
842 '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
843 ],
844 'Multiple folders recursively' => [
845 [
846 'folders' => '1:myfolder/',
847 'folders.' => [
848 'recursive' => '1'
849 ],
850 'renderObj' => 'TEXT',
851 'renderObj.' => [
852 'data' => 'file:current:name',
853 'wrap' => '<p>|</p>',
854 ],
855 ],
856 '<p>File 7</p><p>File 8</p><p>File 9</p><p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p><p>File 6</p>',
857 true
858 ],
859 'Multiple folders recursively, sorted by name' => [
860 [
861 'folders' => '1:myfolder/',
862 'folders.' => [
863 'recursive' => '1'
864 ],
865 'sorting' => 'name',
866 'renderObj' => 'TEXT',
867 'renderObj.' => [
868 'data' => 'file:current:name',
869 'wrap' => '<p>|</p>',
870 ],
871 ],
872 '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
873 true
874 ],
875 ];
876 }
877
878 /**
879 * @test
880 * @dataProvider renderReturnsFilesForFoldersDataProvider
881 * @param array $configuration
882 * @param string $expected
883 * @param bool $recursive
884 */
885 public function renderReturnsFilesForFolders(array $configuration, string $expected, bool $recursive = false): void
886 {
887 $folderMap = [];
888 $folders = [];
889 $fileCount = 1;
890 $filesArrayForFolder = [];
891 for ($i = 1; $i < 4; $i++) {
892 $filesArrayForFolder[$i] = [];
893 for ($j = 1; $j < 4; $j++) {
894 $file = $this->createMock(File::class);
895 $file->expects($this->any())
896 ->method('getName')
897 ->will($this->returnValue('File ' . $fileCount));
898 $file->expects($this->any())
899 ->method('hasProperty')
900 ->with('name')
901 ->will($this->returnValue(true));
902 $file->expects($this->any())
903 ->method('getProperty')
904 ->with('name')
905 ->will($this->returnValue('File ' . $fileCount));
906
907 $filesArrayForFolder[$i][] = $file;
908 $fileCount++;
909 }
910
911 $folder = $this->createMock(Folder::class);
912
913 if ($recursive) {
914 if ($i < 3) {
915 $folders[$i] = $folder;
916 $folderMap[$i] = ['1:myfolder/mysubfolder-' . $i . '/', $folder];
917 } else {
918 $folder->expects($this->any())
919 ->method('getSubfolders')
920 ->will($this->returnValue($folders));
921 $folderMap[$i] = ['1:myfolder/', $folder];
922 }
923 } else {
924 $folderMap[$i] = [$i . ':myfolder/', $folder];
925 }
926 }
927 foreach ($folderMap as $i => $folderMapInfo) {
928 if ($i < 3 || !$recursive) {
929 $folderMapInfo[1]->expects($this->any())
930 ->method('getFiles')
931 ->will($this->returnValue($filesArrayForFolder[$i]));
932 } else {
933 $recursiveFiles = array_merge(
934 $filesArrayForFolder[3],
935 $filesArrayForFolder[1],
936 $filesArrayForFolder[2]
937 );
938 $folderMapInfo[1]->expects($this->any())
939 ->method('getFiles')
940 ->will($this->returnValue($recursiveFiles));
941 }
942 }
943
944 $resourceFactory = $this->getMockBuilder(ResourceFactory::class)->getMock();
945 $resourceFactory->expects($this->any())
946 ->method('getFolderObjectFromCombinedIdentifier')
947 ->will($this->returnValueMap($folderMap));
948 $fileCollector = $this->getMockBuilder(FileCollector::class)
949 ->setMethods(['getResourceFactory'])
950 ->getMock();
951 $fileCollector->expects($this->any())
952 ->method('getResourceFactory')
953 ->will($this->returnValue($resourceFactory));
954
955 $this->subject->expects($this->any())
956 ->method('getFileCollector')
957 ->will($this->returnValue($fileCollector));
958
959 $this->assertSame($expected, $this->subject->render($configuration));
960 }
961 }