[TASK] Enable DataHandler frontend rendering tests 11/27711/3
authorOliver Hader <oliver@typo3.org>
Wed, 19 Feb 2014 09:05:32 +0000 (10:05 +0100)
committerOliver Hader <oliver.hader@typo3.org>
Wed, 19 Feb 2014 14:15:50 +0000 (15:15 +0100)
After having performed changes to data structures using the
DataHandler, the correct impact for the frontend needs to be
asserted. This patch checks the correct behavior for DataHandler
action tests for regular, MM and IRRE disposal.

Resolves: #56104
Releases: 6.2
Change-Id: I99f11f6b039c31e08614caf8ee9bca9d47700b93
Reviewed-on: https://review.typo3.org/27711
Reviewed-by: Oliver Hader
Tested-by: Oliver Hader
13 files changed:
typo3/sysext/core/Tests/Functional/DataHandling/AbstractDataHandlerActionTestCase.php
typo3/sysext/core/Tests/Functional/DataHandling/InlineRelationalRecordEditing/ForeignField/AbstractActionTestCase.php
typo3/sysext/core/Tests/Functional/DataHandling/ManyToMany/AbstractActionTestCase.php
typo3/sysext/core/Tests/Functional/DataHandling/Regular/AbstractActionTestCase.php
typo3/sysext/core/Tests/Functional/Fixtures/Frontend/AdditionalConfiguration.php [new file with mode: 0644]
typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.ts [new file with mode: 0644]
typo3/sysext/core/Tests/Functional/Framework/Frontend/UserFunction.php [new file with mode: 0644]
typo3/sysext/workspaces/Tests/Functional/DataHandling/InlineRelationalRecordEditing/ForeignField/AbstractActionTestCase.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/InlineRelationalRecordEditing/ForeignField/WorkspaceActionTest.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/ManyToMany/AbstractActionTestCase.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/ManyToMany/WorkspaceActionTest.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/Regular/AbstractActionTestCase.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/Regular/WorkspaceActionTest.php

index 3ff6907..f50ca22 100644 (file)
@@ -53,6 +53,7 @@ abstract class AbstractDataHandlerActionTestCase extends \TYPO3\CMS\Core\Tests\F
         * @var array
         */
        protected $pathsToLinkInTestInstance = array(
+               'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/AdditionalConfiguration.php' => 'typo3conf/AdditionalConfiguration.php',
                'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/extTables.php' => 'typo3conf/extTables.php',
        );
 
index 50ce71d..373ebb2 100644 (file)
@@ -52,6 +52,8 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                parent::setUp();
                $this->importScenarioDataSet('LiveDefaultPages');
                $this->importScenarioDataSet('LiveDefaultElements');
+
+               $this->setUpFrontendRootPage(1, array('typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.ts'));
        }
 
        /**
@@ -64,6 +66,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function createParentContentRecord() {
                $this->actionService->createNewRecord(self::TABLE_Content, self::VALUE_PageId, array('header' => 'Testing #1'));
                $this->assertAssertionDataSet('createParentContentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
        }
 
        /**
@@ -72,6 +77,13 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function modifyParentContentRecord() {
                $this->actionService->modifyRecord(self::TABLE_Content, self::VALUE_ContentIdLast, array('header' => 'Testing #1'));
                $this->assertAssertionDataSet('modifyParentContentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1')
+               );
        }
 
        /**
@@ -80,14 +92,24 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function deleteParentContentRecord() {
                $this->actionService->deleteRecord(self::TABLE_Content, self::VALUE_ContentIdLast);
                $this->assertAssertionDataSet('deleteParentContentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentDoesNotHaveRecords($responseContent, self::TABLE_Content, 'header', 'Regular Element #2');
        }
 
        /**
         * @test
         */
        public function copyParentContentRecord() {
-               $this->actionService->copyRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageId);
+               $newTableIds = $this->actionService->copyRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageId);
                $this->assertAssertionDataSet('copyParentContentRecord');
