From 446a20c4784e022b07ce9ddda0dbf97a6381cdaf Mon Sep 17 00:00:00 2001 From: Stefan Froemken Date: Mon, 15 Jan 2024 10:27:17 +0100 Subject: [PATCH] Update func tests --- .../Functional/Configuration/ExtConfTest.php | 47 +- .../Fixtures/basic_template.typoscript | 9 + Tests/Functional/Fixtures/pages.xml | 6 + Tests/Functional/Helper/MessageHelperTest.php | 415 +++++++++++++ .../Form/DynamicUploadValidatorHookTest.php | 564 ++++++++++++++---- .../Hooks/Form/ReplacePlaceholderHookTest.php | 99 +-- 6 files changed, 971 insertions(+), 169 deletions(-) create mode 100644 Tests/Functional/Fixtures/basic_template.typoscript create mode 100644 Tests/Functional/Fixtures/pages.xml create mode 100644 Tests/Functional/Helper/MessageHelperTest.php diff --git a/Tests/Functional/Configuration/ExtConfTest.php b/Tests/Functional/Configuration/ExtConfTest.php index ae075b6..34141f9 100644 --- a/Tests/Functional/Configuration/ExtConfTest.php +++ b/Tests/Functional/Configuration/ExtConfTest.php @@ -13,8 +13,12 @@ use JWeiland\Checkfaluploads\Configuration\ExtConf; use Nimut\TestingFramework\TestCase\FunctionalTestCase; +use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Core\Configuration\ExtensionConfiguration; +use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder; +use TYPO3\CMS\Core\Http\ServerRequest; use TYPO3\CMS\Core\Localization\LanguageService; +use TYPO3\CMS\Core\Site\Entity\Site; use TYPO3\CMS\Core\Utility\GeneralUtility; /** @@ -52,6 +56,30 @@ public function tearDown(): void parent::tearDown(); } + private function getRequestForContext(int $applicationType): ServerRequestInterface + { + $site = new Site('https://example.com', 1, [ + 'base' => '/', + 'languages' => [ + 0 => [ + 'languageId' => 0, + 'locale' => 'en_US.UTF-8', + 'base' => '/en/', + 'enabled' => false, + ], + ], + ]); + + $this->importDataSet(__DIR__ . '/../Fixtures/pages.xml'); + + // Request to default page + $request = new ServerRequest('https://example.com', 'GET'); + $request = $request->withAttribute('site', $site); + $request = $request->withAttribute('applicationType', $applicationType); + + return $request->withAttribute('language', $site->getDefaultLanguage()); + } + /** * @test */ @@ -79,8 +107,25 @@ public function setOwnerSetsOwner(): void /** * @test */ - public function getLabelForUserRightsContainsOwner(): void + public function getLabelForUserRightsInFrontendContextContainsOwner(): void { + $GLOBALS['TYPO3_REQUEST'] = $this->getRequestForContext(SystemEnvironmentBuilder::REQUESTTYPE_FE); + + $this->subject->setOwner('foo bar'); + + self::assertStringContainsString( + 'foo bar', + $this->subject->getLabelForUserRights() + ); + } + + /** + * @test + */ + public function getLabelForUserRightsInBackendContextContainsOwner(): void + { + $GLOBALS['TYPO3_REQUEST'] = $this->getRequestForContext(SystemEnvironmentBuilder::REQUESTTYPE_BE); + $this->subject->setOwner('foo bar'); self::assertStringContainsString( diff --git a/Tests/Functional/Fixtures/basic_template.typoscript b/Tests/Functional/Fixtures/basic_template.typoscript new file mode 100644 index 0000000..8ca4a51 --- /dev/null +++ b/Tests/Functional/Fixtures/basic_template.typoscript @@ -0,0 +1,9 @@ +page = PAGE +page { + config { + disableAllHeaderCode = 1 + } + + 10 = TEXT + 10.value =

I like apples

+} diff --git a/Tests/Functional/Fixtures/pages.xml b/Tests/Functional/Fixtures/pages.xml new file mode 100644 index 0000000..d346147 --- /dev/null +++ b/Tests/Functional/Fixtures/pages.xml @@ -0,0 +1,6 @@ + + + + 1 + + diff --git a/Tests/Functional/Helper/MessageHelperTest.php b/Tests/Functional/Helper/MessageHelperTest.php new file mode 100644 index 0000000..1eb1bd5 --- /dev/null +++ b/Tests/Functional/Helper/MessageHelperTest.php @@ -0,0 +1,415 @@ +setUpBackendUserFromFixture(1); + + $this->subject = new MessageHelper( + new FlashMessageService() + ); + } + + protected function tearDown(): void + { + unset( + $this->subject + ); + + parent::tearDown(); + } + + /** + * @test + */ + public function addFlashMessageWithMessageCallsEnqueue(): void + { + $expectedFlashMessage = new FlashMessage( + 'Hello', + '', + AbstractMessage::OK, + true + ); + + $this->subject->addFlashMessage('Hello'); + + self::assertEquals( + [$expectedFlashMessage], + $this->subject->getAllFlashMessages() + ); + } + + /** + * @test + */ + public function addFlashMessageWithMessageAndSubjectCallsEnqueue(): void + { + $expectedFlashMessage = new FlashMessage( + 'Hello', + 'Subject', + AbstractMessage::OK, + true + ); + + $this->subject->addFlashMessage('Hello', 'Subject'); + + self::assertEquals( + [$expectedFlashMessage], + $this->subject->getAllFlashMessages() + ); + } + + /** + * @test + */ + public function addFlashMessageWithAllArgumentsCallsEnqueue(): void + { + $expectedFlashMessage = new FlashMessage( + 'Hello', + 'Subject', + AbstractMessage::ERROR, + true + ); + + $this->subject->addFlashMessage('Hello', 'Subject', AbstractMessage::ERROR); + + self::assertEquals( + [$expectedFlashMessage], + $this->subject->getAllFlashMessages() + ); + } + + /** + * @test + */ + public function getAllFlashMessagesReturnsAllFlashMessages(): void + { + $this->subject->addFlashMessage('Hello', 'Hello'); + $this->subject->addFlashMessage('all', 'all', AbstractMessage::WARNING); + $this->subject->addFlashMessage('together', 'together', AbstractMessage::ERROR); + + // Test two times, to be safe that messages were NOT flushed + self::assertCount( + 3, + $this->subject->getAllFlashMessages(false) + ); + self::assertCount( + 3, + $this->subject->getAllFlashMessages(false) + ); + } + + /** + * @test + */ + public function getAllFlashMessagesReturnsAllFlashMessagesAndFlush(): void + { + $this->subject->addFlashMessage('Hello', 'Hello'); + $this->subject->addFlashMessage('all', 'all', AbstractMessage::WARNING); + $this->subject->addFlashMessage('together', 'together', AbstractMessage::ERROR); + + // Test two times, to be safe that messages were flushed + self::assertCount( + 3, + $this->subject->getAllFlashMessages() + ); + self::assertCount( + 0, + $this->subject->getAllFlashMessages() + ); + } + + /** + * @test + */ + public function hasMessagesChecksQueueIfThereAreAnyMessages(): void + { + $this->subject->addFlashMessage('Hello', 'Hello'); + $this->subject->addFlashMessage('all', 'all', AbstractMessage::WARNING); + $this->subject->addFlashMessage('together', 'together', AbstractMessage::ERROR); + + self::assertTrue( + $this->subject->hasMessages() + ); + } + + /** + * @test + */ + public function getFlashMessagesBySeverityAndFlushReturnsFlashMessages(): void + { + $this->subject->addFlashMessage('Hello', 'Hello', AbstractMessage::WARNING); + $this->subject->addFlashMessage('all', 'all', AbstractMessage::WARNING); + $this->subject->addFlashMessage('together', 'together', AbstractMessage::ERROR); + + // Test two times, to be save that messages were flushed + self::assertCount( + 1, + $this->subject->getFlashMessagesBySeverityAndFlush(AbstractMessage::ERROR) + ); + self::assertCount( + 0, + $this->subject->getFlashMessagesBySeverityAndFlush(AbstractMessage::ERROR) + ); + + // Test two times, to be save that messages were flushed + self::assertCount( + 2, + $this->subject->getFlashMessagesBySeverityAndFlush(AbstractMessage::WARNING) + ); + self::assertCount( + 0, + $this->subject->getFlashMessagesBySeverityAndFlush(AbstractMessage::WARNING) + ); + } + + /** + * @test + */ + public function hasErrorMessagesReturnsTrue(): void + { + $this->subject->addFlashMessage('Hello', 'Hello', AbstractMessage::WARNING); + $this->subject->addFlashMessage('all', 'all', AbstractMessage::ERROR); + $this->subject->addFlashMessage('together', 'together', AbstractMessage::ERROR); + + self::assertTrue( + $this->subject->hasErrorMessages() + ); + } + + /** + * @test + */ + public function hasErrorMessagesReturnsFalse(): void + { + $this->subject->addFlashMessage('Hello', 'Hello', AbstractMessage::WARNING); + $this->subject->addFlashMessage('all', 'all'); + $this->subject->addFlashMessage('together', 'together'); + + self::assertFalse( + $this->subject->hasErrorMessages() + ); + } + + /** + * @test + */ + public function getErrorMessagesReturnsErrorMessages(): void + { + $this->subject->addFlashMessage('Hello', 'Hello', AbstractMessage::WARNING); + $this->subject->addFlashMessage('all', 'all', AbstractMessage::ERROR); + $this->subject->addFlashMessage('together', 'together', AbstractMessage::ERROR); + + self::assertCount( + 2, + $this->subject->getErrorMessages() + ); + } + + /** + * @test + */ + public function hasWarningMessagesReturnsTrue(): void + { + $this->subject->addFlashMessage('Hello', 'Hello'); + $this->subject->addFlashMessage('all', 'all', AbstractMessage::WARNING); + $this->subject->addFlashMessage('together', 'together', AbstractMessage::WARNING); + + self::assertTrue( + $this->subject->hasWarningMessages() + ); + } + + /** + * @test + */ + public function hasWarningMessagesReturnsFalse(): void + { + $this->subject->addFlashMessage('Hello', 'Hello'); + $this->subject->addFlashMessage('all', 'all', AbstractMessage::ERROR); + $this->subject->addFlashMessage('together', 'together', AbstractMessage::ERROR); + + self::assertFalse( + $this->subject->hasWarningMessages() + ); + } + + /** + * @test + */ + public function getWarningMessagesReturnsErrorMessages(): void + { + $this->subject->addFlashMessage('Hello', 'Hello'); + $this->subject->addFlashMessage('all', 'all', AbstractMessage::WARNING); + $this->subject->addFlashMessage('together', 'together', AbstractMessage::WARNING); + + self::assertCount( + 2, + $this->subject->getWarningMessages() + ); + } + + /** + * @test + */ + public function hasOkMessagesReturnsTrue(): void + { + $this->subject->addFlashMessage('Hello', 'Hello', AbstractMessage::WARNING); + $this->subject->addFlashMessage('all', 'all'); + $this->subject->addFlashMessage('together', 'together'); + + self::assertTrue( + $this->subject->hasOkMessages() + ); + } + + /** + * @test + */ + public function hasOkMessagesReturnsFalse(): void + { + $this->subject->addFlashMessage('Hello', 'Hello', AbstractMessage::ERROR); + $this->subject->addFlashMessage('all', 'all', AbstractMessage::WARNING); + $this->subject->addFlashMessage('together', 'together', AbstractMessage::WARNING); + + self::assertFalse( + $this->subject->hasOkMessages() + ); + } + + /** + * @test + */ + public function getOkMessagesReturnsErrorMessages(): void + { + $this->subject->addFlashMessage('Hello', 'Hello', AbstractMessage::WARNING); + $this->subject->addFlashMessage('all', 'all'); + $this->subject->addFlashMessage('together', 'together'); + + self::assertCount( + 2, + $this->subject->getOkMessages() + ); + } + + /** + * @test + */ + public function hasInfoMessagesReturnsTrue(): void + { + $this->subject->addFlashMessage('Hello', 'Hello', AbstractMessage::WARNING); + $this->subject->addFlashMessage('all', 'all', AbstractMessage::INFO); + $this->subject->addFlashMessage('together', 'together', AbstractMessage::INFO); + + self::assertTrue( + $this->subject->hasInfoMessages() + ); + } + + /** + * @test + */ + public function hasInfoMessagesReturnsFalse(): void + { + $this->subject->addFlashMessage('Hello', 'Hello', AbstractMessage::ERROR); + $this->subject->addFlashMessage('all', 'all', AbstractMessage::WARNING); + $this->subject->addFlashMessage('together', 'together', AbstractMessage::WARNING); + + self::assertFalse( + $this->subject->hasInfoMessages() + ); + } + + /** + * @test + */ + public function getInfoMessagesReturnsErrorMessages(): void + { + $this->subject->addFlashMessage('Hello', 'Hello', AbstractMessage::WARNING); + $this->subject->addFlashMessage('all', 'all', AbstractMessage::INFO); + $this->subject->addFlashMessage('together', 'together', AbstractMessage::INFO); + + self::assertCount( + 2, + $this->subject->getInfoMessages() + ); + } + + /** + * @test + */ + public function hasNoticeMessagesReturnsTrue(): void + { + $this->subject->addFlashMessage('Hello', 'Hello', AbstractMessage::WARNING); + $this->subject->addFlashMessage('all', 'all', AbstractMessage::NOTICE); + $this->subject->addFlashMessage('together', 'together', AbstractMessage::NOTICE); + + self::assertTrue( + $this->subject->hasNoticeMessages() + ); + } + + /** + * @test + */ + public function hasNoticeMessagesReturnsFalse(): void + { + $this->subject->addFlashMessage('Hello', 'Hello', AbstractMessage::ERROR); + $this->subject->addFlashMessage('all', 'all', AbstractMessage::WARNING); + $this->subject->addFlashMessage('together', 'together', AbstractMessage::WARNING); + + self::assertFalse( + $this->subject->hasNoticeMessages() + ); + } + + /** + * @test + */ + public function getNoticeMessagesReturnsErrorMessages(): void + { + $this->subject->addFlashMessage('Hello', 'Hello', AbstractMessage::WARNING); + $this->subject->addFlashMessage('all', 'all', AbstractMessage::NOTICE); + $this->subject->addFlashMessage('together', 'together', AbstractMessage::NOTICE); + + self::assertCount( + 2, + $this->subject->getNoticeMessages() + ); + } +} diff --git a/Tests/Functional/Hooks/Form/DynamicUploadValidatorHookTest.php b/Tests/Functional/Hooks/Form/DynamicUploadValidatorHookTest.php index 1642bf6..ceeb7ec 100644 --- a/Tests/Functional/Hooks/Form/DynamicUploadValidatorHookTest.php +++ b/Tests/Functional/Hooks/Form/DynamicUploadValidatorHookTest.php @@ -9,16 +9,13 @@ * LICENSE file that was distributed with this source code. */ -namespace JWeiland\Checkfaluploads\Tests\Functional\Hooks; +namespace JWeiland\Checkfaluploads\Tests\Functional\Hooks\Form; use JWeiland\Checkfaluploads\Hooks\Form\DynamicUploadValidatorHook; use Nimut\TestingFramework\TestCase\FunctionalTestCase; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; +use PHPUnit\Framework\MockObject\MockObject; use TYPO3\CMS\Extbase\Validation\Validator\NotEmptyValidator; use TYPO3\CMS\Form\Domain\Model\FormElements\FileUpload; -use TYPO3\CMS\Form\Domain\Model\FormElements\FormElementInterface; use TYPO3\CMS\Form\Domain\Model\FormElements\GenericFormElement; use TYPO3\CMS\Form\Domain\Model\FormElements\Page; use TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface; @@ -29,44 +26,20 @@ */ class DynamicUploadValidatorHookTest extends FunctionalTestCase { - use ProphecyTrait; - /** - * @var FormRuntime|ObjectProphecy + * @var FormRuntime|MockObject */ - protected $formRuntimeProphecy; + protected $formRuntimeMock; /** - * @var RenderableInterface|Page|ObjectProphecy + * @var RenderableInterface|Page|MockObject */ - protected $renderableProphecy; + protected $renderableMock; /** - * @var DynamicUploadValidatorHook - */ - protected $subject; - - /** - * @var array + * @var DynamicUploadValidatorHook|null */ - protected $elementValue = [ - 'foo' => 'bar' - ]; - - /** - * @var array - */ - protected $requestArguments = [ - 'foo' => 'bar', - 'image-upload' => [ - 'error' => 0, - 'name' => 'schlumpf', - 'size' => 123, - 'tmp_name' => '/tmp/nr4378tg', - 'type' => 2, - ], - 'upload-rights' => '0', - ]; + protected $subject = null; /** * Core extensions to load. @@ -74,11 +47,11 @@ class DynamicUploadValidatorHookTest extends FunctionalTestCase * @var array */ protected $coreExtensionsToLoad = [ - 'form' + 'form', ]; /** - * @var array + * @var array|string[] */ protected $testExtensionsToLoad = [ 'typo3conf/ext/checkfaluploads' @@ -88,8 +61,8 @@ public function setUp(): void { parent::setUp(); - $this->formRuntimeProphecy = $this->prophesize(FormRuntime::class); - $this->renderableProphecy = $this->prophesize(Page::class); + $this->formRuntimeMock = $this->createMock(FormRuntime::class); + $this->renderableMock = $this->createMock(Page::class); $this->subject = new DynamicUploadValidatorHook(); } @@ -98,8 +71,8 @@ public function tearDown(): void { unset( $this->subject, - $this->renderableProphecy, - $this->formRuntimeProphecy + $this->renderableMock, + $this->formRuntimeMock ); parent::tearDown(); @@ -108,33 +81,146 @@ public function tearDown(): void /** * @test */ - public function afterSubmitWithoutUploadElementsWillNotAddValidator(): void + public function afterSubmitWithoutFileUploadWillReturnOriginalElementValue(): void { - /** @var FormElementInterface|ObjectProphecy $formElement */ - $formElement = $this->prophesize(GenericFormElement::class); - $formElement - ->getProperties() + self::assertSame( + 'Test', + $this->subject->afterSubmit( + $this->formRuntimeMock, + $this->createMock(Page::class), + 'Test' + ) + ); + } + + /** + * @test + */ + public function afterSubmitWithNullValueWillReturnNull(): void + { + self::assertNull( + $this->subject->afterSubmit( + $this->formRuntimeMock, + $this->createMock(FileUpload::class), + null + ) + ); + } + + /** + * @test + */ + public function afterSubmitWithUploadedFileErrorWillReturnNull(): void + { + self::assertNull( + $this->subject->afterSubmit( + $this->formRuntimeMock, + $this->createMock(FileUpload::class), + [ + 'error' => 1, + ] + ) + ); + } + + public function invalidResourcePointerDataProvider(): array + { + return [ + 'empty array' => [[]], + 'invalid array structure' => [['eat' => 'apple']], + 'empty submitted file' => [['submittedFile' => []]], + 'empty resource pointer' => [['submittedFile' => ['resourcePointer' => '']]], + ]; + } + + /** + * @test + * + * @dataProvider invalidResourcePointerDataProvider + */ + public function afterSubmitWithEmptyResourcePointerWillReturnNull($invalidResourcePointer): void + { + self::assertNull( + $this->subject->afterSubmit( + $this->formRuntimeMock, + $this->createMock(FileUpload::class), + $invalidResourcePointer + ) + ); + } + + /** + * @test + */ + public function afterSubmitWithNoChildElementsReturnsOriginalEmptyValue(): void + { + $uploadedFile = [ + 'error' => 0, + 'path' => '/tmp/cth8w9mth' + ]; + + /** @var Page|MockObject $pageMock */ + $pageMock = $this->createMock(Page::class); + $pageMock + ->expects(self::atLeastOnce()) + ->method('getElementsRecursively') ->willReturn([]); - $formElement - ->addValidator(Argument::cetera()) - ->shouldNotBeCalled(); + /** @var FileUpload|MockObject $fileUploadMock */ + $fileUploadMock = $this->createMock(FileUpload::class); + $fileUploadMock + ->expects(self::atLeastOnce()) + ->method('getParentRenderable') + ->willReturn($pageMock); - $this->renderableProphecy = $this->prophesize(Page::class); - $this->renderableProphecy - ->getElementsRecursively() - ->shouldBeCalled() + self::assertSame( + $uploadedFile, + $this->subject->afterSubmit( + $this->formRuntimeMock, + $fileUploadMock, + $uploadedFile + ) + ); + } + + /** + * @test + */ + public function afterSubmitWithNoCheckboxElementReturnsOriginalEmptyValue(): void + { + /** @var GenericFormElement|MockObject $genericFormElementMock */ + $genericFormElementMock = $this->createMock(GenericFormElement::class); + $genericFormElementMock + ->expects(self::atLeastOnce()) + ->method('getType') + ->willReturn('Text'); + + /** @var Page|MockObject $pageMock */ + $pageMock = $this->createMock(Page::class); + $pageMock + ->expects(self::atLeastOnce()) + ->method('getElementsRecursively') ->willReturn([ - 0 => $formElement->reveal() + $genericFormElementMock, ]); + $fileUploadMock = $this->createMock(FileUpload::class); + $fileUploadMock + ->expects(self::atLeastOnce()) + ->method('getParentRenderable') + ->willReturn($pageMock); + + $uploadedFile = [ + 'error' => 0, + 'path' => '/tmp/cth8w9mth' + ]; + self::assertSame( - $this->elementValue, + $uploadedFile, $this->subject->afterSubmit( - $this->formRuntimeProphecy->reveal(), - $this->renderableProphecy->reveal(), - $this->elementValue, - $this->requestArguments + $this->formRuntimeMock, + $fileUploadMock, + $uploadedFile ) ); } @@ -142,52 +228,93 @@ public function afterSubmitWithoutUploadElementsWillNotAddValidator(): void /** * @test */ - public function afterSubmitWithFailedUploadWillNotAddValidator(): void + public function afterSubmitWithEmptyCheckboxPropertiesReturnsOriginalEmptyValue(): void { - /** @var FormElementInterface|ObjectProphecy $fileUploadProphecy */ - $fileUploadProphecy = $this->prophesize(FileUpload::class); - $fileUploadProphecy - ->getProperties() + /** @var GenericFormElement|MockObject $checkboxFormElementMock */ + $checkboxFormElementMock = $this->createMock(GenericFormElement::class); + $checkboxFormElementMock + ->expects(self::atLeastOnce()) + ->method('getType') + ->willReturn('Checkbox'); + $checkboxFormElementMock + ->expects(self::atLeastOnce()) + ->method('getProperties') ->willReturn([]); - $fileUploadProphecy - ->getIdentifier() - ->willReturn('image-upload'); - - /** @var FormElementInterface|ObjectProphecy $checkboxElementProphecy */ - $checkboxElementProphecy = $this->prophesize(GenericFormElement::class); - $checkboxElementProphecy - ->getProperties() + + /** @var Page|MockObject $pageMock */ + $pageMock = $this->createMock(Page::class); + $pageMock + ->expects(self::atLeastOnce()) + ->method('getElementsRecursively') + ->willReturn([ + $checkboxFormElementMock, + ]); + + $fileUploadMock = $this->createMock(FileUpload::class); + $fileUploadMock + ->expects(self::atLeastOnce()) + ->method('getParentRenderable') + ->willReturn($pageMock); + + $uploadedFile = [ + 'error' => 0, + 'path' => '/tmp/cth8w9mth' + ]; + + self::assertSame( + $uploadedFile, + $this->subject->afterSubmit( + $this->formRuntimeMock, + $fileUploadMock, + $uploadedFile + ) + ); + } + + /** + * @test + */ + public function afterSubmitWithEmptyUploadIdentifierReturnsOriginalEmptyValue(): void + { + /** @var GenericFormElement|MockObject $checkboxFormElementMock */ + $checkboxFormElementMock = $this->createMock(GenericFormElement::class); + $checkboxFormElementMock + ->expects(self::atLeastOnce()) + ->method('getType') + ->willReturn('Checkbox'); + $checkboxFormElementMock + ->expects(self::atLeastOnce()) + ->method('getProperties') ->willReturn([ 'checkboxType' => 'uploadRights', - 'referenceUploadIdentifier' => 'image-upload' ]); - $checkboxElementProphecy - ->getIdentifier() - ->willReturn('upload-rights'); - - $checkboxElementProphecy - ->addValidator(Argument::cetera()) - ->shouldNotBeCalled(); - - $this->renderableProphecy = $this->prophesize(Page::class); - $this->renderableProphecy - ->getElementsRecursively() - ->shouldBeCalled() + + /** @var Page|MockObject $pageMock */ + $pageMock = $this->createMock(Page::class); + $pageMock + ->expects(self::atLeastOnce()) + ->method('getElementsRecursively') ->willReturn([ - 0 => $fileUploadProphecy->reveal(), - 1 => $checkboxElementProphecy->reveal() + $checkboxFormElementMock, ]); - $requestArguments = $this->requestArguments; - $requestArguments['image-upload']['error'] = 4; + $fileUploadMock = $this->createMock(FileUpload::class); + $fileUploadMock + ->expects(self::atLeastOnce()) + ->method('getParentRenderable') + ->willReturn($pageMock); + + $uploadedFile = [ + 'error' => 0, + 'path' => '/tmp/cth8w9mth' + ]; self::assertSame( - $this->elementValue, + $uploadedFile, $this->subject->afterSubmit( - $this->formRuntimeProphecy->reveal(), - $this->renderableProphecy->reveal(), - $this->elementValue, - $requestArguments + $this->formRuntimeMock, + $fileUploadMock, + $uploadedFile ) ); } @@ -195,49 +322,230 @@ public function afterSubmitWithFailedUploadWillNotAddValidator(): void /** * @test */ - public function afterSubmitWithUploadElementsWillAddValidator(): void + public function afterSubmitWithDifferentIdentifiersReturnsOriginalEmptyValue(): void { - /** @var FormElementInterface|ObjectProphecy $fileUploadProphecy */ - $fileUploadProphecy = $this->prophesize(FileUpload::class); - $fileUploadProphecy - ->getProperties() - ->willReturn([]); - $fileUploadProphecy - ->getIdentifier() - ->willReturn('image-upload'); - - /** @var FormElementInterface|ObjectProphecy $checkboxElementProphecy */ - $checkboxElementProphecy = $this->prophesize(GenericFormElement::class); - $checkboxElementProphecy - ->getProperties() + /** @var GenericFormElement|MockObject $checkboxFormElementMock */ + $checkboxFormElementMock = $this->createMock(GenericFormElement::class); + $checkboxFormElementMock + ->expects(self::atLeastOnce()) + ->method('getType') + ->willReturn('Checkbox'); + $checkboxFormElementMock + ->expects(self::atLeastOnce()) + ->method('getProperties') ->willReturn([ 'checkboxType' => 'uploadRights', - 'referenceUploadIdentifier' => 'image-upload' + 'referenceUploadIdentifier' => 'Different Identifier', ]); - $checkboxElementProphecy - ->getIdentifier() - ->willReturn('upload-rights'); - - $checkboxElementProphecy - ->addValidator(Argument::type(NotEmptyValidator::class)) - ->shouldBeCalled(); - - $this->renderableProphecy = $this->prophesize(Page::class); - $this->renderableProphecy - ->getElementsRecursively() - ->shouldBeCalled() + + /** @var Page|MockObject $pageMock */ + $pageMock = $this->createMock(Page::class); + $pageMock + ->expects(self::atLeastOnce()) + ->method('getElementsRecursively') ->willReturn([ - 0 => $fileUploadProphecy->reveal(), - 1 => $checkboxElementProphecy->reveal() + $checkboxFormElementMock, ]); + $fileUploadMock = $this->createMock(FileUpload::class); + $fileUploadMock + ->expects(self::atLeastOnce()) + ->method('getParentRenderable') + ->willReturn($pageMock); + $fileUploadMock + ->expects(self::atLeastOnce()) + ->method('getIdentifier') + ->willReturn('Other Identifier'); + + $uploadedFile = [ + 'error' => 0, + 'path' => '/tmp/cth8w9mth' + ]; + self::assertSame( - $this->elementValue, + $uploadedFile, + $this->subject->afterSubmit( + $this->formRuntimeMock, + $fileUploadMock, + $uploadedFile + ) + ); + } + + /** + * @test + */ + public function afterSubmitWithMissingCheckboxRequestReturnsOriginalEmptyValue(): void + { + /** @var GenericFormElement|MockObject $checkboxFormElementMock */ + $checkboxFormElementMock = $this->createMock(GenericFormElement::class); + $checkboxFormElementMock + ->expects(self::atLeastOnce()) + ->method('getType') + ->willReturn('Checkbox'); + $checkboxFormElementMock + ->expects(self::atLeastOnce()) + ->method('getProperties') + ->willReturn([ + 'checkboxType' => 'uploadRights', + 'referenceUploadIdentifier' => 'CorrectIdentifier', + ]); + + /** @var Page|MockObject $pageMock */ + $pageMock = $this->createMock(Page::class); + $pageMock + ->expects(self::atLeastOnce()) + ->method('getElementsRecursively') + ->willReturn([ + $checkboxFormElementMock, + ]); + + $fileUploadMock = $this->createMock(FileUpload::class); + $fileUploadMock + ->expects(self::atLeastOnce()) + ->method('getParentRenderable') + ->willReturn($pageMock); + $fileUploadMock + ->expects(self::atLeastOnce()) + ->method('getIdentifier') + ->willReturn('CorrectIdentifier'); + + $uploadedFile = [ + 'error' => 0, + 'path' => '/tmp/cth8w9mth' + ]; + + self::assertSame( + $uploadedFile, + $this->subject->afterSubmit( + $this->formRuntimeMock, + $fileUploadMock, + $uploadedFile + ) + ); + } + + /** + * @test + */ + public function afterSubmitWithActivatedCheckboxReturnsOriginalEmptyValue(): void + { + /** @var GenericFormElement|MockObject $checkboxFormElementMock */ + $checkboxFormElementMock = $this->createMock(GenericFormElement::class); + $checkboxFormElementMock + ->expects(self::atLeastOnce()) + ->method('getType') + ->willReturn('Checkbox'); + $checkboxFormElementMock + ->expects(self::atLeastOnce()) + ->method('getProperties') + ->willReturn([ + 'checkboxType' => 'uploadRights', + 'referenceUploadIdentifier' => 'FileUploadIdentifier', + ]); + $checkboxFormElementMock + ->expects(self::atLeastOnce()) + ->method('getIdentifier') + ->willReturn('CheckboxIdentifier'); + + /** @var Page|MockObject $pageMock */ + $pageMock = $this->createMock(Page::class); + $pageMock + ->expects(self::atLeastOnce()) + ->method('getElementsRecursively') + ->willReturn([ + $checkboxFormElementMock, + ]); + + $fileUploadMock = $this->createMock(FileUpload::class); + $fileUploadMock + ->expects(self::atLeastOnce()) + ->method('getParentRenderable') + ->willReturn($pageMock); + $fileUploadMock + ->expects(self::atLeastOnce()) + ->method('getIdentifier') + ->willReturn('FileUploadIdentifier'); + + $uploadedFile = [ + 'error' => 0, + 'path' => '/tmp/cth8w9mth' + ]; + + self::assertSame( + $uploadedFile, + $this->subject->afterSubmit( + $this->formRuntimeMock, + $fileUploadMock, + $uploadedFile, + [ + 'CheckboxIdentifier' => '1', + ] + ) + ); + } + + /** + * @test + */ + public function afterSubmitWithDeactivatedCheckboxWillAddNotEmptyValidator(): void + { + /** @var GenericFormElement|MockObject $checkboxFormElementMock */ + $checkboxFormElementMock = $this->createMock(GenericFormElement::class); + $checkboxFormElementMock + ->expects(self::atLeastOnce()) + ->method('getType') + ->willReturn('Checkbox'); + $checkboxFormElementMock + ->expects(self::atLeastOnce()) + ->method('getProperties') + ->willReturn([ + 'checkboxType' => 'uploadRights', + 'referenceUploadIdentifier' => 'FileUploadIdentifier', + ]); + $checkboxFormElementMock + ->expects(self::atLeastOnce()) + ->method('getIdentifier') + ->willReturn('CheckboxIdentifier'); + $checkboxFormElementMock + ->expects(self::atLeastOnce()) + ->method('addValidator') + ->with( + self::isInstanceOf(NotEmptyValidator::class) + ); + + /** @var Page|MockObject $pageMock */ + $pageMock = $this->createMock(Page::class); + $pageMock + ->expects(self::atLeastOnce()) + ->method('getElementsRecursively') + ->willReturn([ + $checkboxFormElementMock, + ]); + + $fileUploadMock = $this->createMock(FileUpload::class); + $fileUploadMock + ->expects(self::atLeastOnce()) + ->method('getParentRenderable') + ->willReturn($pageMock); + $fileUploadMock + ->expects(self::atLeastOnce()) + ->method('getIdentifier') + ->willReturn('FileUploadIdentifier'); + + $uploadedFile = [ + 'error' => 0, + 'path' => '/tmp/cth8w9mth' + ]; + + self::assertNull( $this->subject->afterSubmit( - $this->formRuntimeProphecy->reveal(), - $this->renderableProphecy->reveal(), - $this->elementValue, - $this->requestArguments + $this->formRuntimeMock, + $fileUploadMock, + $uploadedFile, + [ + 'CheckboxIdentifier' => '', + ] ) ); } diff --git a/Tests/Functional/Hooks/Form/ReplacePlaceholderHookTest.php b/Tests/Functional/Hooks/Form/ReplacePlaceholderHookTest.php index ea6a9eb..6bfe8b1 100644 --- a/Tests/Functional/Hooks/Form/ReplacePlaceholderHookTest.php +++ b/Tests/Functional/Hooks/Form/ReplacePlaceholderHookTest.php @@ -9,17 +9,16 @@ * LICENSE file that was distributed with this source code. */ -namespace JWeiland\Checkfaluploads\Tests\Functional\Hooks; +namespace JWeiland\Checkfaluploads\Tests\Functional\Hooks\Form; use JWeiland\Checkfaluploads\Configuration\ExtConf; use JWeiland\Checkfaluploads\Hooks\Form\ReplacePlaceholderHook; use Nimut\TestingFramework\TestCase\FunctionalTestCase; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; -use Prophecy\Prophecy\ObjectProphecy; +use PHPUnit\Framework\MockObject\MockObject; use TYPO3\CMS\Core\Configuration\ExtensionConfiguration; -use TYPO3\CMS\Core\Localization\LanguageService; -use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder; +use TYPO3\CMS\Core\Http\ServerRequest; +use TYPO3\CMS\Core\Site\Entity\Site; use TYPO3\CMS\Form\Domain\Model\FormElements\GenericFormElement; use TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface; @@ -28,34 +27,32 @@ */ class ReplacePlaceholderHookTest extends FunctionalTestCase { - use ProphecyTrait; - /** - * @var RenderableInterface|GenericFormElement|ObjectProphecy + * @var RenderableInterface|GenericFormElement|MockObject */ - protected $renderableProphecy; + protected $renderableMock; /** - * @var ExtConf|ObjectProphecy + * @var ExtConf */ protected $extConf; /** - * @var ReplacePlaceholderHook + * @var ReplacePlaceholderHook|null */ - protected $subject; + protected $subject = null; /** * Core extensions to load. * - * @var array + * @var array|string[] */ protected $coreExtensionsToLoad = [ - 'form' + 'form', ]; /** - * @var array + * @var array|string[] */ protected $testExtensionsToLoad = [ 'typo3conf/ext/checkfaluploads' @@ -65,12 +62,29 @@ public function setUp(): void { parent::setUp(); - $GLOBALS['LANG'] = GeneralUtility::makeInstance(LanguageService::class); + $site = new Site('https://example.com', 1, [ + 'base' => '/', + 'languages' => [ + 0 => [ + 'languageId' => 0, + 'locale' => 'en_US.UTF-8', + 'base' => '/en/', + 'enabled' => false, + ], + ], + ]); + + // Request to default page + $request = new ServerRequest('https://example.com', 'GET'); + $request = $request->withAttribute('site', $site); + $request = $request->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_FE); + $GLOBALS['TYPO3_REQUEST'] = $request->withAttribute('language', $site->getDefaultLanguage()); + + $this->importDataSet(__DIR__ . '/../../Fixtures/pages.xml'); - $this->renderableProphecy = $this->prophesize(GenericFormElement::class); + $this->renderableMock = $this->createMock(GenericFormElement::class); $this->extConf = new ExtConf(new ExtensionConfiguration()); - GeneralUtility::setSingletonInstance(ExtConf::class, $this->extConf); $this->subject = new ReplacePlaceholderHook($this->extConf); } @@ -79,7 +93,7 @@ public function tearDown(): void { unset( $this->subject, - $this->renderableProphecy + $this->renderableMock ); parent::tearDown(); @@ -90,17 +104,18 @@ public function tearDown(): void */ public function afterBuildingFinishedWithoutCheckboxTypeWillNotModifyLabel(): void { - /** @var GenericFormElement|ObjectProphecy $formElement */ - $formElement = $this->prophesize(GenericFormElement::class); + /** @var GenericFormElement|MockObject $formElement */ + $formElement = $this->createMock(GenericFormElement::class); $formElement - ->getProperties() + ->expects(self::atLeastOnce()) + ->method('getProperties') ->willReturn([]); $formElement - ->setLabel(Argument::any()) - ->shouldNotBeCalled(); + ->expects(self::never()) + ->method('setLabel'); - $this->subject->afterBuildingFinished($formElement->reveal()); + $this->subject->afterBuildingFinished($formElement); } /** @@ -110,19 +125,21 @@ public function afterBuildingFinishedWithCheckboxTypeWillModifyLabelWithMissingO { $this->extConf->setOwner(''); - /** @var GenericFormElement|ObjectProphecy $formElement */ - $formElement = $this->prophesize(GenericFormElement::class); + /** @var GenericFormElement|MockObject $formElement */ + $formElement = $this->createMock(GenericFormElement::class); $formElement - ->getProperties() + ->expects(self::atLeastOnce()) + ->method('getProperties') ->willReturn([ - 'checkboxType' => 'uploadRights' + 'checkboxType' => 'uploadRights', ]); $formElement - ->setLabel(Argument::containingString('[Missing owner in ext settings of checkfaluploads]')) - ->shouldBeCalled(); + ->expects(self::atLeastOnce()) + ->method('setLabel') + ->with(self::stringContains('[Missing owner in ext settings of checkfaluploads]')); - $this->subject->afterBuildingFinished($formElement->reveal()); + $this->subject->afterBuildingFinished($formElement); } /** @@ -132,18 +149,20 @@ public function afterBuildingFinishedWithCheckboxTypeWillModifyLabelWithOwner(): { $this->extConf->setOwner('jweiland.net'); - /** @var GenericFormElement|ObjectProphecy $formElement */ - $formElement = $this->prophesize(GenericFormElement::class); + /** @var GenericFormElement|MockObject $formElement */ + $formElement = $this->createMock(GenericFormElement::class); $formElement - ->getProperties() + ->expects(self::atLeastOnce()) + ->method('getProperties') ->willReturn([ - 'checkboxType' => 'uploadRights' + 'checkboxType' => 'uploadRights', ]); $formElement - ->setLabel(Argument::containingString('jweiland.net')) - ->shouldBeCalled(); + ->expects(self::atLeastOnce()) + ->method('setLabel') + ->with(self::stringContains('jweiland.net')); - $this->subject->afterBuildingFinished($formElement->reveal()); + $this->subject->afterBuildingFinished($formElement); } }