‪TYPO3CMS  ‪main
ExportTest.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
18 use PHPUnit\Framework\Attributes\DataProvider;
19 use PHPUnit\Framework\Attributes\Test;
20 use PHPUnit\Framework\MockObject\MockObject;
24 use TYPO3\TestingFramework\Core\AccessibleObjectInterface;
25 
27 {
29  'typo3/sysext/impexp/Tests/Functional/Fixtures/Folders/fileadmin/user_upload' => 'fileadmin/user_upload',
30  ];
31 
32  protected array ‪$testExtensionsToLoad = [
33  'typo3/sysext/impexp/Tests/Functional/Fixtures/Extensions/template_extension',
34  ];
35 
36  protected ‪Export&MockObject&AccessibleObjectInterface ‪$exportMock;
37 
38  protected array ‪$recordTypesIncludeFields =
39  [
40  'pages' => [
41  'title',
42  'deleted',
43  'doktype',
44  'hidden',
45  'perms_everybody',
46  ],
47  'tt_content' => [
48  'CType',
49  'header',
50  'header_link',
51  'deleted',
52  'hidden',
53  't3ver_oid',
54  ],
55  'sys_file' => [
56  'storage',
57  'type',
58  'metadata',
59  'identifier',
60  'identifier_hash',
61  'folder_hash',
62  'mime_type',
63  'name',
64  'sha1',
65  'size',
66  'creation_date',
67  'modification_date',
68  ],
69  ]
70  ;
71 
72  protected function ‪setUp(): void
73  {
74  parent::setUp();
75  $this->exportMock = $this->getAccessibleMock(Export::class, ['setMetaData']);
76  }
77 
78  #[Test]
80  {
81  $temporaryFolderName = $this->exportMock->getOrCreateTemporaryFolderName();
82  $temporaryFileName = $temporaryFolderName . '/export_file.txt';
83  file_put_contents($temporaryFileName, 'Hello TYPO3 World.');
84  self::assertDirectoryExists($temporaryFolderName);
85  self::assertTrue(is_file($temporaryFileName));
86 
87  $this->exportMock->removeTemporaryFolderName();
88  self::assertDirectoryDoesNotExist($temporaryFolderName);
89  self::assertFalse(is_file($temporaryFileName));
90  }
91 
92  #[Test]
94  {
95  $exportFolder = $this->exportMock->getOrCreateDefaultImportExportFolder();
96  $exportFileName = 'export_file.txt';
97  $exportFolder->createFile($exportFileName);
98  self::assertDirectoryExists(‪Environment::getPublicPath() . '/' . $exportFolder->getPublicUrl());
99  self::assertTrue(is_file(‪Environment::getPublicPath() . '/' . $exportFolder->getPublicUrl() . $exportFileName));
100 
101  $this->exportMock->removeDefaultImportExportFolder();
102  self::assertDirectoryDoesNotExist(‪Environment::getPublicPath() . '/' . $exportFolder->getPublicUrl());
103  self::assertFalse(is_file(‪Environment::getPublicPath() . '/' . $exportFolder->getPublicUrl() . $exportFileName));
104  }
105 
106  #[Test]
108  {
109  $this->exportMock->process();
110  $previewData = $this->exportMock->renderPreview();
111  self::assertEquals([
112  'update' => false,
113  'showDiff' => false,
114  'insidePageTree' => [],
115  'outsidePageTree' => [],
116  ], $previewData);
117  }
118 
119  #[Test]
121  {
122  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/pages.csv');
123  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/tt_content.csv');
124  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/sys_file.csv');
125  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/sys_file-export-pages-and-tt-content.csv');
126  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/sys_file_storage.csv');
127 
128  $renderPreviewExport = include __DIR__ . '/Fixtures/ArrayAssertions/RenderPreviewExportPageAndRecords.php';
129 
130  $this->exportMock->setPid(0);
131  $this->exportMock->setLevels(‪Export::LEVELS_INFINITE);
132  $this->exportMock->setTables(['_ALL']);
133  $this->exportMock->setRecordTypesIncludeFields($this->recordTypesIncludeFields);
134  $this->exportMock->process();
135  $previewData = $this->exportMock->renderPreview();
136  // file_put_contents(
137  // __DIR__ . '/Fixtures/ArrayAssertions/RenderPreviewExportPageAndRecords.php',
138  // str_replace(
139  // ['array (', '),', ');'],
140  // ['[', '],', '];'],
141  // '<?php' . "\n\nreturn " . var_export($previewData, true) . ";\n")
142  // );
143  self::assertEquals($renderPreviewExport, $previewData);
144  }
145 
146  #[Test]
148  {
149  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/pages.csv');
150  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/tt_content-with-softrefs.csv');
151  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/sys_file.csv');
152  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/sys_file_storage.csv');
153 
154  $renderPreviewExport = include __DIR__ . '/Fixtures/ArrayAssertions/RenderPreviewExportPageAndRecordsWithSoftRefs.php';
155 
156  $this->exportMock->setPid(0);
157  $this->exportMock->setLevels(‪Export::LEVELS_INFINITE);
158  $this->exportMock->setTables(['_ALL']);
159  $this->exportMock->setRecordTypesIncludeFields($this->recordTypesIncludeFields);
160  $this->exportMock->process();
161  $previewData = $this->exportMock->renderPreview();
162  // file_put_contents(
163  // __DIR__ . '/Fixtures/ArrayAssertions/RenderPreviewExportPageAndRecordsWithSoftRefs.php',
164  // str_replace(
165  // ['array (', '),', ');'],
166  // ['[', '],', '];'],
167  // '<?php' . "\n\nreturn " . var_export($previewData, true) . ";\n")
168  // );
169  self::assertEquals($renderPreviewExport, $previewData);
170  }
171 
172  #[Test]
173  public function ‪renderPreviewForExportOfTable(): void
174  {
175  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/pages.csv');
176  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/tt_content.csv');
177  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/sys_file.csv');
178  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/sys_file-export-pages-and-tt-content.csv');
179 
180  $renderPreviewExport = include __DIR__ . '/Fixtures/ArrayAssertions/RenderPreviewExportTable.php';
181 
182  $this->exportMock->setList(['tt_content:1']);
183  $this->exportMock->setRecordTypesIncludeFields($this->recordTypesIncludeFields);
184  $this->exportMock->process();
185  $previewData = $this->exportMock->renderPreview();
186  // file_put_contents(
187  // __DIR__ . '/Fixtures/ArrayAssertions/RenderPreviewExportTable.php',
188  // str_replace(
189  // ['array (', '),', ');'],
190  // ['[', '],', '];'],
191  // '<?php' . "\n\nreturn " . var_export($previewData, true) . ";\n")
192  // );
193  self::assertEquals($renderPreviewExport, $previewData);
194  }
195 
196  #[Test]
197  public function ‪renderPreviewForExportOfRecords(): void
198  {
199  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/pages.csv');
200  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/tt_content.csv');
201  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/sys_file.csv');
202  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/sys_file-export-pages-and-tt-content.csv');
203 
204  $renderPreviewExport = include __DIR__ . '/Fixtures/ArrayAssertions/RenderPreviewExportRecords.php';
205 
206  $this->exportMock->setRecord(['tt_content:1', 'tt_content:2']);
207  $this->exportMock->setRecordTypesIncludeFields($this->recordTypesIncludeFields);
208  $this->exportMock->process();
209  $previewData = $this->exportMock->renderPreview();
210  // file_put_contents(
211  // __DIR__ . '/Fixtures/ArrayAssertions/RenderPreviewExportRecords.php',
212  // str_replace(
213  // ['array (', '),', ');'],
214  // ['[', '],', '];'],
215  // '<?php' . "\n\nreturn " . var_export($previewData, true) . ";\n")
216  // );
217  self::assertEquals($renderPreviewExport, $previewData);
218  }
219 
220  public static function ‪addFilesSucceedsDataProvider(): array
221  {
222  return [
223  ['dat' => [
224  'header' => [
225  'files' => [
226  '123456789' => [
227  'filename' => 'filename.jpg',
228  'relFileName' => 'filename.jpg',
229  ],
230  ],
231  ],
232  ], 'relations' => [
233  '123456789',
234  ], 'expected' => [
235  [
236  'ref' => 'FILE',
237  'type' => 'file',
238  'msg' => '',
239  'preCode' => '<span class="indent indent-inline-block" style="--indent-level: 1"></span><span title="FILE" class="t3js-icon icon icon-size-small icon-state-default icon-status-reference-hard" data-identifier="status-reference-hard" aria-hidden="true">
240 ' . "\t" . '<span class="icon-markup">
241 <img src="typo3/sysext/impexp/Resources/Public/Icons/status-reference-hard.png" width="16" height="16" alt="" />
242 ' . "\t" . '</span>' . "\n\t\n" . '</span>',
243  'title' => 'filename.jpg',
244  'showDiffContent' => '',
245  ],
246  ]],
247  ];
248  }
249 
253  #[DataProvider('addFilesSucceedsDataProvider')]
254  #[Test]
255  public function ‪addFilesSucceeds(array $dat, array $relations, array $expected): void
256  {
257  ‪$exportMock = $this->getAccessibleMock(
258  Export::class,
259  ['addError'],
260  [],
261  '',
262  true
263  );
264 
265  $lines = [];
266  ‪$exportMock->_set('dat', $dat);
267  ‪$exportMock->‪addFiles($relations, $lines, 0);
268  self::assertEquals($expected, $lines);
269  }
270 
271  #[Test]
272  public function ‪renderSucceedsWithoutArguments(): void
273  {
274  $this->exportMock->process();
275  $actual = $this->exportMock->render();
276 
277  self::assertXmlStringEqualsXmlFile(__DIR__ . '/Fixtures/XmlExports/empty.xml', $actual);
278  }
279 
280  #[Test]
281  public function ‪saveXmlToFileIsDefaultAndSucceeds(): void
282  {
283  $this->exportMock->setExportFileName('export');
284  $this->exportMock->process();
285  $file = $this->exportMock->saveToFile();
286  $filePath = ‪Environment::getPublicPath() . '/' . $file->getPublicUrl();
287 
288  $this->testFilesToDelete[] = $filePath;
289 
290  self::assertStringEndsWith('export.xml', $filePath);
291  self::assertXmlFileEqualsXmlFile(__DIR__ . '/Fixtures/XmlExports/empty.xml', $filePath);
292  }
293 
294  #[Test]
295  public function ‪saveT3dToFileSucceeds(): void
296  {
297  $this->exportMock->setExportFileName('export');
298  $this->exportMock->setExportFileType(‪Export::FILETYPE_T3D);
299  $this->exportMock->process();
300  $file = $this->exportMock->saveToFile();
301  $filePath = ‪Environment::getPublicPath() . '/' . $file->getPublicUrl();
302 
303  $this->testFilesToDelete[] = $filePath;
304 
305  // remove final newlines
306  $expected = trim(file_get_contents(__DIR__ . '/Fixtures/T3dExports/empty.t3d'));
307  $actual = trim(file_get_contents($filePath));
308 
309  self::assertStringEndsWith('export.t3d', $filePath);
310  self::assertEquals($expected, $actual);
311  }
312 
313  #[Test]
314  public function ‪saveT3dCompressedToFileSucceeds(): void
315  {
316  if (!function_exists('gzcompress')) {
317  self::markTestSkipped('The function gzcompress() is not available for compression.');
318  }
319 
320  $this->exportMock->setExportFileName('export');
321  $this->exportMock->setExportFileType(‪Export::FILETYPE_T3DZ);
322  $this->exportMock->process();
323  $file = $this->exportMock->saveToFile();
324  $filePath = ‪Environment::getPublicPath() . '/' . $file->getPublicUrl();
325 
326  $this->testFilesToDelete[] = $filePath;
327 
328  // remove final newlines
329  $expected = trim(file_get_contents(__DIR__ . '/Fixtures/T3dExports/empty-z.t3d'));
330  $actual = trim(file_get_contents($filePath));
331 
332  self::assertStringEndsWith('export-z.t3d', $filePath);
333  self::assertEquals($expected, $actual);
334  }
335 
336  #[Test]
337  public function ‪saveToFileCleansUpTemporaryFolder(): void
338  {
339  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/pages.csv');
340  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/tt_content.csv');
341  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/sys_file.csv');
342  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/sys_file-export-pages-and-tt-content.csv');
343 
344  $fileDirectory = ‪Environment::getVarPath() . '/transient';
345  $numTemporaryFilesAndFoldersBeforeImport = iterator_count(new \FilesystemIterator($fileDirectory, \FilesystemIterator::SKIP_DOTS));
346 
347  $this->exportMock->setPid(1);
348  $this->exportMock->setLevels(1);
349  $this->exportMock->setTables(['_ALL']);
350  $this->exportMock->setRelOnlyTables(['sys_file']);
351  $this->exportMock->setRecordTypesIncludeFields($this->recordTypesIncludeFields);
352  $this->exportMock->setSaveFilesOutsideExportFile(true);
353  $this->exportMock->setExportFileName('export');
354  $this->exportMock->process();
355  $file = $this->exportMock->saveToFile();
356 
357  $this->testFilesToDelete[] = ‪Environment::getPublicPath() . '/' . $file->getPublicUrl();
358 
359  self::assertCount($numTemporaryFilesAndFoldersBeforeImport, new \FilesystemIterator($fileDirectory, \FilesystemIterator::SKIP_DOTS));
360  self::assertEmpty($this->exportMock->_get('temporaryFolderName'));
361  }
362 
363  #[Test]
365  {
366  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/pages.csv');
367  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/tt_content.csv');
368  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/sys_file.csv');
369  $this->importCSVDataSet(__DIR__ . '/Fixtures/DatabaseImports/sys_file-export-pages-and-tt-content.csv');
370 
371  $this->exportMock->setPid(1);
372  $this->exportMock->setLevels(1);
373  $this->exportMock->setTables(['_ALL']);
374  $this->exportMock->setRelOnlyTables(['sys_file']);
375  $this->exportMock->setRecordTypesIncludeFields($this->recordTypesIncludeFields);
376  $this->exportMock->setSaveFilesOutsideExportFile(true);
377  $this->exportMock->setExportFileName('export');
378  $this->exportMock->process();
379  $this->exportMock->saveToFile();
380 
382  $importExportFolder = $this->exportMock->_get('defaultImportExportFolder');
383  $filesFolderName = 'export.xml.files';
384  self::assertTrue($importExportFolder->hasFolder($filesFolderName));
385 
386  $this->exportMock->setSaveFilesOutsideExportFile(false);
387  $this->exportMock->process();
388  $file = $this->exportMock->saveToFile();
389 
390  $this->testFilesToDelete[] = ‪Environment::getPublicPath() . '/' . $file->getPublicUrl();
391 
392  self::assertFalse($importExportFolder->hasFolder($filesFolderName));
393  }
394 }
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\renderPreviewWithoutArgumentsReturnsBasicArray
‪renderPreviewWithoutArgumentsReturnsBasicArray()
Definition: ExportTest.php:107
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\renderPreviewForExportOfRecords
‪renderPreviewForExportOfRecords()
Definition: ExportTest.php:197
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\creationAndDeletionOfTemporaryFolderSucceeds
‪creationAndDeletionOfTemporaryFolderSucceeds()
Definition: ExportTest.php:79
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\saveT3dToFileSucceeds
‪saveT3dToFileSucceeds()
Definition: ExportTest.php:295
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\setUp
‪setUp()
Definition: ExportTest.php:72
‪TYPO3\CMS\Impexp\ImportExport\addFiles
‪addFiles(array $relations, array &$lines, int $indent, string $tokenID='')
Definition: ImportExport.php:588
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static getPublicPath()
Definition: Environment.php:187
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\addFilesSucceedsDataProvider
‪static addFilesSucceedsDataProvider()
Definition: ExportTest.php:220
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\saveXmlToFileIsDefaultAndSucceeds
‪saveXmlToFileIsDefaultAndSucceeds()
Definition: ExportTest.php:281
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\renderSucceedsWithoutArguments
‪renderSucceedsWithoutArguments()
Definition: ExportTest.php:272
‪TYPO3\CMS\Impexp\Tests\Functional
Definition: AbstractImportExportTestCase.php:18
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\saveToFileCleansUpTemporaryFolder
‪saveToFileCleansUpTemporaryFolder()
Definition: ExportTest.php:337
‪TYPO3\CMS\Core\Core\Environment\getVarPath
‪static getVarPath()
Definition: Environment.php:197
‪TYPO3\CMS\Impexp\Export\LEVELS_INFINITE
‪const LEVELS_INFINITE
Definition: Export.php:54
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest
Definition: ExportTest.php:27
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\addFilesSucceeds
‪addFilesSucceeds(array $dat, array $relations, array $expected)
Definition: ExportTest.php:255
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\$testExtensionsToLoad
‪array $testExtensionsToLoad
Definition: ExportTest.php:32
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\renderPreviewForExportOfTable
‪renderPreviewForExportOfTable()
Definition: ExportTest.php:173
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\saveToFileCleansUpFormerExportsOfSameName
‪saveToFileCleansUpFormerExportsOfSameName()
Definition: ExportTest.php:364
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\renderPreviewForExportOfPageAndRecordsWithSoftRefs
‪renderPreviewForExportOfPageAndRecordsWithSoftRefs()
Definition: ExportTest.php:147
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\creationAndDeletionOfDefaultImportExportFolderSucceeds
‪creationAndDeletionOfDefaultImportExportFolderSucceeds()
Definition: ExportTest.php:93
‪TYPO3\CMS\Impexp\Export\FILETYPE_T3D
‪const FILETYPE_T3D
Definition: Export.php:57
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\renderPreviewForExportOfPageAndRecords
‪renderPreviewForExportOfPageAndRecords()
Definition: ExportTest.php:120
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:38
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\$recordTypesIncludeFields
‪array $recordTypesIncludeFields
Definition: ExportTest.php:38
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\$exportMock
‪Export &MockObject &AccessibleObjectInterface $exportMock
Definition: ExportTest.php:36
‪TYPO3\CMS\Impexp\Tests\Functional\AbstractImportExportTestCase
Definition: AbstractImportExportTestCase.php:33
‪TYPO3\CMS\Impexp\Export\FILETYPE_T3DZ
‪const FILETYPE_T3DZ
Definition: Export.php:58
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:41
‪TYPO3\CMS\Impexp\Export
Definition: Export.php:52
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\saveT3dCompressedToFileSucceeds
‪saveT3dCompressedToFileSucceeds()
Definition: ExportTest.php:314
‪TYPO3\CMS\Impexp\Tests\Functional\ExportTest\$pathsToProvideInTestInstance
‪array $pathsToProvideInTestInstance
Definition: ExportTest.php:28