[TASK] Add functional tests for generic persistence
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Functional / Persistence / RelationTest.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Tests\Functional\Relations;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2014 Tymoteusz Motylewski <t.motylewski@gmail.com>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 *
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
26
27 use TYPO3\CMS\Core\Utility\GeneralUtility;
28 use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
29
30 class RelationTest extends \TYPO3\CMS\Core\Tests\FunctionalTestCase {
31
32 /**
33 * @var int number of all records
34 */
35 protected $numberOfRecordsInFixture = 11;
36
37 /**
38 * @var \ExtbaseTeam\BlogExample\Domain\Model\Blog
39 */
40 protected $blog;
41
42 /**
43 * @var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager
44 */
45 protected $persistentManager;
46
47 protected $testExtensionsToLoad = array('typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example');
48
49 protected $coreExtensionsToLoad = array('extbase', 'fluid');
50
51 /**
52 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface The object manager
53 */
54 protected $objectManager;
55
56 /**
57 * Sets up this test suite.
58 */
59 public function setUp() {
60 parent::setUp();
61
62 $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/core/Tests/Functional/Fixtures/pages.xml');
63 $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Persistence/Fixtures/blogs.xml');
64 $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Persistence/Fixtures/posts.xml');
65 $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Persistence/Fixtures/tags.xml');
66 $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Persistence/Fixtures/post-tag-mm.xml');
67
68 $this->objectManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
69 $this->persistentManager = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\PersistenceManager');
70 /* @var $blogRepository \TYPO3\CMS\Extbase\Persistence\Repository */
71 $blogRepository = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Repository\\BlogRepository');
72 $this->blog = $blogRepository->findByUid(1);
73 }
74
75 /**
76 * Tests adding object at the end of sorted 1:M relation (Blog:Posts)
77 *
78 * @test
79 */
80 public function attachPostToBlogAtTheEnd() {
81 $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post');
82 $this->assertSame($this->numberOfRecordsInFixture, $countPosts);
83
84 $newPostTitle = 'sdufhisdhuf';
85 $newPost = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Model\\Post');
86 $newPost->setBlog($this->blog);
87 $newPost->setTitle($newPostTitle);
88 $newPost->setContent('Bla Bla Bla');
89
90 $this->blog->addPost($newPost);
91 $this->updateAndPersistBlog();
92
93 $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post');
94 $this->assertSame(($this->numberOfRecordsInFixture + 1), $countPosts);
95
96 $post = $this->getDatabase()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid(), '', 'sorting DESC');
97 $this->assertSame($newPostTitle, $post['title']);
98 $this->assertSame((string)($this->numberOfRecordsInFixture), $post['sorting']);
99 }
100
101 /**
102 * Tests removing object from the end of sorted 1:M relation (Blog:Posts)
103 *
104 * @test
105 */
106 public function removeLastPostFromBlog() {
107 $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post');
108 $this->assertSame($this->numberOfRecordsInFixture, $countPosts);
109
110 $post = $this->getDatabase()->exec_SELECTgetSingleRow('sorting', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid(), '', 'sorting DESC');
111 $this->assertEquals(10, $post['sorting']);
112
113 $posts = $this->blog->getPosts();
114 $postsArray = $posts->toArray();
115 $latestPost = array_pop($postsArray);
116
117 $this->assertEquals(10, $latestPost->getUid());
118
119 $this->blog->removePost($latestPost);
120 $this->updateAndPersistBlog();
121
122 $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'deleted=0');
123 $this->assertEquals(($this->numberOfRecordsInFixture - 1), $countPosts);
124
125 $post = $this->getDatabase()->exec_SELECTgetSingleRow('uid', 'tx_blogexample_domain_model_post', 'uid =' . $latestPost->getUid() . ' AND deleted=0');
126 $this->assertSame(NULL, $post['uid']);
127
128 $post = $this->getDatabase()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid(), '', 'sorting DESC');
129 $this->assertSame('Post9', $post['title']);
130 $this->assertSame('9', $post['sorting']);
131 }
132
133 /**
134 * Tests adding object in the middle of the sorted 1:M relation (Blog:Posts)
135 *
136 * @test
137 */
138 public function addPostToBlogInTheMiddle() {
139 $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post');
140 $this->assertSame($this->numberOfRecordsInFixture, $countPosts);
141
142 $posts = clone $this->blog->getPosts();
143 $this->blog->getPosts()->removeAll($posts);
144 $counter = 1;
145 $newPostTitle = 'INSERTED POST at position 6';
146 foreach ($posts as $post) {
147 $this->blog->addPost($post);
148 if ($counter == 5) {
149 $newPost = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Model\\Post');
150 $newPost->setBlog($this->blog);
151 $newPost->setTitle($newPostTitle);
152 $newPost->setContent('Bla Bla Bla');
153 $this->blog->addPost($newPost);
154 }
155 $counter++;
156 }
157 $this->updateAndPersistBlog();
158
159 $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'deleted=0');
160 $this->assertSame(($this->numberOfRecordsInFixture + 1), $countPosts);
161
162 //last post
163 $post = $this->getDatabase()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'blog =' . $this->blog->getUid(), '', 'sorting DESC');
164 $this->assertSame('Post10', $post['title']);
165 $this->assertSame('11', $post['sorting']);
166
167 // check sorting of the post added in the middle
168 $post = $this->getDatabase()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'uid=' . ($this->numberOfRecordsInFixture + 1));
169 $this->assertSame($newPostTitle, $post['title']);
170 $this->assertSame('6', $post['sorting']);
171 }
172
173 /**
174 * Tests removing object from the middle of sorted 1:M relation (Blog:Posts)
175 *
176 * @test
177 */
178 public function removeMiddlePostFromBlog() {
179 $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post');
180 $this->assertSame($this->numberOfRecordsInFixture, $countPosts);
181
182 $posts = clone $this->blog->getPosts();
183 $counter = 1;
184 foreach ($posts as $post) {
185 if ($counter == 5) {
186 $this->blog->removePost($post);
187 }
188 $counter++;
189 }
190 $this->updateAndPersistBlog();
191
192 $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'deleted=0');
193 $this->assertSame(($this->numberOfRecordsInFixture - 1), $countPosts);
194
195 $post = $this->getDatabase()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'blog ='.$this->blog->getUid(), '', 'sorting DESC');
196 $this->assertSame('Post10', $post['title']);
197 $this->assertSame('10', $post['sorting']);
198 }
199
200 /**
201 * Tests moving object from the end to the middle of the sorted 1:M relation (Blog:Posts)
202 *
203 * @test
204 */
205 public function movePostFromEndToTheMiddle() {
206 $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post');
207 $this->assertSame($this->numberOfRecordsInFixture, $countPosts);
208
209 $posts = clone $this->blog->getPosts();
210 $postsArray = $posts->toArray();
211 $latestPost = array_pop($postsArray);
212
213 $this->blog->getPosts()->removeAll($posts);
214 $counter = 0;
215 $postCount = $posts->count();
216 foreach ($posts as $post) {
217 if ($counter != ($postCount - 1)) {
218 $this->blog->addPost($post);
219 }
220 if ($counter == 4) {
221 $latestPost->setTitle('MOVED POST ' . $latestPost->getTitle());
222 $this->blog->addPost($latestPost);
223 }
224 $counter++;
225 }
226 $this->updateAndPersistBlog();
227
228 $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_post', 'deleted=0');
229 $this->assertSame($this->numberOfRecordsInFixture, $countPosts);
230
231 $post = $this->getDatabase()->exec_SELECTgetSingleRow('title,sorting', 'tx_blogexample_domain_model_post', 'blog ='.$this->blog->getUid(), '', 'sorting DESC');
232 $this->assertSame('Post9', $post['title']);
233 $this->assertSame('10', $post['sorting']);
234
235 $post = $this->getDatabase()->exec_SELECTgetSingleRow('title,uid', 'tx_blogexample_domain_model_post', 'blog ='.$this->blog->getUid().' AND sorting=6');
236 $this->assertSame('MOVED POST Post10', $post['title']);
237 $this->assertSame('10', $post['uid']);
238 }
239
240 /**
241 * Tests adding object at the end of sorted M:M relation (Post:Tag)
242 *
243 * @test
244 */
245 public function attachTagToPostAtTheEnd() {
246 $count = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_tag');
247 $this->assertSame(10, $count);
248
249 $newTagTitle = 'sdufhisdhuf';
250 $newTag = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Model\\Tag', $newTagTitle);
251
252 $postRepository = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Repository\\PostRepository');
253 $post = $postRepository->findByUid(1);
254 $post->addTag($newTag);
255
256 $postRepository->update($post);
257 $this->persistentManager->persistAll();
258
259 $count = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_tag');
260 $this->assertSame(11, $count);
261
262 $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid(), '', 'sorting DESC');
263 $this->assertSame('11', $tag['uid_foreign']);
264 }
265
266
267 /**
268 * Tests removing object from the end of sorted M:M relation (Post:Tag)
269 *
270 * @test
271 */
272 public function removeLastTagFromPost() {
273 $count = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_tag');
274 $this->assertSame(10, $count);
275
276 $postRepository = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Repository\\PostRepository');
277 $post = $postRepository->findByUid(1);
278 $tags = $post->getTags();
279 $tagsArray = $tags->toArray();
280 $latestTag = array_pop($tagsArray);
281
282 $this->assertEquals(10, $latestTag->getUid());
283
284 $post->removeTag($latestTag);
285
286 $postRepository->update($post);
287 $this->persistentManager->persistAll();
288
289 $countPosts = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_domain_model_tag', 'deleted=0' );
290 $this->assertEquals(10, $countPosts);
291
292 $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid(), '', 'sorting DESC');
293 $this->assertSame('9', $tag['uid_foreign']);
294
295 $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid().' AND uid_foreign='.$latestTag->getUid());
296 $this->assertSame(NULL, $tag['uid_foreign']);
297 }
298
299 /**
300 * Tests adding object in the middle of sorted M:M relation (Post:Tag)
301 *
302 * @test
303 */
304 public function addTagToPostInTheMiddle() {
305 $countTags = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
306 $this->assertSame(10, $countTags);
307
308 $postRepository = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Repository\\PostRepository');
309 $post = $postRepository->findByUid(1);
310 $tags = clone $post->getTags();
311 $post->setTags(new ObjectStorage());
312
313 $counter = 1;
314 foreach ($tags as $tag) {
315 $post->addTag($tag);
316 if ($counter == 5) {
317 $newTag = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Model\\Tag', 'INSERTED TAG at position 6 : ' . strftime(''));
318 $post->addTag($newTag);
319 }
320 $counter++;
321 }
322
323 $postRepository->update($post);
324 $this->persistentManager->persistAll();
325
326 $countTags = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
327 $this->assertSame(11, $countTags);
328
329 $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid(), '', 'sorting DESC');
330 $this->assertSame('10', $tag['uid_foreign']);
331
332 $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid().' AND sorting=6');
333 $this->assertSame('11', $tag['uid_foreign']);
334 }
335
336
337 /**
338 * Tests removing object from the middle of the sorted M:M relation (Post:Tag)
339 *
340 * @test
341 */
342 public function removeMiddleTagFromPost() {
343 $countTags = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
344 $this->assertSame(10, $countTags);
345
346 $postRepository = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Repository\\PostRepository');
347 $post = $postRepository->findByUid(1);
348 $tags = clone $post->getTags();
349 $counter = 1;
350 foreach ($tags as $tag) {
351 if ($counter == 5) {
352 $post->removeTag($tag);
353 }
354 $counter++;
355 }
356
357 $postRepository->update($post);
358 $this->persistentManager->persistAll();
359
360 $countTags = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
361 $this->assertSame(9, $countTags);
362
363 $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign,sorting', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid(), '', 'sorting DESC');
364 $this->assertSame('10', $tag['uid_foreign']);
365 $this->assertSame('10', $tag['sorting']);
366
367 $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid().' AND sorting=5');
368 $this->assertSame(NULL, $tag['uid_foreign']);
369 }
370
371 /**
372 * Tests moving object from the end to the middle of sorted M:M relation (Post:Tag)
373 *
374 * @test
375 */
376 public function moveTagFromEndToTheMiddle() {
377 $countTags = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
378 $this->assertSame(10, $countTags);
379
380 $postRepository = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Repository\\PostRepository');
381 $post = $postRepository->findByUid(1);
382 $tags = clone $post->getTags();
383 $tagsArray = $tags->toArray();
384 $latestTag = array_pop($tagsArray);
385 $post->removeTag($latestTag);
386 $post->setTags(new ObjectStorage());
387
388 $counter = 1;
389 $tagCount = $tags->count();
390 foreach ($tags as $tag) {
391 if ($counter != $tagCount) {
392 $post->addTag($tag);
393 }
394 if ($counter == 5) {
395 $post->addTag($latestTag);
396 }
397 $counter++;
398 }
399 $post->addTag($latestTag);
400
401 $postRepository->update($post);
402 $this->persistentManager->persistAll();
403
404 $countTags = $this->getDatabase()->exec_SELECTcountRows('*', 'tx_blogexample_post_tag_mm', 'uid_local=1');
405 $this->assertSame(10, $countTags);
406
407 $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign,sorting', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid(), '', 'sorting DESC');
408 $this->assertSame('9', $tag['uid_foreign']);
409 $this->assertSame('10', $tag['sorting']);
410
411 $sorting = '6';
412 $tag = $this->getDatabase()->exec_SELECTgetSingleRow('uid_foreign', 'tx_blogexample_post_tag_mm', 'uid_local ='.$post->getUid().' AND sorting='.$sorting);
413 $this->assertSame('10', $tag['uid_foreign']);
414 }
415
416 /**
417 * Test if timestamp field is updated when updating a record
418 *
419 * @test
420 */
421 public function timestampFieldIsUpdatedOnPostSave() {
422 $rawPost = $this->getDatabase()->exec_SELECTgetSingleRow('*', 'tx_blogexample_domain_model_post', 'uid=1');
423
424 $postRepository = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Repository\\PostRepository');
425 $post = $postRepository->findByUid(1);
426 $post->setTitle("newTitle");
427
428 $postRepository->update($post);
429 $this->persistentManager->persistAll();
430
431 $rawPost2 = $this->getDatabase()->exec_SELECTgetSingleRow('*', 'tx_blogexample_domain_model_post', 'uid=1');
432 $this->assertTrue($rawPost2['tstamp'] > $rawPost['tstamp']);
433 }
434
435 /**
436 * Helper method for persisting blog
437 */
438 protected function updateAndPersistBlog() {
439 /** @var \ExtbaseTeam\BlogExample\Domain\Repository\BlogRepository $blogRepository */
440 $blogRepository = $this->objectManager->get('ExtbaseTeam\\BlogExample\\Domain\\Repository\\BlogRepository');
441 $blogRepository->update($this->blog);
442 $this->persistentManager->persistAll();
443 }
444 }