+
+               $newContentId = $newTableIds[self::TABLE_Content][self::VALUE_ContentIdLast];
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . $newContentId, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1')
+               );
        }
 
        /**
@@ -96,6 +118,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function localizeParentContentRecord() {
                $this->actionService->localizeRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_LanguageId);
                $this->assertAssertionDataSet('localizeParentContentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('[Translate to Dansk:] Hotel #1')
+               );
        }
 
        /**
@@ -104,6 +132,16 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function changeParentContentRecordSorting() {
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdFirst, -self::VALUE_ContentIdLast);
                $this->assertAssertionDataSet('changeParentContentRecordSorting');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1', 'Hotel #2')
+               );
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1')
+               );
        }
 
        /**
@@ -112,6 +150,13 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function moveParentContentRecordToDifferentPage() {
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageIdTarget);
                $this->assertAssertionDataSet('moveParentContentRecordToDifferentPage');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageIdTarget)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Regular Element #2');
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1')
+               );
        }
 
        /**
@@ -121,6 +166,17 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageIdTarget);
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdFirst, -self::VALUE_ContentIdLast);
                $this->assertAssertionDataSet('moveParentContentRecordToDifferentPageAndChangeSorting');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageIdTarget)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', array('Regular Element #2', 'Regular Element #1'));
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1', 'Hotel #2')
+               );
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1')
+               );
        }
 
        /**
@@ -133,6 +189,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function modifyPageRecord() {
                $this->actionService->modifyRecord(self::TABLE_Page, self::VALUE_PageId, array('title' => 'Testing #1'));
                $this->assertAssertionDataSet('modifyPageRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Page, 'title', 'Testing #1');
        }
 
        /**
@@ -141,14 +200,21 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function deletePageRecord() {
                $this->actionService->deleteRecord(self::TABLE_Page, self::VALUE_PageId);
                $this->assertAssertionDataSet('deletePageRecord');
+
+               $response = $this->getFrontendResponse(self::VALUE_PageId, 0, 0, 0, FALSE);
+               $this->assertContains('PageNotFoundException', $response->getError());
        }
 
        /**
         * @test
         */
        public function copyPageRecord() {
-               $this->actionService->copyRecord(self::TABLE_Page, self::VALUE_PageId, self::VALUE_PageIdTarget);
+               $newTableIds = $this->actionService->copyRecord(self::TABLE_Page, self::VALUE_PageId, self::VALUE_PageIdTarget);
                $this->assertAssertionDataSet('copyPageRecord');
+
+               $newPageId = $newTableIds[self::TABLE_Page][self::VALUE_PageId];
+               $responseContent = $this->getFrontendResponse($newPageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Hotel, 'title', array('Hotel #1', 'Hotel #2', 'Hotel #1'));
        }
 
        /**
@@ -159,7 +225,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
         * @test
         */
        public function createParentContentRecordWithHotelAndOfferChildRecords() {
-               $this->actionService->createNewRecords(
+               $newTableIds = $this->actionService->createNewRecords(
                        self::VALUE_PageId,
                        array(
                                self::TABLE_Offer => array('title' => 'Offer #1'),
@@ -168,6 +234,14 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        )
                );
                $this->assertAssertionDataSet('createParentContentRecordWithHotelAndOfferChildRecords');
+
+               $newContentId = $newTableIds[self::TABLE_Content][0];
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . $newContentId, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', 'Hotel #1'
+               );
        }
 
        /**
@@ -186,6 +260,22 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                $newHotelId = $newTableIds[self::TABLE_Hotel][0];
                $copiedTableIds = $this->actionService->copyRecord(self::TABLE_Content, $newContentId, self::VALUE_PageId);
                $this->assertAssertionDataSet('createAndCopyParentContentRecordWithHotelAndOfferChildRecords');
+
+               $copiedContentId = $copiedTableIds[self::TABLE_Content][$newContentId];
+               $copiedHotelId = $copiedTableIds[self::TABLE_Hotel][$newHotelId];
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . $newContentId, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', 'Hotel #1'
+               );
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . $copiedContentId, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', 'Hotel #1'
+               );
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Hotel . ':' . $copiedHotelId, 'offers',
+                       self::TABLE_Offer, 'title', 'Offer #1'
+               );
        }
 
        /**
@@ -205,6 +295,22 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                $newHotelId = $newTableIds[self::TABLE_Hotel][0];
                $localizedTableIds = $this->actionService->localizeRecord(self::TABLE_Content, $newContentId, self::VALUE_LanguageId);
                $this->assertAssertionDataSet('createAndLocalizeParentContentRecordWithHotelAndOfferChildRecords');
+
+               $localizedContentId = $localizedTableIds[self::TABLE_Content][$newContentId];
+               $localizedHotelId = $localizedTableIds[self::TABLE_Hotel][$newHotelId];
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId)->getResponseContent();
+
+               // @todo Does not work since children don't point to live-default record
+               /*
+                       $this->assertResponseContentStructureHasRecords(
+                               $responseContent, self::TABLE_Content . ':' . $localizedContentId, 'tx_irretutorial_hotels',
+                               self::TABLE_Hotel, 'title', '[Translate to Dansk:] Hotel #1'
+                       );
+                       $this->assertResponseContentStructureHasRecords(
+                               $responseContent, self::TABLE_Hotel . ':' . $localizedHotelId, 'offers',
+                               self::TABLE_Offer, 'title', '[Translate to Dansk:] Offer #1'
+                       );
+               */
        }
 
        /**
@@ -213,6 +319,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function modifyOnlyHotelChildRecord() {
                $this->actionService->modifyRecord(self::TABLE_Hotel, 4, array('title' => 'Testing #1'));
                $this->assertAssertionDataSet('modifyOnlyHotelChildRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1', 'Testing #1')
+               );
        }
 
        /**
@@ -221,6 +333,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function modifyParentRecordAndChangeHotelChildRecordsSorting() {
                $this->actionService->modifyRecord(self::TABLE_Content, self::VALUE_ContentIdFirst, array('tx_irretutorial_hotels' => '4,3'));
                $this->assertAssertionDataSet('modifyParentRecordAndChangeHotelChildRecordsSorting');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #2', 'Hotel #1')
+               );
        }
 
        /**
@@ -235,6 +353,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        )
                );
                $this->assertAssertionDataSet('modifyParentRecordWithHotelChildRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1', 'Testing #1')
+               );
        }
 
        /**
@@ -249,6 +373,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        )
                );
                $this->assertAssertionDataSet('modifyParentRecordAndAddHotelChildRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1', 'Hotel #2')
+               );
        }
 
        /**
@@ -262,6 +392,16 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        array(self::TABLE_Hotel => array(4))
                );
                $this->assertAssertionDataSet('modifyParentRecordAndDeleteHotelChildRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', 'Hotel #1'
+               );
+               $this->assertResponseContentStructureDoesNotHaveRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', 'Hotel #2'
+               );
        }
 
 }
index 3295410..fdea301 100644 (file)
@@ -52,6 +52,8 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                parent::setUp();
                $this->importScenarioDataSet('LiveDefaultPages');
                $this->importScenarioDataSet('LiveDefaultElements');
+
+               $this->setUpFrontendRootPage(1, array('typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.ts'));
        }
 
        /**
@@ -66,6 +68,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        self::TABLE_Content, self::VALUE_ContentIdFirst, 'categories', array(self::VALUE_CategoryIdFirst, self::VALUE_CategoryIdSecond, 31)
                );
                $this->assertAssertionDataSet('addCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', array('Category A', 'Category B', 'Category A.A')
+               );
        }
 
        /**
@@ -76,6 +84,16 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        self::TABLE_Content, self::VALUE_ContentIdFirst, 'categories', array(self::VALUE_CategoryIdFirst)
                );
                $this->assertAssertionDataSet('deleteCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', array('Category A')
+               );
+               $this->assertResponseContentStructureDoesNotHaveRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', array('Category B', 'Category C', 'Category A.A')
+               );
        }
 
        /**
@@ -86,6 +104,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        self::TABLE_Content, self::VALUE_ContentIdFirst, 'categories', array(self::VALUE_CategoryIdSecond, self::VALUE_CategoryIdFirst)
                );
                $this->assertAssertionDataSet('changeCategoryRelationSorting');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', array('Category A', 'Category B')
+               );
        }
 
        /**
@@ -94,6 +118,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function modifyCategoryRecordOfCategoryRelation() {
                $this->actionService->modifyRecord(self::TABLE_Category, self::VALUE_CategoryIdFirst, array('title' => 'Testing #1'));
                $this->assertAssertionDataSet('modifyCategoryRecordOfCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', array('Testing #1', 'Category B')
+               );
        }
 
        /**
@@ -102,6 +132,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function modifyContentRecordOfCategoryRelation() {
                $this->actionService->modifyRecord(self::TABLE_Content, self::VALUE_ContentIdFirst, array('header' => 'Testing #1'));
                $this->assertAssertionDataSet('modifyContentRecordOfCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
        }
 
        /**
@@ -111,6 +144,13 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                $this->actionService->modifyRecord(self::TABLE_Category, self::VALUE_CategoryIdFirst, array('title' => 'Testing #1'));
                $this->actionService->modifyRecord(self::TABLE_Content, self::VALUE_ContentIdFirst, array('header' => 'Testing #1'));
                $this->assertAssertionDataSet('modifyBothRecordsOfCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', array('Testing #1', 'Category B')
+               );
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
        }
 
        /**
@@ -119,6 +159,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function deleteContentRecordOfCategoryRelation() {
                $this->actionService->deleteRecord(self::TABLE_Content, self::VALUE_ContentIdLast);
                $this->assertAssertionDataSet('deleteContentRecordOfCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentDoesNotHaveRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
        }
 
        /**
@@ -127,14 +170,27 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function deleteCategoryRecordOfCategoryRelation() {
                $this->actionService->deleteRecord(self::TABLE_Category, self::VALUE_CategoryIdFirst);
                $this->assertAssertionDataSet('deleteCategoryRecordOfCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentStructureDoesNotHaveRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', array('Category A')
+               );
        }
 
        /**
         * @test
         */
        public function copyContentRecordOfCategoryRelation() {
-               $this->actionService->copyRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageId);
+               $newTableIds = $this->actionService->copyRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageId);
                $this->assertAssertionDataSet('copyContentRecordOfCategoryRelation');
