ef8b7891025ba013f3a0dc95a0352686531b90b1
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Tests / Functional / Controller / Page / LocalizationControllerTest.php
1 <?php
2 declare(strict_types = 1);
3
4 namespace TYPO3\CMS\Backend\Tests\Functional\Controller\Page;
5
6 /*
7 * This file is part of the TYPO3 CMS project.
8 *
9 * It is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License, either version 2
11 * of the License, or any later version.
12 *
13 * For the full copyright and license information, please read the
14 * LICENSE.txt file that was distributed with this source code.
15 *
16 * The TYPO3 project - inspiring people to share!
17 */
18
19 use TYPO3\CMS\Backend\Controller\Page\LocalizationController;
20 use TYPO3\CMS\Core\Core\Bootstrap;
21 use TYPO3\CMS\Core\DataHandling\DataHandler;
22 use TYPO3\CMS\Core\Http\ServerRequest;
23 use TYPO3\CMS\Core\Utility\GeneralUtility;
24 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\ActionService;
25
26 /**
27 * Test case for TYPO3\CMS\Backend\Controller\Page\LocalizationController
28 */
29 class LocalizationControllerTest extends \TYPO3\TestingFramework\Core\Functional\FunctionalTestCase
30 {
31 /**
32 * @var string
33 */
34 protected $assertionDataSetDirectory = 'typo3/sysext/backend/Tests/Functional/Controller/Page/Localization/CSV/DataSet/';
35
36 /**
37 * @var LocalizationController|\PHPUnit_Framework_MockObject_MockObject
38 */
39 protected $subject;
40
41 /**
42 * @var \TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\ActionService
43 */
44 protected $actionService;
45
46 /**
47 * @var \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
48 */
49 protected $backendUser;
50
51 /**
52 * @var array
53 */
54 protected $coreExtensionsToLoad = ['workspaces'];
55
56 /**
57 * Sets up this test case.
58 */
59 protected function setUp(): void
60 {
61 parent::setUp();
62
63 $this->backendUser = $this->setUpBackendUserFromFixture(1);
64 $this->backendUser->workspace = 0;
65
66 Bootstrap::initializeLanguageObject();
67 $this->actionService = GeneralUtility::makeInstance(ActionService::class);
68
69 $this->importDataSet(__DIR__ . '/Fixtures/pages.xml');
70 $this->importDataSet('PACKAGE:typo3/testing-framework/Resources/Core/Functional/Fixtures/sys_language.xml');
71 $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/tt_content-default-language.xml');
72
73 $this->subject = $this->getMockBuilder(LocalizationController::class)
74 ->setMethods(['getPageColumns'])
75 ->getMock()
76 ;
77 }
78
79 /**
80 * @test
81 * see DataSet/TranslatedFromDefault.csv
82 */
83 public function recordsGetTranslatedFromDefaultLanguage(): void
84 {
85 $params = [
86 'pageId' => 1,
87 'srcLanguageId' => 0,
88 'destLanguageId' => 1,
89 'uidList' => [1, 2, 3],
90 'action' => LocalizationController::ACTION_LOCALIZE,
91 ];
92 $this->callInaccessibleMethod($this->subject, 'process', $params);
93 $this->assertAssertionDataSet('TranslatedFromDefault');
94 }
95
96 /**
97 * @test
98 */
99 public function recordsGetTranslatedFromDifferentTranslation(): void
100 {
101 $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/tt_content-danish-language.xml');
102
103 $params = [
104 'pageId' => 1,
105 'srcLanguageId' => 1,
106 'destLanguageId' => 2,
107 'uidList' => [4, 5, 6], // uids of tt_content-danish-language
108 'action' => LocalizationController::ACTION_LOCALIZE,
109 ];
110 $this->callInaccessibleMethod($this->subject, 'process', $params);
111 $this->assertAssertionDataSet('TranslatedFromTranslation');
112 }
113
114 /**
115 * @test
116 */
117 public function recordsGetCopiedFromDefaultLanguage(): void
118 {
119 $params = [
120 'pageId' => 1,
121 'srcLanguageId' => 0,
122 'destLanguageId' => 2,
123 'uidList' => [1, 2, 3],
124 'action' => LocalizationController::ACTION_COPY,
125 ];
126 $this->callInaccessibleMethod($this->subject, 'process', $params);
127 $this->assertAssertionDataSet('CopiedFromDefault');
128 }
129
130 /**
131 * @test
132 */
133 public function recordsGetCopiedFromAnotherLanguage(): void
134 {
135 $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/tt_content-danish-language.xml');
136
137 $params = [
138 'pageId' => 1,
139 'srcLanguageId' => 1,
140 'destLanguageId' => 2,
141 'uidList' => [4, 5, 6], // uids of tt_content-danish-language
142 'action' => LocalizationController::ACTION_COPY,
143 ];
144 $this->callInaccessibleMethod($this->subject, 'process', $params);
145 $this->assertAssertionDataSet('CopiedFromTranslation');
146 }
147
148 /**
149 * @test
150 */
151 public function copyingNewContentFromLanguageIntoExistingLocalizationHasSameOrdering(): void
152 {
153 $params = [
154 'pageId' => 1,
155 'srcLanguageId' => 0,
156 'destLanguageId' => 1,
157 'uidList' => [1, 2, 3],
158 'action' => LocalizationController::ACTION_COPY,
159 ];
160 $this->callInaccessibleMethod($this->subject, 'process', $params);
161
162 // Create another content element in default language
163 $data = [
164 'tt_content' => [
165 'NEW123456' => [
166 'sys_language_uid' => 0,
167 'header' => 'Test content 2.5',
168 'pid' => -2,
169 'colPos' => 0,
170 ],
171 ],
172 ];
173 $dataHandler = new DataHandler();
174 $dataHandler->start($data, []);
175 $dataHandler->process_datamap();
176 $dataHandler->process_cmdmap();
177 $newContentElementUid = $dataHandler->substNEWwithIDs['NEW123456'];
178
179 // Copy the new content element
180 $params = [
181 'pageId' => 1,
182 'srcLanguageId' => 0,
183 'destLanguageId' => 1,
184 'uidList' => [$newContentElementUid],
185 'action' => LocalizationController::ACTION_COPY,
186 ];
187 $this->callInaccessibleMethod($this->subject, 'process', $params);
188 $this->assertAssertionDataSet('CreatedElementOrdering');
189 }
190
191 /**
192 * @test
193 */
194 public function recordLocalizeSummaryRespectsWorkspaceEncapsulationForDeletedRecords(): void
195 {
196 // Delete record 2 within workspace 1
197 $this->backendUser->workspace = 1;
198 $this->actionService->deleteRecord('tt_content', 2);
199
200 $expectedRecords = [
201 '0' => [
202 ['uid' => 1],
203 ],
204 '1' => [
205 ['uid' => 3],
206 ],
207 ];
208
209 $localizeSummary = $this->getReducedRecordLocalizeSummary();
210
211 $this->assertEquals($expectedRecords, $localizeSummary);
212 }
213
214 /**
215 * @test
216 */
217 public function recordLocalizeSummaryRespectsWorkspaceEncapsulationForMovedRecords(): void
218 {
219 // Move record 2 to page 2 within workspace 1
220 $this->backendUser->workspace = 1;
221 $this->actionService->moveRecord('tt_content', 2, 2);
222
223 $expectedRecords = [
224 '0' => [
225 ['uid' => 1],
226 ],
227 '1' => [
228 ['uid' => 3],
229 ],
230 ];
231
232 $localizeSummary = $this->getReducedRecordLocalizeSummary();
233
234 $this->assertEquals($expectedRecords, $localizeSummary);
235 }
236
237 /**
238 * Get record localized summary list reduced to list of uids
239 *
240 * @return array
241 */
242 protected function getReducedRecordLocalizeSummary(): array
243 {
244 $request = (new ServerRequest())->withQueryParams([
245 'pageId' => 1, // page uid, the records are stored on
246 'destLanguageId' => 1, // destination language uid
247 'languageId' => 0 // source language uid
248 ]);
249
250 $this->subject->method('getPageColumns')->willReturn([
251 0 => 'Column 0',
252 1 => 'Column 1',
253 ]);
254
255 $recordLocalizeSummaryResponse = $this->subject->getRecordLocalizeSummary($request);
256
257 // Reduce the fetched record summary to list of uids
258 if ($recordLocalizeSummary = json_decode((string)$recordLocalizeSummaryResponse->getBody(), true)) {
259 foreach ($recordLocalizeSummary['records'] as $colPos => $records) {
260 foreach ($records as $key => $record) {
261 $recordLocalizeSummary['records'][$colPos][$key] = array_intersect_key($record, ['uid' => '']);
262 }
263 }
264 }
265
266 return $recordLocalizeSummary['records'];
267 }
268
269 /**
270 * @param string $dataSetName
271 */
272 protected function assertAssertionDataSet(string $dataSetName)
273 {
274 $fileName = rtrim($this->assertionDataSetDirectory, '/') . '/' . $dataSetName . '.csv';
275 $fileName = GeneralUtility::getFileAbsFileName($fileName);
276 $this->assertCSVDataSet($fileName);
277 }
278 }