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