+
+               $newContentId = $newTableIds[self::TABLE_Content][self::VALUE_ContentIdLast];
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . $newContentId, 'categories',
+                       self::TABLE_Category, 'title', array('Category B', 'Category C')
+               );
        }
 
        /**
@@ -143,6 +199,14 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function copyCategoryRecordOfCategoryRelation() {
                $this->actionService->copyRecord(self::TABLE_Category, self::VALUE_CategoryIdFirst, 0);
                $this->assertAssertionDataSet('copyCategoryRecordOfCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', 'Category A'
+                       // @todo Actually it should be twice "Category A" since the category got copied
+                       // self::TABLE_Category, 'title', array('Category A', 'Category A')
+               );
        }
 
        /**
@@ -151,6 +215,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function localizeContentRecordOfCategoryRelation() {
                $this->actionService->localizeRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_LanguageId);
                $this->assertAssertionDataSet('localizeContentRecordOfCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'categories',
+                       self::TABLE_Category, 'title', array('Category B', 'Category C')
+               );
        }
 
        /**
@@ -159,6 +229,14 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function localizeCategoryRecordOfCategoryRelation() {
                $this->actionService->localizeRecord(self::TABLE_Category, self::VALUE_CategoryIdFirst, self::VALUE_LanguageId);
                $this->assertAssertionDataSet('localizeCategoryRecordOfCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', array('Category A', 'Category B')
+                       // @todo Actually it should contain the localized category
+                       // self::TABLE_Category, 'title', array('[Translate to Dansk:] Category A', 'Category B')
+               );
        }
 
        /**
@@ -167,6 +245,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function moveContentRecordOfCategoryRelationToDifferentPage() {
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageIdTarget);
                $this->assertAssertionDataSet('moveContentRecordOfCategoryRelationToDifferentPage');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageIdTarget)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'categories',
+                       self::TABLE_Category, 'title', array('Category B', 'Category C')
+               );
        }
 
 }
index 0ae5e79..d839577 100644 (file)
@@ -50,6 +50,8 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                parent::setUp();
                $this->importScenarioDataSet('LiveDefaultPages');
                $this->importScenarioDataSet('LiveDefaultElements');
+
+               $this->setUpFrontendRootPage(1, array('typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.ts'));
        }
 
        /**
@@ -65,6 +67,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                // Creating record at the end of the page (after last one)
                $this->actionService->createNewRecord(self::TABLE_Content, -self::VALUE_ContentIdLast, array('header' => 'Testing #2'));
                $this->assertAssertionDataSet('createContentRecords');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', array('Testing #1', 'Testing #2'));
        }
 
        /**
@@ -73,6 +78,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function modifyContentRecord() {
                $this->actionService->modifyRecord(self::TABLE_Content, self::VALUE_ContentIdLast, array('header' => 'Testing #1'));
                $this->assertAssertionDataSet('modifyContentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
        }
 
        /**
@@ -81,6 +89,10 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function deleteContentRecord() {
                $this->actionService->deleteRecord(self::TABLE_Content, self::VALUE_ContentIdLast);
                $this->assertAssertionDataSet('deleteContentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Regular Element #1');
+               $this->assertResponseContentDoesNotHaveRecords($responseContent, self::TABLE_Content, 'header', 'Regular Element #2');
        }
 
        /**
@@ -89,6 +101,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function copyContentRecord() {
                $this->actionService->copyRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageId);
                $this->assertAssertionDataSet('copyContentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Regular Element #2 (copy 1)');
        }
 
        /**
@@ -97,6 +112,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function localizeContentRecord() {
                $this->actionService->localizeRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_LanguageId);
                $this->assertAssertionDataSet('localizeContentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', array('Regular Element #1', '[Translate to Dansk:] Regular Element #2'));
        }
 
        /**
@@ -105,6 +123,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function changeContentRecordSorting() {
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdFirst, -self::VALUE_ContentIdLast);
                $this->assertAssertionDataSet('changeContentRecordSorting');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', array('Regular Element #1', 'Regular Element #2'));
        }
 
        /**
@@ -113,6 +134,11 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function moveContentRecordToDifferentPage() {
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageIdTarget);
                $this->assertAssertionDataSet('moveContentRecordToDifferentPage');
+
+               $responseContentSource = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContentSource, self::TABLE_Content, 'header', 'Regular Element #1');
+               $responseContentTarget = $this->getFrontendResponse(self::VALUE_PageIdTarget)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContentTarget, self::TABLE_Content, 'header', 'Regular Element #2');
        }
 
        /**
@@ -122,6 +148,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageIdTarget);
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdFirst, -self::VALUE_ContentIdLast);
                $this->assertAssertionDataSet('moveContentRecordToDifferentPageAndChangeSorting');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageIdTarget)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', array('Regular Element #1', 'Regular Element #2'));
        }
 
        /**
@@ -132,8 +161,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
         * @test
         */
        public function createPageRecord() {
-               $this->actionService->createNewRecord(self::TABLE_Page, self::VALUE_PageId, array('title' => 'Testing #1'));
+               $newTableIds = $this->actionService->createNewRecord(self::TABLE_Page, self::VALUE_PageId, array('title' => 'Testing #1', 'hidden' => 0));
                $this->assertAssertionDataSet('createPageRecord');
+
+               $newPageId = $newTableIds[self::TABLE_Page][0];
+               $responseContent = $this->getFrontendResponse($newPageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Page, 'title', 'Testing #1');
        }
 
        /**
@@ -142,6 +175,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function modifyPageRecord() {
                $this->actionService->modifyRecord(self::TABLE_Page, self::VALUE_PageId, array('title' => 'Testing #1'));
                $this->assertAssertionDataSet('modifyPageRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Page, 'title', 'Testing #1');
        }
 
        /**
@@ -150,14 +186,21 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function deletePageRecord() {
                $this->actionService->deleteRecord(self::TABLE_Page, self::VALUE_PageId);
                $this->assertAssertionDataSet('deletePageRecord');
+
+               $response = $this->getFrontendResponse(self::VALUE_PageId, 0, 0, 0, FALSE);
+               $this->assertContains('PageNotFoundException', $response->getError());
        }
 
        /**
         * @test
         */
        public function copyPageRecord() {
-               $this->actionService->copyRecord(self::TABLE_Page, self::VALUE_PageId, self::VALUE_PageIdTarget);
+               $newTableIds = $this->actionService->copyRecord(self::TABLE_Page, self::VALUE_PageId, self::VALUE_PageIdTarget);
                $this->assertAssertionDataSet('copyPageRecord');
+
+               $newPageId = $newTableIds[self::TABLE_Page][self::VALUE_PageId];
+               $responseContent = $this->getFrontendResponse($newPageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Page, 'title', 'Relations');
        }
 
        /**
@@ -166,6 +209,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function localizePageRecord() {
                $this->actionService->localizeRecord(self::TABLE_Page, self::VALUE_PageId, self::VALUE_LanguageId);
                $this->assertAssertionDataSet('localizePageRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Page, 'title', '[Translate to Dansk:] Relations');
        }
 
        /**
@@ -174,6 +220,10 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function changePageRecordSorting() {
                $this->actionService->moveRecord(self::TABLE_Page, self::VALUE_PageId, -self::VALUE_PageIdTarget);
                $this->assertAssertionDataSet('changePageRecordSorting');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Page, 'title', 'Relations');
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', array('Regular Element #1', 'Regular Element #2'));
        }
 
        /**
@@ -182,6 +232,10 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function movePageRecordToDifferentPage() {
                $this->actionService->moveRecord(self::TABLE_Page, self::VALUE_PageId, self::VALUE_PageIdTarget);
                $this->assertAssertionDataSet('movePageRecordToDifferentPage');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Page, 'title', 'Relations');
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', array('Regular Element #1', 'Regular Element #2'));
        }
 
        /**
@@ -191,6 +245,10 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                $this->actionService->moveRecord(self::TABLE_Page, self::VALUE_PageIdTarget, self::VALUE_PageIdWebsite);
                $this->actionService->moveRecord(self::TABLE_Page, self::VALUE_PageId, -self::VALUE_PageIdTarget);
                $this->assertAssertionDataSet('movePageRecordToDifferentPageAndChangeSorting');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Page, 'title', 'Relations');
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', array('Regular Element #1', 'Regular Element #2'));
        }
 
 }
diff --git a/typo3/sysext/core/Tests/Functional/Fixtures/Frontend/AdditionalConfiguration.php b/typo3/sysext/core/Tests/Functional/Fixtures/Frontend/AdditionalConfiguration.php
new file mode 100644 (file)
index 0000000..d8319fb
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+if (!defined('TYPO3_MODE')) {
+       die('Access denied.');
+}
+// You may add PHP code here, wich is executed on every request after the configuration is loaded.
+// The code here should only manipulate TYPO3_CONF_VARS for example to set the database configuration
+// dependent to the requested environment.
+
+// $GLOBALS['TYPO3_CONF_VARS']['BE']['explicitConfirmationOfTranslation'] = TRUE;
+
+$GLOBALS['TYPO3_CONF_VARS']['FE']['debug'] = FALSE;
+
+// Register hooks for frontend test
+if (TYPO3_MODE === 'FE') {
+       $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['postBeUser']['FunctionalTest'] =
+               'TYPO3\\CMS\\Core\\Tests\\Functional\\Framework\\Frontend\\Hook\\BackendUserHandler->initialize';
+       $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_db.php']['queryProcessors']['FunctionalTest'] =
+               'TYPO3\\CMS\\Core\\Tests\\Functional\\Framework\\Frontend\\Hook\\DatabaseConnectionWatcher';
+       $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['cObjTypeAndClass']['FunctionalTest'] =
+               array('CONTENT', 'TYPO3\\CMS\\Core\\Tests\\Functional\\Framework\\Frontend\\Hook\\ContentObjectRendererWatcher');
+       $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['postInit']['FunctionalTest'] =
+               'TYPO3\\CMS\\Core\\Tests\\Functional\\Framework\\Frontend\\Hook\\ContentObjectRendererWatcher';
+       $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['isOutputting']['FunctionalTest'] =
+               'TYPO3\\CMS\\Core\\Tests\\Functional\\Framework\\Frontend\\Hook\\ContentObjectRendererWatcher->show';
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.ts b/typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.ts
new file mode 100644 (file)
index 0000000..64520ba
--- /dev/null
@@ -0,0 +1,106 @@
+config {
+       no_cache = 1
+       debug = 0
+       xhtml_cleaning = 0
+       admPanel = 0
+       disableAllHeaderCode = 1
+       sendCacheHeaders = 0
+       sys_language_uid = 0
+       sys_language_mode = ignore
+       sys_language_overlay = 1
+#      additionalHeaders = Content-Type: application/json; charset=utf-8
+}
+
+watcher {
+       tableFields {
+               pages = uid,_ORIG_uid,pid,sorting,title
+               sys_category = uid,_ORIG_uid,_LOCALIZED_UID,pid,sys_language_uid,title,parent,items,sys_language_uid
+               tt_content = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,header,categories,tx_irretutorial_hotels
+               tx_irretutorial_1nff_hotel = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title,offers
+               tx_irretutorial_1nff_offer = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title,prices
+               tx_irretutorial_1nff_price = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title,price
+       }
+}
+
+page = PAGE
+page {
+       10 = CONTENT
+       10 {
+               watcher.parentRecordField = __contents
+               table = tt_content
+               select {
+                       orderBy = sorting
+                       where = colPos=0
+                       languageField = sys_language_uid
+               }
+               renderObj = COA
+               renderObj {
+                       10 = CONTENT
+                       10 {
+                               if.isTrue.field = categories
+                               watcher.parentRecordField = categories
+                               table = sys_category
+                               select {
+                                       pidInList = 0
+                                       uidInList.preUserFunc = TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\UserFunction->getManyToManyIds
+                                       uidInList.preUserFunc {
+                                               uidForeign.data = field:_ORIG_uid // field:uid
+                                               manyToManyTableName = sys_category_record_mm
+                                               matchTableName = tt_content
+                                               matchFieldName = categories
+                                       }
+                                       selectFields = sys_category.*
+                                       join = sys_category_record_mm ON sys_category_record_mm.uid_local = sys_category.uid
+                                       where.data = field:_ORIG_uid // field:uid
+                                       where.intval = 1
+                                       where.wrap = sys_category_record_mm.uid_foreign=|
+                                       orderBy = sys_category_record_mm.sorting_foreign
+                                       languageField = sys_category.sys_language_uid
+                               }
+                       }
+                       20 = CONTENT
+                       20 {
+                               if.isTrue.field = tx_irretutorial_hotels
+                               watcher.parentRecordField = tx_irretutorial_hotels
+                               table = tx_irretutorial_1nff_hotel
+                               select {
+                                       orderBy = sorting
+                                       where.field = uid
+                                       where.intval = 1
+                                       where.wrap = parenttable="tt_content" AND parentid=|
+                                       languageField = sys_language_uid
+                               }
+                               renderObj = CONTENT
+                               renderObj {
+                                       if.isTrue.field = offers
+                                       watcher.parentRecordField = offers
+                                       table = tx_irretutorial_1nff_offer
+                                       select {
+                                               orderBy = sorting
+                                               where.field = uid
+                                               where.intval = 1
+                                               where.wrap = parenttable="tx_irretutorial_1nff_hotel" AND parentid=|
+                                               languageField = sys_language_uid
+                                       }
+                                       renderObj = CONTENT
+                                       renderObj {
+                                               if.isTrue.field = prices
+                                               watcher.parentRecordField = prices
+                                               table = tx_irretutorial_1nff_price
+                                               select {
+                                                       orderBy = sorting
+                                                       where.field = uid
+                                                       where.intval = 1
+                                                       where.wrap = parenttable="tx_irretutorial_1nff_offer" AND parentid=|
+                                                       languageField = sys_language_uid
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+[globalVar = GP:L = 1]
+config.sys_language_uid = 1
+[end]
\ No newline at end of file
diff --git a/typo3/sysext/core/Tests/Functional/Framework/Frontend/UserFunction.php b/typo3/sysext/core/Tests/Functional/Framework/Frontend/UserFunction.php
new file mode 100644 (file)
index 0000000..fecb08c
--- /dev/null
@@ -0,0 +1,116 @@
+<?php
+namespace TYPO3\CMS\Core\Tests\Functional\Framework\Frontend;
+
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2014 Oliver Hader <oliver.hader@typo3.org>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Model of frontend response
+ */
+class UserFunction implements \TYPO3\CMS\Core\SingletonInterface {
+
+       /**
+        * @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
+        */
+       public $cObj;
+
+       /**
+        * @param string $content
+        * @param array $configuration
+        * @return string
+        */
+       public function getManyToManyIds($content, array $configuration = NULL) {
+               $where = array();
+               $uidLocal = NULL;
+               $uidForeign = NULL;
+               $manyToManyTableName = NULL;
+
+               $uidLocal = (int)$this->getValue('uidLocal', $configuration);
+               $uidForeign = (int)$this->getValue('uidForeign', $configuration);
+               $manyToManyTableName = $this->getValue('manyToManyTableName', $configuration);
+
+               if (!($uidLocal xor $uidForeign) || empty($manyToManyTableName)) {
+                       return $content;
+               }
+
+               if (!empty($uidLocal)) {
+                       $selectField = 'uid_foreign';
+                       $sortingField = 'sorting';
+                       $where[] = 'uid_local=' . $uidLocal;
+               } else {
+                       $selectField = 'uid_local';
+                       $sortingField = 'sorting_foreign';
+                       $where[] = 'uid_foreign=' . $uidForeign;
+               }
+
+               if (!empty($configuration['matchTableName'])) {
+                       $where[] = 'tablenames=' . $this->getDatabaseConnection()->fullQuoteStr($configuration['matchTableName'], $manyToManyTableName);
+               }
+               if (!empty($configuration['matchFieldName'])) {
+                       $where[] = 'fieldname=' . $this->getDatabaseConnection()->fullQuoteStr($configuration['matchFieldName'], $manyToManyTableName);
+               }
+
+               $references = $this->getDatabaseConnection()->exec_SELECTgetRows(
+                       $selectField,
+                       $manyToManyTableName,
+                       implode(' AND ', $where),
+                       '',
+                       $sortingField,
+                       '',
+                       $selectField
+               );
+
+               if (empty($references)) {
+                       return $content;
+               }
+
+               $content = implode(',', array_keys($references));
+               return $content;
+       }
+
+       /**
+        * @param string $property
+        * @param array $configuration
+        * @return string
+        */
+       protected function getValue($property, array $configuration = NULL) {
+               $value = '';
+
+               if (!empty($configuration[$property])) {
+                       $value = $configuration[$property];
+               }
+               if (!empty($configuration[$property . '.'])) {
+                       $value = $this->cObj->stdWrap($value, $configuration[$property . '.']);
+               }
+
+               return $value;
+       }
+
+       /**
+        * @return \TYPO3\CMS\Core\Database\DatabaseConnection
+        */
+       protected function getDatabaseConnection() {
+               return $GLOBALS['TYPO3_DB'];
+       }
+
+}
index e833f07..de810e3 100644 (file)
@@ -37,6 +37,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        const VALUE_ContentIdFirst = 297;
        const VALUE_ContentIdLast = 298;
        const VALUE_LanguageId = 1;
+       const VALUE_WorkspaceId = 1;
 
        const TABLE_Page = 'pages';
        const TABLE_Content = 'tt_content';
@@ -60,6 +61,8 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                parent::setUp();
                $this->importScenarioDataSet('LiveDefaultPages');
                $this->importScenarioDataSet('LiveDefaultElements');
+
+               $this->setUpFrontendRootPage(1, array('typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.ts'));
        }
 
        /**
@@ -72,6 +75,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function createParentContentRecord() {
                $this->actionService->createNewRecord(self::TABLE_Content, self::VALUE_PageId, array('header' => 'Testing #1'));
                $this->assertAssertionDataSet('createParentContentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
        }
 
        /**
@@ -80,6 +86,13 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function modifyParentContentRecord() {
                $this->actionService->modifyRecord(self::TABLE_Content, self::VALUE_ContentIdLast, array('header' => 'Testing #1'));
                $this->assertAssertionDataSet('modifyParentContentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1')
+               );
        }
 
        /**
@@ -88,6 +101,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function deleteParentContentRecord() {
                $this->actionService->deleteRecord(self::TABLE_Content, self::VALUE_ContentIdLast);
                $this->assertAssertionDataSet('deleteParentContentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentDoesNotHaveRecords($responseContent, self::TABLE_Content, 'header', 'Regular Element #2');
        }
 
        /**
@@ -98,14 +114,24 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                $versionedDeletedContentId = $newTableIds[self::TABLE_Content][self::VALUE_ContentIdLast];
                $this->actionService->clearWorkspaceRecord(self::TABLE_Content, $versionedDeletedContentId);
                $this->assertAssertionDataSet('deleteParentContentRecordAndDiscardDeletedParentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Regular Element #2');
        }
 
        /**
         * @test
         */
        public function copyParentContentRecord() {
-               $this->actionService->copyRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageId);
+               $newTableIds = $this->actionService->copyRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageId);
                $this->assertAssertionDataSet('copyParentContentRecord');
+
+               $newContentId = $newTableIds[self::TABLE_Content][self::VALUE_ContentIdLast];
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . $newContentId, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1')
+               );
        }
 
        /**
@@ -114,6 +140,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function localizeParentContentRecord() {
                $this->actionService->localizeRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_LanguageId);
                $this->assertAssertionDataSet('localizeParentContentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('[Translate to Dansk:] Hotel #1')
+               );
        }
 
        /**
@@ -122,6 +154,16 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function changeParentContentRecordSorting() {
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdFirst, -self::VALUE_ContentIdLast);
                $this->assertAssertionDataSet('changeParentContentRecordSorting');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1', 'Hotel #2')
+               );
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1')
+               );
        }
 
        /**
@@ -130,6 +172,17 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function moveParentContentRecordToDifferentPage() {
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageIdTarget);
                $this->assertAssertionDataSet('moveParentContentRecordToDifferentPage');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageIdTarget, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Regular Element #2');
+
+               // @todo Workspace child records gets lost due to core bug
+               /*
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1')
+               );
+               */
        }
 
        /**
@@ -140,6 +193,17 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageIdTarget);
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdFirst, -self::VALUE_ContentIdLast);
                $this->assertAssertionDataSet('moveParentContentRecordToDifferentPageAndChangeSorting');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageIdTarget, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', array('Regular Element #2', 'Regular Element #1'));
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1', 'Hotel #2')
+               );
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1')
+               );
        }
 
        /**
@@ -152,6 +216,13 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function modifyPageRecord() {
                $this->actionService->modifyRecord(self::TABLE_Page, self::VALUE_PageId, array('title' => 'Testing #1'));
                $this->assertAssertionDataSet('modifyPageRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Page, 'title', 'Testing #1');
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1', 'Hotel #2')
+               );
        }
 
        /**
@@ -160,14 +231,21 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function deletePageRecord() {
                $this->actionService->deleteRecord(self::TABLE_Page, self::VALUE_PageId);
                $this->assertAssertionDataSet('deletePageRecord');
+
+               $response = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId, FALSE);
+               $this->assertContains('RuntimeException', $response->getError());
        }
 
        /**
         * @test
         */
        public function copyPageRecord() {
-               $this->actionService->copyRecord(self::TABLE_Page, self::VALUE_PageId, self::VALUE_PageIdTarget);
+               $newTableIds = $this->actionService->copyRecord(self::TABLE_Page, self::VALUE_PageId, self::VALUE_PageIdTarget);
                $this->assertAssertionDataSet('copyPageRecord');
+
+               $newPageId = $newTableIds[self::TABLE_Page][self::VALUE_PageId];
+               $responseContent = $this->getFrontendResponse($newPageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Hotel, 'title', array('Hotel #1', 'Hotel #2', 'Hotel #1'));
        }
 
        /**
@@ -178,7 +256,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
         * @test
         */
        public function createParentContentRecordWithHotelAndOfferChildRecords() {
-               $this->actionService->createNewRecords(
+               $newTableIds = $this->actionService->createNewRecords(
                        self::VALUE_PageId,
                        array(
                                self::TABLE_Offer => array('title' => 'Offer #1'),
@@ -187,6 +265,18 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        )
                );
                $this->assertAssertionDataSet('createParentContentRecordWithHotelAndOfferChildRecords');
+
+               $newContentId = $newTableIds[self::TABLE_Content][0];
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
+
+               // @todo Shadow fields are not correct on the new placeholder
+               /*
+                       $this->assertResponseContentStructureHasRecords(
+                               $responseContent, self::TABLE_Content . ':' . $newContentId, 'tx_irretutorial_hotels',
+                               self::TABLE_Hotel, 'title', 'Hotel #1'
+                       );
+               */
        }
 
        /**
@@ -202,9 +292,31 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                                self::TABLE_Content => array('header' => 'Testing #1', 'tx_irretutorial_hotels' => '__previousUid'),
                        )
                );
-               $newContentId = $newTableIds['tt_content'][0];
-               $this->actionService->copyRecord(self::TABLE_Content, $newContentId, self::VALUE_PageId);
+               $newContentId = $newTableIds[self::TABLE_Content][0];
+               $newHotelId = $newTableIds[self::TABLE_Hotel][0];
+               $copiedTableIds = $this->actionService->copyRecord(self::TABLE_Content, $newContentId, self::VALUE_PageId);
                $this->assertAssertionDataSet('createAndCopyParentContentRecordWithHotelAndOfferChildRecords');
+
+               $copiedContentId = $copiedTableIds[self::TABLE_Content][$newContentId];
+               $copiedHotelId = $copiedTableIds[self::TABLE_Hotel][$newHotelId];
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1 (copy 1)');
+
+               // @todo Shadow fields are not correct on the new placeholder
+               /*
+                       $this->assertResponseContentStructureHasRecords(
+                               $responseContent, self::TABLE_Content . ':' . $newContentId, 'tx_irretutorial_hotels',
+                               self::TABLE_Hotel, 'title', 'Hotel #1'
+                       );
+                       $this->assertResponseContentStructureHasRecords(
+                               $responseContent, self::TABLE_Content . ':' . $copiedContentId, 'tx_irretutorial_hotels',
+                               self::TABLE_Hotel, 'title', 'Hotel #1'
+                       );
+                       $this->assertResponseContentStructureHasRecords(
+                               $responseContent, self::TABLE_Hotel . ':' . $copiedHotelId, 'offers',
+                               self::TABLE_Offer, 'title', 'Offer #1'
+                       );
+                */
        }
 
        /**
@@ -226,6 +338,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                $versionedCopiedContentId = $this->actionService->getDataHander()->getAutoVersionId(self::TABLE_Content, $copiedContentId);
                $this->actionService->clearWorkspaceRecord(self::TABLE_Content, $versionedCopiedContentId);
                $this->assertAssertionDataSet('createAndCopyParentContentRecordWithHotelAndOfferChildRecordsAndDiscardCopiedParentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentDoesNotHaveRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1 (copy 1)');
        }
 
        /**
@@ -245,6 +360,23 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                $newHotelId = $newTableIds[self::TABLE_Hotel][0];
                $localizedTableIds = $this->actionService->localizeRecord(self::TABLE_Content, $newContentId, self::VALUE_LanguageId);
                $this->assertAssertionDataSet('createAndLocalizeParentContentRecordWithHotelAndOfferChildRecords');
+
+               $localizedContentId = $localizedTableIds[self::TABLE_Content][$newContentId];
+               $localizedHotelId = $localizedTableIds[self::TABLE_Hotel][$newHotelId];
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', '[Translate to Dansk:] Testing #1');
+
+               // @todo Does not work since children don't point to live-default record
+               /*
+                       $this->assertResponseContentStructureHasRecords(
+                               $responseContent, self::TABLE_Content . ':' . $localizedContentId, 'tx_irretutorial_hotels',
+                               self::TABLE_Hotel, 'title', '[Translate to Dansk:] Hotel #1'
+                       );
+                       $this->assertResponseContentStructureHasRecords(
+                               $responseContent, self::TABLE_Hotel . ':' . $localizedHotelId, 'offers',
+                               self::TABLE_Offer, 'title', '[Translate to Dansk:] Offer #1'
+                       );
+               */
        }
 
        /**
@@ -266,6 +398,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                $versionedLocalizedContentId = $this->actionService->getDataHander()->getAutoVersionId(self::TABLE_Content, $localizedContentId);
                $this->actionService->clearWorkspaceRecord(self::TABLE_Content, $versionedLocalizedContentId);
                $this->assertAssertionDataSet('createAndLocalizeParentContentRecordWithHotelAndOfferChildRecordsAndDiscardLocalizedParentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentDoesNotHaveRecords($responseContent, self::TABLE_Content, 'header', '[Translate to Dansk:] Testing #1');
        }
 
        /**
@@ -274,6 +409,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function modifyOnlyHotelChildRecord() {
                $this->actionService->modifyRecord(self::TABLE_Hotel, 4, array('title' => 'Testing #1'));
                $this->assertAssertionDataSet('modifyOnlyHotelChildRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1', 'Testing #1')
+               );
        }
 
        /**
@@ -282,6 +423,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function modifyParentRecordAndChangeHotelChildRecordsSorting() {
                $this->actionService->modifyRecord(self::TABLE_Content, self::VALUE_ContentIdFirst, array('tx_irretutorial_hotels' => '4,3'));
                $this->assertAssertionDataSet('modifyParentRecordAndChangeHotelChildRecordsSorting');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #2', 'Hotel #1')
+               );
        }
 
        /**
@@ -296,6 +443,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        )
                );
                $this->assertAssertionDataSet('modifyParentRecordWithHotelChildRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1', 'Testing #1')
+               );
        }
 
        /**
@@ -312,6 +465,21 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                $modifiedContentId = $this->actionService->getDataHander()->getAutoVersionId(self::TABLE_Content, self::VALUE_ContentIdFirst);
                $this->actionService->clearWorkspaceRecord(self::TABLE_Content, $modifiedContentId);
                $this->assertAssertionDataSet('modifyParentRecordWithHotelChildRecordAndDiscardModifiedParentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Regular Element #1');
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1', 'Testing #1')
+                       // @todo Discarding the parent record should discard the child records as well
+                       // self::TABLE_Hotel, 'title', array('Hotel #1', 'Hotel #2')
+               );
+               /*
+                       $this->assertResponseContentStructureDoesNotHaveRecords(
+                               $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'tx_irretutorial_hotels',
+                               self::TABLE_Hotel, 'title', 'Testing #1'
+                       );
+               */
        }
 
        /**
@@ -334,6 +502,13 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                                )
                );
                $this->assertAssertionDataSet('modifyParentRecordWithHotelChildRecordAndDiscardAllModifiedRecords');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Regular Element #1');
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', array('Hotel #1', 'Hotel #2')
+               );
        }
 
        /**
@@ -348,6 +523,16 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        )
                );
                $this->assertAssertionDataSet('modifyParentRecordAndAddHotelChildRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+
+               // @todo Child record cannot be selected since they do not point to the live record
+               /*
+                       $this->assertResponseContentStructureHasRecords(
+                               $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'tx_irretutorial_hotels',
+                               self::TABLE_Hotel, 'title', array('Hotel #1', 'Hotel #2')
+                       );
+               */
        }
 
        /**
@@ -361,6 +546,16 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        array(self::TABLE_Hotel => array(4))
                );
                $this->assertAssertionDataSet('modifyParentRecordAndDeleteHotelChildRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', 'Hotel #1'
+               );
+               $this->assertResponseContentStructureDoesNotHaveRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'tx_irretutorial_hotels',
+                       self::TABLE_Hotel, 'title', 'Hotel #2'
+               );
        }
 
 }
index b34ca1d..814db68 100644 (file)
@@ -33,7 +33,7 @@ class WorkspaceActionTest extends AbstractActionTestCase {
 
        public function setUp() {
                parent::setUp();
-               $this->backendUser->workspace = 1;
+               $this->backendUser->workspace = self::VALUE_WorkspaceId;
        }
 
 }
index 13d0eea..d6fcc57 100644 (file)
@@ -38,6 +38,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        const VALUE_LanguageId = 1;
        const VALUE_CategoryIdFirst = 28;
        const VALUE_CategoryIdSecond = 29;
+       const VALUE_WorkspaceId = 1;
 
        const TABLE_Content = 'tt_content';
        const TABLE_Category = 'sys_category';
@@ -60,6 +61,8 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                parent::setUp();
                $this->importScenarioDataSet('LiveDefaultPages');
                $this->importScenarioDataSet('LiveDefaultElements');
+
+               $this->setUpFrontendRootPage(1, array('typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.ts'));
        }
 
        /**
@@ -74,6 +77,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        self::TABLE_Content, self::VALUE_ContentIdFirst, 'categories', array(self::VALUE_CategoryIdFirst, self::VALUE_CategoryIdSecond, 31)
                );
                $this->assertAssertionDataSet('addCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', array('Category A', 'Category B', 'Category A.A')
+               );
        }
 
        /**
@@ -84,6 +93,16 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        self::TABLE_Content, self::VALUE_ContentIdFirst, 'categories', array(self::VALUE_CategoryIdFirst)
                );
                $this->assertAssertionDataSet('deleteCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', array('Category A')
+               );
+               $this->assertResponseContentStructureDoesNotHaveRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', array('Category B', 'Category C', 'Category A.A')
+               );
        }
 
        /**
@@ -94,16 +113,30 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        self::TABLE_Content, self::VALUE_ContentIdFirst, 'categories', array(self::VALUE_CategoryIdSecond, self::VALUE_CategoryIdFirst)
                );
                $this->assertAssertionDataSet('changeCategoryRelationSorting');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', array('Category A', 'Category B')
+               );
        }
 
        /**
         * @test
         */
        public function createContentRecordAndAddCategoryRelation() {
-               $this->actionService->createNewRecord(
+               $newTableIds = $this->actionService->createNewRecord(
                        self::TABLE_Content, self::VALUE_PageId, array('header' => 'Testing #1', 'categories' => self::VALUE_CategoryIdSecond)
                );
                $this->assertAssertionDataSet('createContentRecordAndAddCategoryRelation');
+
+               $newContentId = $newTableIds[self::TABLE_Content][0];
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . $newContentId, 'categories',
+                       self::TABLE_Category, 'title', 'Category B'
+               );
        }
 
        /**
@@ -114,13 +147,23 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        self::TABLE_Category, 0, array('title' => 'Testing #1', 'items' => 'tt_content_' . self::VALUE_ContentIdFirst)
                );
                $this->assertAssertionDataSet('createCategoryRecordAndAddCategoryRelation');
+
+               // @todo Does not work due to the core bug of not setting the reference field in the MM record
+               /*
+                       $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+                       $this->assertResponseContentHasRecords($responseContent, self::TABLE_Category, 'title', 'Testing #1');
+                       $this->assertResponseContentStructureHasRecords(
+                               $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                               self::TABLE_Category, 'title', 'Testing #1'
+                       );
+               */
        }
 
        /**
         * @test
         */
        public function createContentRecordAndCreateCategoryRelation() {
-               $this->actionService->createNewRecords(
+               $newTableIds = $this->actionService->createNewRecords(
                        self::VALUE_PageId,
                        array(
                                self::TABLE_Category => array('title' => 'Testing #1'),
@@ -128,6 +171,18 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        )
                );
                $this->assertAssertionDataSet('createContentRecordAndCreateCategoryRelation');
+
+               $newContentId = $newTableIds[self::TABLE_Content][0];
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
+
+               // @todo New category is not resolved in new content element due to core bug
+               /*
+                       $this->assertResponseContentStructureHasRecords(
+                               $responseContent, self::TABLE_Content . ':' . $newContentId, 'categories',
+                               self::TABLE_Category, 'title', 'Testing #1'
+                       );
+               */
        }
 
        /**
@@ -151,6 +206,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function modifyCategoryRecordOfCategoryRelation() {
                $this->actionService->modifyRecord(self::TABLE_Category, self::VALUE_CategoryIdFirst, array('title' => 'Testing #1'));
                $this->assertAssertionDataSet('modifyCategoryRecordOfCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', array('Testing #1', 'Category B')
+               );
        }
 
        /**
@@ -159,6 +220,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function modifyContentRecordOfCategoryRelation() {
                $this->actionService->modifyRecord(self::TABLE_Content, self::VALUE_ContentIdFirst, array('header' => 'Testing #1'));
                $this->assertAssertionDataSet('modifyContentRecordOfCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
        }
 
        /**
@@ -168,6 +232,13 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                $this->actionService->modifyRecord(self::TABLE_Category, self::VALUE_CategoryIdFirst, array('title' => 'Testing #1'));
                $this->actionService->modifyRecord(self::TABLE_Content, self::VALUE_ContentIdFirst, array('header' => 'Testing #1'));
                $this->assertAssertionDataSet('modifyBothRecordsOfCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', array('Testing #1', 'Category B')
+               );
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
        }
 
        /**
@@ -176,6 +247,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function deleteContentRecordOfCategoryRelation() {
                $this->actionService->deleteRecord(self::TABLE_Content, self::VALUE_ContentIdLast);
                $this->assertAssertionDataSet('deleteContentRecordOfCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentDoesNotHaveRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
        }
 
        /**
@@ -184,14 +258,27 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function deleteCategoryRecordOfCategoryRelation() {
                $this->actionService->deleteRecord(self::TABLE_Category, self::VALUE_CategoryIdFirst);
                $this->assertAssertionDataSet('deleteCategoryRecordOfCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureDoesNotHaveRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', array('Category A')
+               );
        }
 
        /**
         * @test
         */
        public function copyContentRecordOfCategoryRelation() {
-               $this->actionService->copyRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageId);
+               $newTableIds = $this->actionService->copyRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageId);
                $this->assertAssertionDataSet('copyContentRecordOfCategoryRelation');
+
+               $newContentId = $newTableIds[self::TABLE_Content][self::VALUE_ContentIdLast];
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . $newContentId, 'categories',
+                       self::TABLE_Category, 'title', array('Category B', 'Category C')
+               );
        }
 
        /**
@@ -200,6 +287,14 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function copyCategoryRecordOfCategoryRelation() {
                $this->actionService->copyRecord(self::TABLE_Category, self::VALUE_CategoryIdFirst, 0);
                $this->assertAssertionDataSet('copyCategoryRecordOfCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', 'Category A'
+                       // @todo Actually it should be twice "Category A" since the category got copied
+                       // self::TABLE_Category, 'title', array('Category A', 'Category A')
+               );
        }
 
        /**
@@ -208,6 +303,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function localizeContentRecordOfCategoryRelation() {
                $this->actionService->localizeRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_LanguageId);
                $this->assertAssertionDataSet('localizeContentRecordOfCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'categories',
+                       self::TABLE_Category, 'title', array('Category B', 'Category C')
+               );
        }
 
        /**
@@ -216,6 +317,14 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function localizeCategoryRecordOfCategoryRelation() {
                $this->actionService->localizeRecord(self::TABLE_Category, self::VALUE_CategoryIdFirst, self::VALUE_LanguageId);
                $this->assertAssertionDataSet('localizeCategoryRecordOfCategoryRelation');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', array('Category A', 'Category B')
+                       // @todo Actually it should contain the localized category
+                       // self::TABLE_Category, 'title', array('[Translate to Dansk:] Category A', 'Category B')
+               );
        }
 
        /**
@@ -224,6 +333,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function moveContentRecordOfCategoryRelationToDifferentPage() {
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageIdTarget);
                $this->assertAssertionDataSet('moveContentRecordOfCategoryRelationToDifferentPage');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageIdTarget, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdLast, 'categories',
+                       self::TABLE_Category, 'title', array('Category B', 'Category C')
+               );
        }
 
 }
index 16f34a5..4de31b7 100644 (file)
@@ -33,7 +33,7 @@ class WorkspaceActionTest extends AbstractActionTestCase {
 
        public function setUp() {
                parent::setUp();
-               $this->backendUser->workspace = 1;
+               $this->backendUser->workspace = self::VALUE_WorkspaceId;
        }
 
 }
index 50f7129..f18135c 100644 (file)
@@ -37,6 +37,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        const VALUE_ContentIdFirst = 297;
        const VALUE_ContentIdLast = 298;
        const VALUE_LanguageId = 1;
+       const VALUE_WorkspaceId = 1;
 
        const TABLE_Page = 'pages';
        const TABLE_Content = 'tt_content';
@@ -58,6 +59,8 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                parent::setUp();
                $this->importScenarioDataSet('LiveDefaultPages');
                $this->importScenarioDataSet('LiveDefaultElements');
+
+               $this->setUpFrontendRootPage(1, array('typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.ts'));
        }
 
        /**
@@ -73,6 +76,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                // Creating record at the end of the page (after last one)
                $this->actionService->createNewRecord(self::TABLE_Content, -self::VALUE_ContentIdLast, array('header' => 'Testing #2'));
                $this->assertAssertionDataSet('createContentRecords');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', array('Testing #1', 'Testing #2'));
        }
 
        /**
@@ -81,6 +87,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function modifyContentRecord() {
                $this->actionService->modifyRecord(self::TABLE_Content, self::VALUE_ContentIdLast, array('header' => 'Testing #1'));
                $this->assertAssertionDataSet('modifyContentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
        }
 
        /**
@@ -89,6 +98,10 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function deleteContentRecord() {
                $this->actionService->deleteRecord(self::TABLE_Content, self::VALUE_ContentIdLast);
                $this->assertAssertionDataSet('deleteContentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Regular Element #1');
+               $this->assertResponseContentDoesNotHaveRecords($responseContent, self::TABLE_Content, 'header', 'Regular Element #2');
        }
 
        /**
@@ -97,6 +110,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function copyContentRecord() {
                $this->actionService->copyRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageId);
                $this->assertAssertionDataSet('copyContentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Regular Element #2 (copy 1)');
        }
 
        /**
@@ -105,6 +121,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function localizeContentRecord() {
                $this->actionService->localizeRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_LanguageId);
                $this->assertAssertionDataSet('localizeContentRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', array('Regular Element #1', '[Translate to Dansk:] Regular Element #2'));
        }
 
        /**
@@ -113,6 +132,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function changeContentRecordSorting() {
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdFirst, -self::VALUE_ContentIdLast);
                $this->assertAssertionDataSet('changeContentRecordSorting');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', array('Regular Element #1', 'Regular Element #2'));
        }
 
        /**
@@ -121,6 +143,11 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function moveContentRecordToDifferentPage() {
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageIdTarget);
                $this->assertAssertionDataSet('moveContentRecordToDifferentPage');
+
+               $responseContentSource = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContentSource, self::TABLE_Content, 'header', 'Regular Element #1');
+               $responseContentTarget = $this->getFrontendResponse(self::VALUE_PageIdTarget, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContentTarget, self::TABLE_Content, 'header', 'Regular Element #2');
        }
 
        /**
@@ -131,6 +158,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_PageIdTarget);
                $this->actionService->moveRecord(self::TABLE_Content, self::VALUE_ContentIdFirst, -self::VALUE_ContentIdLast);
                $this->assertAssertionDataSet('moveContentRecordToDifferentPageAndChangeSorting');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageIdTarget, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', array('Regular Element #1', 'Regular Element #2'));
        }
 
        /**
@@ -141,8 +171,12 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
         * @test
         */
        public function createPageRecord() {
-               $this->actionService->createNewRecord(self::TABLE_Page, self::VALUE_PageId, array('title' => 'Testing #1'));
+               $newTableIds = $this->actionService->createNewRecord(self::TABLE_Page, self::VALUE_PageId, array('title' => 'Testing #1'));
                $this->assertAssertionDataSet('createPageRecord');
+
+               $newPageId = $newTableIds[self::TABLE_Page][0];
+               $responseContent = $this->getFrontendResponse($newPageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Page, 'title', 'Testing #1');
        }
 
        /**
@@ -151,6 +185,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function modifyPageRecord() {
                $this->actionService->modifyRecord(self::TABLE_Page, self::VALUE_PageId, array('title' => 'Testing #1'));
                $this->assertAssertionDataSet('modifyPageRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Page, 'title', 'Testing #1');
        }
 
        /**
@@ -159,14 +196,21 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function deletePageRecord() {
                $this->actionService->deleteRecord(self::TABLE_Page, self::VALUE_PageId);
                $this->assertAssertionDataSet('deletePageRecord');
+
+               $response = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId, FALSE);
+               $this->assertContains('RuntimeException', $response->getError());
        }
 
        /**
         * @test
         */
        public function copyPageRecord() {
-               $this->actionService->copyRecord(self::TABLE_Page, self::VALUE_PageId, self::VALUE_PageIdTarget);
+               $newTableIds = $this->actionService->copyRecord(self::TABLE_Page, self::VALUE_PageId, self::VALUE_PageIdTarget);
                $this->assertAssertionDataSet('copyPageRecord');
+
+               $newPageId = $newTableIds[self::TABLE_Page][self::VALUE_PageId];
+               $responseContent = $this->getFrontendResponse($newPageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Page, 'title', 'Relations');
        }
 
        /**
@@ -175,6 +219,9 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function localizePageRecord() {
                $this->actionService->localizeRecord(self::TABLE_Page, self::VALUE_PageId, self::VALUE_LanguageId);
                $this->assertAssertionDataSet('localizePageRecord');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Page, 'title', '[Translate to Dansk:] Relations');
        }
 
        /**
@@ -183,6 +230,10 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function changePageRecordSorting() {
                $this->actionService->moveRecord(self::TABLE_Page, self::VALUE_PageId, -self::VALUE_PageIdTarget);
                $this->assertAssertionDataSet('changePageRecordSorting');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Page, 'title', 'Relations');
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', array('Regular Element #1', 'Regular Element #2'));
        }
 
        /**
@@ -191,6 +242,10 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
        public function movePageRecordToDifferentPage() {
                $this->actionService->moveRecord(self::TABLE_Page, self::VALUE_PageId, self::VALUE_PageIdTarget);
                $this->assertAssertionDataSet('movePageRecordToDifferentPage');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Page, 'title', 'Relations');
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', array('Regular Element #1', 'Regular Element #2'));
        }
 
        /**
@@ -200,6 +255,10 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                $this->actionService->moveRecord(self::TABLE_Page, self::VALUE_PageIdTarget, self::VALUE_PageIdWebsite);
                $this->actionService->moveRecord(self::TABLE_Page, self::VALUE_PageId, -self::VALUE_PageIdTarget);
                $this->assertAssertionDataSet('movePageRecordToDifferentPageAndChangeSorting');
+
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Page, 'title', 'Relations');
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', array('Regular Element #1', 'Regular Element #2'));
        }
 
 }
index 48eac21..2029534 100644 (file)
@@ -33,7 +33,7 @@ class WorkspaceActionTest extends AbstractActionTestCase {
 
        public function setUp() {
                parent::setUp();
-               $this->backendUser->workspace = 1;
+               $this->backendUser->workspace = self::VALUE_WorkspaceId;
        }
 
 }