From 2cff7798f13e2536bf92a3d434aef0f987710de8 Mon Sep 17 00:00:00 2001 From: Christian Kuhn Date: Wed, 28 Feb 2024 14:25:40 +0100 Subject: [PATCH] [TASK] Avoid phpunit getMockForAbstractClass() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deprecated with phpunit 11. Adapt to fixture classes to test details of abstracts. Resolves: #103228 Releases: main Change-Id: Ic0cd4541856beb45775d50d22b95be687888373a Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/83160 Reviewed-by: Anja Leichsenring Tested-by: Oliver Klee Reviewed-by: Stefan Bürk Reviewed-by: Oliver Klee Reviewed-by: Christian Kuhn Tested-by: Anja Leichsenring Tested-by: core-ci Tested-by: Stefan Bürk Tested-by: Christian Kuhn --- .../Domain/Finishers/AbstractFinisherTest.php | 354 +++--------------- .../Fixtures/AbstractFinisherFixture.php | 57 +++ .../FormElements/AbstractSectionTest.php | 149 ++------ ...Section.php => AbstractSectionFixture.php} | 17 +- .../Menu/AbstractMenuContentObjectTest.php | 172 +++------ .../AbstractMenuContentObjectFixture.php | 52 +++ .../Typolink/AbstractTypolinkBuilderTest.php | 119 ++---- .../AbstractTypolinkBuilderFixture.php | 40 ++ .../Php/Matcher/AbstractCoreMatcherTest.php | 32 +- .../Fixtures/AbstractCoreMatcherFixture.php | 35 ++ 10 files changed, 371 insertions(+), 656 deletions(-) create mode 100644 typo3/sysext/form/Tests/Unit/Domain/Finishers/Fixtures/AbstractFinisherFixture.php rename typo3/sysext/form/Tests/Unit/Domain/FormElements/Fixtures/{TestingSection.php => AbstractSectionFixture.php} (60%) create mode 100644 typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/Fixtures/AbstractMenuContentObjectFixture.php create mode 100644 typo3/sysext/frontend/Tests/Unit/Typolink/Fixtures/AbstractTypolinkBuilderFixture.php create mode 100644 typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/Fixtures/AbstractCoreMatcherFixture.php diff --git a/typo3/sysext/form/Tests/Unit/Domain/Finishers/AbstractFinisherTest.php b/typo3/sysext/form/Tests/Unit/Domain/Finishers/AbstractFinisherTest.php index 03fa36d93633..f7ace48098d8 100644 --- a/typo3/sysext/form/Tests/Unit/Domain/Finishers/AbstractFinisherTest.php +++ b/typo3/sysext/form/Tests/Unit/Domain/Finishers/AbstractFinisherTest.php @@ -18,13 +18,13 @@ namespace TYPO3\CMS\Form\Tests\Unit\Domain\Finishers; use PHPUnit\Framework\Attributes\Test; -use TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher; use TYPO3\CMS\Form\Domain\Finishers\Exception\FinisherException; use TYPO3\CMS\Form\Domain\Finishers\FinisherContext; use TYPO3\CMS\Form\Domain\Finishers\FinisherVariableProvider; use TYPO3\CMS\Form\Domain\Model\FormDefinition; use TYPO3\CMS\Form\Domain\Model\FormElements\StringableFormElementInterface; use TYPO3\CMS\Form\Domain\Runtime\FormRuntime; +use TYPO3\CMS\Form\Tests\Unit\Domain\Finishers\Fixtures\AbstractFinisherFixture; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; final class AbstractFinisherTest extends UnitTestCase @@ -32,264 +32,99 @@ final class AbstractFinisherTest extends UnitTestCase #[Test] public function parseOptionReturnsNullIfOptionNameIsTranslation(): void { - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false - ); - - self::assertNull($mockAbstractFinisher->_call('parseOption', 'translation')); + $subject = new AbstractFinisherFixture(); + self::assertNull($subject->parseOption('translation')); } #[Test] public function parseOptionReturnsNullIfOptionNameNotExistsWithinOptions(): void { - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false - ); - - $mockAbstractFinisher->_set('options', []); - - self::assertNull($mockAbstractFinisher->_call('parseOption', 'foo')); - } - - #[Test] - public function parseOptionReturnsNullIfOptionNameNotExistsWithinDefaultOptions(): void - { - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false - ); - - $mockAbstractFinisher->_set('options', []); - - self::assertNull($mockAbstractFinisher->_call('parseOption', 'foo')); - } - - #[Test] - public function parseOptionReturnsBoolOptionValuesAsBool(): void - { - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false - ); - - $mockAbstractFinisher->_set('options', [ - 'foo1' => false, - ]); - - self::assertFalse($mockAbstractFinisher->_call('parseOption', 'foo1')); + $subject = new AbstractFinisherFixture(); + $subject->options = []; + self::assertNull($subject->parseOption('foo')); } #[Test] public function parseOptionReturnsDefaultOptionValueIfOptionNameNotExistsWithinOptionsButWithinDefaultOptions(): void { - $expected = 'defaultValue'; - - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false, - false, - true, - [ - 'translateFinisherOption', - ] - ); - - $mockAbstractFinisher - ->method('translateFinisherOption') - ->willReturnArgument(0); - - $mockAbstractFinisher->_set('options', []); - $mockAbstractFinisher->_set('defaultOptions', [ - 'subject' => $expected, - ]); - $finisherContextMock = $this->createMock(FinisherContext::class); - $formRuntimeMock = $this->createMock(FormRuntime::class); $formRuntimeMock->method('offsetExists')->with(self::anything())->willReturn(true); $formRuntimeMock->method('offsetGet')->with(self::anything())->willReturn(null); - $finisherContextMock->method('getFormRuntime')->willReturn($formRuntimeMock); - $finisherContextMock->method('getFinisherVariableProvider') - ->willReturn(new FinisherVariableProvider()); - - $mockAbstractFinisher->_set('finisherContext', $finisherContextMock); + $finisherContextMock->method('getFinisherVariableProvider')->willReturn(new FinisherVariableProvider()); - self::assertSame($expected, $mockAbstractFinisher->_call('parseOption', 'subject')); + $subject = new AbstractFinisherFixture(); + $subject->options = []; + $subject->defaultOptions = [ + 'subject' => 'defaultValue', + ]; + $subject->finisherContext = $finisherContextMock; + self::assertSame('defaultValue', $subject->parseOption('subject')); } #[Test] public function parseOptionReturnsDefaultOptionValueIfOptionValueIsAFormElementReferenceAndTheFormElementValueIsEmpty(): void { - $elementIdentifier = 'element-identifier-1'; - $expected = 'defaultValue'; - - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false, - false, - true, - [ - 'translateFinisherOption', - ] - ); - - $mockAbstractFinisher - ->method('translateFinisherOption') - ->willReturnArgument(0); - - $mockAbstractFinisher->_set('options', [ - 'subject' => '{' . $elementIdentifier . '}', - ]); - $mockAbstractFinisher->_set('defaultOptions', [ - 'subject' => $expected, - ]); - - $finisherContextMock = $this->createMock(FinisherContext::class); - - $formRuntimeMock = $this->createMock(FormRuntime::class); - $formRuntimeMock->method('offsetExists')->with($elementIdentifier)->willReturn(true); - $formRuntimeMock->method('offsetGet')->with($elementIdentifier)->willReturn(''); - - $finisherContextMock->method('getFormRuntime')->willReturn($formRuntimeMock); - - $mockAbstractFinisher->_set('finisherContext', $finisherContextMock); - - self::assertSame($expected, $mockAbstractFinisher->_call('parseOption', 'subject')); - } - - #[Test] - public function parseOptionResolvesFormElementReferenceFromTranslation(): void - { - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false, - false, - true, - [ - 'translateFinisherOption', - ] - ); - - $elementIdentifier = 'element-identifier-1'; - $elementValue = 'element-value-1'; - $elementReferenceName = '{' . $elementIdentifier . '}'; - - $translationValue = 'subject: ' . $elementReferenceName; - $expected = 'subject: ' . $elementValue; - - $mockAbstractFinisher - ->method('translateFinisherOption') - ->willReturn($translationValue); - - $mockAbstractFinisher->_set('options', [ - 'subject' => '', - ]); - $finisherContextMock = $this->createMock(FinisherContext::class); - $formRuntimeMock = $this->createMock(FormRuntime::class); - $formRuntimeMock->method('offsetExists')->with($elementIdentifier)->willReturn(true); - $formRuntimeMock->method('offsetGet')->with($elementIdentifier)->willReturn($elementValue); - + $formRuntimeMock->method('offsetExists')->with(self::anything())->willReturn(true); + $formRuntimeMock->method('offsetGet')->with(self::anything())->willReturn(''); $finisherContextMock->method('getFormRuntime')->willReturn($formRuntimeMock); - $mockAbstractFinisher->_set('finisherContext', $finisherContextMock); - - self::assertSame($expected, $mockAbstractFinisher->_call('parseOption', 'subject')); + $subject = new AbstractFinisherFixture(); + $subject->options = [ + 'subject' => '{element-identifier-1}', + ]; + $subject->defaultOptions = [ + 'subject' => 'defaultValue', + ]; + $subject->finisherContext = $finisherContextMock; + self::assertSame('defaultValue', $subject->parseOption('subject')); } #[Test] public function substituteRuntimeReferencesReturnsArrayIfInputIsArray(): void { - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false - ); - $formRuntimeMock = $this->createMock(FormRuntime::class); - $input = ['bar', 'foobar', ['x', 'y']]; $expected = ['bar', 'foobar', ['x', 'y']]; - - self::assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock)); + $subject = new AbstractFinisherFixture(); + self::assertSame($expected, $subject->substituteRuntimeReferences($input, $formRuntimeMock)); } #[Test] public function substituteRuntimeReferencesReturnsStringIfInputIsString(): void { - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false - ); - $formRuntimeMock = $this->createMock(FormRuntime::class); - $input = 'foobar'; $expected = 'foobar'; - - self::assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock)); + $subject = new AbstractFinisherFixture(); + self::assertSame($expected, $subject->substituteRuntimeReferences($input, $formRuntimeMock)); } #[Test] public function substituteRuntimeReferencesReturnsValueFromFormRuntimeIfInputReferenceAFormElementIdentifierWhoseValueIsAString(): void { - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false - ); - $elementIdentifier = 'element-identifier-1'; $input = '{' . $elementIdentifier . '}'; $expected = 'element-value'; - $formRuntimeMock = $this->createMock(FormRuntime::class); $formRuntimeMock->method('offsetExists')->with($elementIdentifier)->willReturn(true); $formRuntimeMock->method('offsetGet')->with($elementIdentifier)->willReturn($expected); - - self::assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock)); + $subject = new AbstractFinisherFixture(); + self::assertSame($expected, $subject->substituteRuntimeReferences($input, $formRuntimeMock)); } #[Test] public function substituteRuntimeReferencesReturnsValueFromFormRuntimeIfInputReferenceMultipleFormElementIdentifierWhoseValueIsAString(): void { - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false - ); - $elementIdentifier1 = 'element-identifier-1'; $elementValue1 = 'element-value-1'; $elementIdentifier2 = 'element-identifier-2'; $elementValue2 = 'element-value-2'; - $input = '{' . $elementIdentifier1 . '},{' . $elementIdentifier2 . '}'; $expected = $elementValue1 . ',' . $elementValue2; - $formRuntimeMock = $this->createMock(FormRuntime::class); $formRuntimeMock->method('offsetExists')->willReturnMap([ [$elementIdentifier1, true], @@ -299,46 +134,30 @@ public function substituteRuntimeReferencesReturnsValueFromFormRuntimeIfInputRef [$elementIdentifier1, $elementValue1], [$elementIdentifier2, $elementValue2], ]); - - self::assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock)); + $subject = new AbstractFinisherFixture(); + self::assertSame($expected, $subject->substituteRuntimeReferences($input, $formRuntimeMock)); } #[Test] public function substituteRuntimeReferencesReturnsValueFromFormRuntimeIfInputReferenceAFormElementIdentifierWhoseValueIsAnArray(): void { - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false - ); - $elementIdentifier = 'element-identifier-1'; $input = '{' . $elementIdentifier . '}'; $expected = ['bar', 'foobar']; - $formRuntimeMock = $this->createMock(FormRuntime::class); $formRuntimeMock->method('offsetExists')->with($elementIdentifier)->willReturn(true); $formRuntimeMock->method('offsetGet')->with($elementIdentifier)->willReturn($expected); - - self::assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock)); + $subject = new AbstractFinisherFixture(); + self::assertSame($expected, $subject->substituteRuntimeReferences($input, $formRuntimeMock)); } #[Test] public function substituteRuntimeReferencesReturnsValueFromFormRuntimeIfInputIsArrayAndSomeItemsReferenceAFormElementIdentifierWhoseValueIsAnArray(): void { - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false - ); - $elementIdentifier1 = 'element-identifier-1'; $elementValue1 = ['klaus', 'fritz']; $elementIdentifier2 = 'element-identifier-2'; $elementValue2 = ['stan', 'steve']; - $input = [ '{' . $elementIdentifier1 . '}', 'static value', @@ -357,7 +176,6 @@ public function substituteRuntimeReferencesReturnsValueFromFormRuntimeIfInputIsA ['stan', 'steve'], ], ]; - $formRuntimeMock = $this->createMock(FormRuntime::class); $formRuntimeMock->method('offsetExists')->willReturnMap([ [$elementIdentifier1, true], @@ -367,71 +185,43 @@ public function substituteRuntimeReferencesReturnsValueFromFormRuntimeIfInputIsA [$elementIdentifier1, $elementValue1], [$elementIdentifier2, $elementValue2], ]); - - self::assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock)); + $subject = new AbstractFinisherFixture(); + self::assertSame($expected, $subject->substituteRuntimeReferences($input, $formRuntimeMock)); } #[Test] public function substituteRuntimeReferencesReturnsNoReplacedValueIfInputReferenceANonExistingFormElement(): void { - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false - ); - $elementIdentifier = 'element-identifier-1'; $input = '{' . $elementIdentifier . '}'; $expected = '{' . $elementIdentifier . '}'; - $formRuntimeMock = $this->createMock(FormRuntime::class); $formRuntimeMock->method('offsetExists')->with($elementIdentifier)->willReturn(true); $formRuntimeMock->method('offsetGet')->with($elementIdentifier)->willReturn($expected); - $finisherContextMock = $this->createMock(FinisherContext::class); $finisherContextMock->method('getFinisherVariableProvider')->willReturn(new FinisherVariableProvider()); - $mockAbstractFinisher->_set('finisherContext', $finisherContextMock); - - self::assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock)); + $subject = new AbstractFinisherFixture(); + $subject->finisherContext = $finisherContextMock; + self::assertSame($expected, $subject->substituteRuntimeReferences($input, $formRuntimeMock)); } #[Test] public function substituteRuntimeReferencesReturnsTimestampIfInputIsATimestampRequestTrigger(): void { - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false - ); - $input = '{__currentTimestamp}'; $expected = '#^([0-9]{10})$#'; - $formRuntimeMock = $this->createMock(FormRuntime::class); - - self::assertMatchesRegularExpression( - $expected, - (string)$mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock) - ); + $subject = new AbstractFinisherFixture(); + self::assertMatchesRegularExpression($expected, (string)$subject->substituteRuntimeReferences($input, $formRuntimeMock)); } #[Test] public function substituteRuntimeReferencesReturnsResolvesElementIdentifiersInArrayKeys(): void { - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false - ); - $elementIdentifier1 = 'element-identifier-1'; $elementValue1 = 'norbert'; $elementIdentifier2 = 'element-identifier-2'; $elementValue2 = ['stan', 'steve']; - $input = [ '{' . $elementIdentifier1 . '}' => [ 'lisa', @@ -444,7 +234,6 @@ public function substituteRuntimeReferencesReturnsResolvesElementIdentifiersInAr ['stan', 'steve'], ], ]; - $formRuntimeMock = $this->createMock(FormRuntime::class); $formRuntimeMock->method('offsetExists')->willReturnMap([ [$elementIdentifier1, true], @@ -454,8 +243,8 @@ public function substituteRuntimeReferencesReturnsResolvesElementIdentifiersInAr [$elementIdentifier1, $elementValue1], [$elementIdentifier2, $elementValue2], ]); - - self::assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock)); + $subject = new AbstractFinisherFixture(); + self::assertSame($expected, $subject->substituteRuntimeReferences($input, $formRuntimeMock)); } #[Test] @@ -465,7 +254,6 @@ public function substituteRuntimeReferencesConvertsObjectsToString(): void $formRuntimeMock = $this->createMock(FormRuntime::class); $formRuntimeMock->method('offsetExists')->with('date-1')->willReturn(true); $formRuntimeMock->method('offsetGet')->with('date-1')->willReturn($date); - $stringableElement = new class () implements StringableFormElementInterface { /** * @param \DateTimeInterface $value @@ -478,20 +266,8 @@ public function valueToString($value): string $formDefinitionMock = $this->createMock(FormDefinition::class); $formDefinitionMock->method('getElementByIdentifier')->with('date-1')->willReturn($stringableElement); $formRuntimeMock->method('getFormDefinition')->willReturn($formDefinitionMock); - - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false - ); - $result = $mockAbstractFinisher->_call( - 'substituteRuntimeReferences', - 'When: {date-1}', - $formRuntimeMock - ); - - self::assertSame('When: 2019-11-22', $result); + $subject = new AbstractFinisherFixture(); + self::assertSame('When: 2019-11-22', $subject->substituteRuntimeReferences('When: {date-1}', $formRuntimeMock)); } #[Test] @@ -500,55 +276,25 @@ public function substituteRuntimeReferencesThrowsExceptionOnObjectWithoutStringa $formRuntimeMock = $this->createMock(FormRuntime::class); $formRuntimeMock->method('offsetExists')->with('date-1')->willReturn(true); $formRuntimeMock->method('offsetGet')->with('date-1')->willReturn(new \DateTime()); - $formDefinitionMock = $this->createMock(FormDefinition::class); $formRuntimeMock->method('getFormDefinition')->willReturn($formDefinitionMock); - - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false - ); - $this->expectException(FinisherException::class); $this->expectExceptionCode(1574362327); - - $mockAbstractFinisher->_call( - 'substituteRuntimeReferences', - 'When: {date-1}', - $formRuntimeMock - ); + $subject = new AbstractFinisherFixture(); + $subject->substituteRuntimeReferences('When: {date-1}', $formRuntimeMock); } #[Test] public function substituteRuntimeReferencesThrowsExceptionOnMultipleVariablesResolvedAsArray(): void { - $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass( - AbstractFinisher::class, - [], - '', - false - ); - $elementIdentifier = 'element-identifier-1'; $input = 'BEFORE {' . $elementIdentifier . '} AFTER'; - $formRuntimeMock = $this->createMock(FormRuntime::class); $formRuntimeMock->method('offsetExists')->with($elementIdentifier)->willReturn(true); $formRuntimeMock->method('offsetGet')->with($elementIdentifier)->willReturn(['value-1', 'value-2']); - - $finisherContextMock = $this->createMock(FinisherContext::class); - $finisherContextMock->method('getFinisherVariableProvider')->willReturn(new FinisherVariableProvider()); - $mockAbstractFinisher->_set('finisherContext', $finisherContextMock); - $this->expectException(FinisherException::class); $this->expectExceptionCode(1519239265); - - $mockAbstractFinisher->_call( - 'substituteRuntimeReferences', - $input, - $formRuntimeMock - ); + $subject = new AbstractFinisherFixture(); + $subject->substituteRuntimeReferences($input, $formRuntimeMock); } } diff --git a/typo3/sysext/form/Tests/Unit/Domain/Finishers/Fixtures/AbstractFinisherFixture.php b/typo3/sysext/form/Tests/Unit/Domain/Finishers/Fixtures/AbstractFinisherFixture.php new file mode 100644 index 000000000000..53eaeee6c5e3 --- /dev/null +++ b/typo3/sysext/form/Tests/Unit/Domain/Finishers/Fixtures/AbstractFinisherFixture.php @@ -0,0 +1,57 @@ +expectException(IdentifierNotValidException::class); $this->expectExceptionCode(1477082501); - - // Section inherits from AbstractSection and serves as concrete implementation - new Section('', 'foobar'); + new AbstractSectionFixture('', 'foobar'); } #[Test] public function constructMustNotThrowExceptionWhenIdentifierIsNonEmptyString(): void { - $section = new Section('foobar', 'foobar'); - self::assertInstanceOf(AbstractSection::class, $section); + $subject = new AbstractSectionFixture('foobar', ''); + self::assertInstanceOf(AbstractSection::class, $subject); } #[Test] public function createElementThrowsExceptionIfTypeDefinitionNotFoundAndSkipUnknownElementsIsFalse(): void { - $rootForm = $this->getMockBuilder(FormDefinition::class) - ->onlyMethods(['getRenderingOptions', 'getTypeDefinitions']) - ->disableOriginalConstructor() - ->getMock(); - $rootForm - ->method('getRenderingOptions') - ->willReturn(['skipUnknownElements' => false]); - $rootForm - ->method('getTypeDefinitions') - ->willReturn([]); - - $mockAbstractSection = $this->getAccessibleMockForAbstractClass( - AbstractSection::class, - [], - '', - false, - false, - true, - [ - 'getRootForm', - ] - ); - - $mockAbstractSection - ->expects(self::once()) - ->method('getRootForm') - ->willReturn($rootForm); - + $rootForm = $this->createMock(FormDefinition::class); $this->expectException(TypeDefinitionNotFoundException::class); $this->expectExceptionCode(1382364019); - - $mockAbstractSection->_call('createElement', '', ''); + $subject = new AbstractSectionFixture('identifier', ''); + $subject->setParentRenderable($rootForm); + $subject->createElement('', ''); } #[Test] public function createElementReturnsUnknownElementsIfTypeDefinitionIsNotFoundAndSkipUnknownElementsIsTrue(): void { - $rootForm = $this->getMockBuilder(FormDefinition::class) - ->onlyMethods(['getRenderingOptions', 'getTypeDefinitions']) - ->disableOriginalConstructor() - ->getMock(); - $rootForm - ->method('getRenderingOptions') - ->willReturn(['skipUnknownElements' => true]); - $rootForm - ->method('getTypeDefinitions') - ->willReturn([]); - $section = new TestingSection($rootForm); - + $rootForm = $this->createMock(FormDefinition::class); + $rootForm->method('getRenderingOptions')->willReturn(['skipUnknownElements' => true]); GeneralUtility::addInstance(UnknownFormElement::class, new UnknownFormElement('foo', 'bar')); - $result = $section->createElement('foo', 'bar'); - + $subject = new AbstractSectionFixture('testing', ''); + $subject->setParentRenderable($rootForm); + $result = $subject->createElement('foo', 'bar'); self::assertInstanceOf(UnknownFormElement::class, $result); self::assertSame('foo', $result->getIdentifier()); self::assertSame('bar', $result->getType()); @@ -114,89 +76,50 @@ public function createElementReturnsUnknownElementsIfTypeDefinitionIsNotFoundAnd #[Test] public function createElementThrowsExceptionIfTypeDefinitionIsNotSet(): void { - $rootForm = $this->getMockBuilder(FormDefinition::class) - ->onlyMethods(['getRenderingOptions', 'getTypeDefinitions']) - ->disableOriginalConstructor() - ->getMock(); - $rootForm - ->method('getRenderingOptions') - ->willReturn(['skipUnknownElements' => true]); - $rootForm - ->method('getTypeDefinitions') - ->willReturn(['foobar' => []]); - $section = new TestingSection($rootForm); - $this->expectException(TypeDefinitionNotFoundException::class); $this->expectExceptionCode(1325689855); - - $section->createElement('id', 'foobar'); + $rootForm = $this->createMock(FormDefinition::class); + $rootForm->method('getTypeDefinitions')->willReturn(['foobar' => []]); + $subject = new AbstractSectionFixture('testing', ''); + $subject->setParentRenderable($rootForm); + $subject->createElement('id', 'foobar'); } #[Test] public function createElementThrowsExceptionIfTypeDefinitionNotInstanceOfFormElementInterface(): void { - $rootForm = $this->getMockBuilder(FormDefinition::class) - ->onlyMethods(['getRenderingOptions', 'getTypeDefinitions']) - ->disableOriginalConstructor() - ->getMock(); - $rootForm - ->method('getRenderingOptions') - ->willReturn([]); - $rootForm - ->method('getTypeDefinitions') - ->willReturn( - [ - 'foobar' => [ - 'implementationClassName' => self::class, - ], - ] - ); - $section = new TestingSection($rootForm); - - GeneralUtility::addInstance(self::class, $this); - $this->expectException(TypeDefinitionNotValidException::class); $this->expectExceptionCode(1327318156); - $section->createElement('id', 'foobar'); + $rootForm = $this->createMock(FormDefinition::class); + $rootForm->method('getTypeDefinitions')->willReturn([ + 'foobar' => [ + 'implementationClassName' => self::class, + ], + ]); + $subject = new AbstractSectionFixture('testing', ''); + $subject->setParentRenderable($rootForm); + GeneralUtility::addInstance(self::class, $this); + $subject->createElement('id', 'foobar'); } #[Test] public function createElementExpectedToAddAndInitializeElement(): void { - $implementationMock = $this->createPartialMock(TestingFormElement::class, ['setOptions', 'initializeFormElement']); - + $implementationMock = $this->createMock(TestingFormElement::class); $typeDefinition = [ 'foo' => 'bar', 'implementationClassName' => get_class($implementationMock), 'fizz' => 'buzz', ]; - $typeDefinitionWithoutImplementationClassName = $typeDefinition; unset($typeDefinitionWithoutImplementationClassName['implementationClassName']); - - $implementationMock - ->expects(self::once()) - ->method('initializeFormElement'); - - $implementationMock - ->expects(self::once()) - ->method('setOptions') - ->with($typeDefinitionWithoutImplementationClassName); - - $rootForm = $this->getMockBuilder(FormDefinition::class) - ->onlyMethods(['getRenderingOptions', 'getTypeDefinitions']) - ->disableOriginalConstructor() - ->getMock(); - $rootForm - ->method('getRenderingOptions') - ->willReturn([]); - $rootForm - ->method('getTypeDefinitions') - ->willReturn(['foobar' => $typeDefinition]); - $section = new TestingSection($rootForm); - + $implementationMock->expects(self::once())->method('initializeFormElement'); + $implementationMock->expects(self::once())->method('setOptions')->with($typeDefinitionWithoutImplementationClassName); + $rootForm = $this->createMock(FormDefinition::class); + $rootForm->method('getTypeDefinitions')->willReturn(['foobar' => $typeDefinition]); + $subject = new AbstractSectionFixture('testing', ''); + $subject->setParentRenderable($rootForm); GeneralUtility::addInstance(get_class($implementationMock), $implementationMock); - - $section->createElement('id', 'foobar'); + $subject->createElement('id', 'foobar'); } } diff --git a/typo3/sysext/form/Tests/Unit/Domain/FormElements/Fixtures/TestingSection.php b/typo3/sysext/form/Tests/Unit/Domain/FormElements/Fixtures/AbstractSectionFixture.php similarity index 60% rename from typo3/sysext/form/Tests/Unit/Domain/FormElements/Fixtures/TestingSection.php rename to typo3/sysext/form/Tests/Unit/Domain/FormElements/Fixtures/AbstractSectionFixture.php index 3e19c2dcc471..7a6f5d36d1a5 100644 --- a/typo3/sysext/form/Tests/Unit/Domain/FormElements/Fixtures/TestingSection.php +++ b/typo3/sysext/form/Tests/Unit/Domain/FormElements/Fixtures/AbstractSectionFixture.php @@ -17,21 +17,6 @@ namespace TYPO3\CMS\Form\Tests\Unit\Domain\FormElements\Fixtures; -use TYPO3\CMS\Form\Domain\Model\FormDefinition; use TYPO3\CMS\Form\Domain\Model\FormElements\AbstractSection; -/** - * Testing subclass of the abstract class. - */ -class TestingSection extends AbstractSection -{ - public function __construct(private readonly FormDefinition $rootForm) - { - parent::__construct('testing_section', ''); - } - - public function getRootForm(): FormDefinition - { - return $this->rootForm; - } -} +final class AbstractSectionFixture extends AbstractSection {} diff --git a/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/AbstractMenuContentObjectTest.php b/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/AbstractMenuContentObjectTest.php index b3160646d405..5aa12651f600 100644 --- a/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/AbstractMenuContentObjectTest.php +++ b/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/AbstractMenuContentObjectTest.php @@ -20,8 +20,6 @@ use Doctrine\DBAL\Result; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; -use PHPUnit\Framework\MockObject\MockObject; -use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface; use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Context\LanguageAspect; use TYPO3\CMS\Core\Database\Connection; @@ -32,31 +30,24 @@ use TYPO3\CMS\Core\Http\ServerRequest; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; -use TYPO3\CMS\Frontend\ContentObject\Menu\AbstractMenuContentObject; use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; use TYPO3\CMS\Frontend\Page\PageInformation; -use TYPO3\TestingFramework\Core\AccessibleObjectInterface; +use TYPO3\CMS\Frontend\Tests\Unit\ContentObject\Menu\Fixtures\AbstractMenuContentObjectFixture; use TYPO3\TestingFramework\Core\Unit\UnitTestCase; final class AbstractMenuContentObjectTest extends UnitTestCase { - protected AbstractMenuContentObject&MockObject&AccessibleObjectInterface $subject; - protected function tearDown(): void { GeneralUtility::purgeInstances(); parent::tearDown(); } - /** - * Prepares a test for the method sectionIndex - */ - protected function prepareSectionIndexTest(): void + private function prepareSectionIndexTest(): void { $connectionMock = $this->createMock(Connection::class); $connectionMock->method('getExpressionBuilder')->willReturn(new ExpressionBuilder($connectionMock)); $connectionMock->method('quoteIdentifier')->willReturnArgument(0)->withAnyParameters(); - $connectionPoolMock = $this->createMock(ConnectionPool::class); $connectionPoolMock->method('getConnectionForTable')->with('tt_content')->willReturn($connectionMock); GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolMock); @@ -66,25 +57,23 @@ protected function prepareSectionIndexTest(): void public function sectionIndexReturnsEmptyArrayIfTheRequestedPageCouldNotBeFetched(): void { $this->prepareSectionIndexTest(); - $pageRepository = $this->getMockBuilder(PageRepository::class)->disableOriginalConstructor()->getMock(); + $pageRepository = $this->createMock(PageRepository::class); $pageRepository->expects(self::once())->method('getPage')->willReturn([]); - $this->subject = $this->getAccessibleMockForAbstractClass(AbstractMenuContentObject::class); - $this->subject->_set('sys_page', $pageRepository); - $result = $this->subject->_call('sectionIndex', 'field'); - self::assertEquals([], $result); + $subject = new AbstractMenuContentObjectFixture(); + $subject->sys_page = $pageRepository; + self::assertEquals([], $subject->sectionIndex('field')); } #[Test] public function sectionIndexUsesTheInternalIdIfNoPageIdWasGiven(): void { $this->prepareSectionIndexTest(); - $pageRepository = $this->getMockBuilder(PageRepository::class)->disableOriginalConstructor()->getMock(); + $pageRepository = $this->createMock(PageRepository::class); $pageRepository->expects(self::once())->method('getPage')->with(10)->willReturn([]); - $this->subject = $this->getAccessibleMockForAbstractClass(AbstractMenuContentObject::class); - $this->subject->_set('sys_page', $pageRepository); - $this->subject->_set('id', 10); - $result = $this->subject->_call('sectionIndex', 'field'); - self::assertEquals([], $result); + $subject = new AbstractMenuContentObjectFixture(); + $subject->sys_page = $pageRepository; + $subject->id = 10; + self::assertEquals([], $subject->sectionIndex('field')); } #[Test] @@ -93,45 +82,39 @@ public function sectionIndexThrowsAnExceptionIfTheInternalQueryFails(): void $this->expectException(\UnexpectedValueException::class); $this->expectExceptionCode(1337334849); $this->prepareSectionIndexTest(); - $pageRepository = $this->getMockBuilder(PageRepository::class)->disableOriginalConstructor()->getMock(); + $pageRepository = $this->createMock(PageRepository::class); $pageRepository->expects(self::once())->method('getPage')->willReturn(['uid' => 10]); - $this->subject = $this->getAccessibleMockForAbstractClass(AbstractMenuContentObject::class); - $this->subject->_set('sys_page', $pageRepository); - $this->subject->_set('id', 10); - - $cObject = $this->getMockBuilder(ContentObjectRenderer::class)->disableOriginalConstructor()->getMock(); + $cObject = $this->createMock(ContentObjectRenderer::class); $cObject->expects(self::once())->method('exec_getQuery')->willReturn(0); - $this->subject->_set('parent_cObj', $cObject); - - $this->subject->_call('sectionIndex', 'field'); + $subject = new AbstractMenuContentObjectFixture(); + $subject->sys_page = $pageRepository; + $subject->id = 10; + $subject->parent_cObj = $cObject; + $subject->sectionIndex('field'); } #[Test] public function sectionIndexReturnsOverlaidRowBasedOnTheLanguageOfTheGivenPage(): void { + $this->prepareSectionIndexTest(); $statementMock = $this->createMock(Result::class); $statementMock->expects(self::exactly(2))->method('fetchAssociative')->willReturn(['uid' => 0, 'header' => 'NOT_OVERLAID'], false); - - $this->prepareSectionIndexTest(); - $this->subject = $this->getAccessibleMockForAbstractClass(AbstractMenuContentObject::class); - $this->subject->_set('mconf', [ + $subject = new AbstractMenuContentObjectFixture(); + $subject->mconf = [ 'sectionIndex.' => [ 'type' => 'all', ], - ]); + ]; $context = GeneralUtility::makeInstance(Context::class); $context->setAspect('language', new LanguageAspect(1, 1, LanguageAspect::OVERLAYS_MIXED)); - $pageRepository = $this->getMockBuilder(PageRepository::class)->setConstructorArgs([$context])->onlyMethods(['init', 'getPage', 'getLanguageOverlay'])->getMock(); $pageRepository->expects(self::once())->method('getPage')->willReturn(['sys_language_uid' => 1]); $pageRepository->expects(self::once())->method('getLanguageOverlay')->willReturn(['uid' => 0, 'header' => 'OVERLAID']); - $this->subject->_set('sys_page', $pageRepository); - - $cObject = $this->getMockBuilder(ContentObjectRenderer::class)->getMock(); + $subject->sys_page = $pageRepository; + $cObject = $this->createMock(ContentObjectRenderer::class); $cObject->expects(self::once())->method('exec_getQuery')->willReturn($statementMock); - $this->subject->_set('parent_cObj', $cObject); - - $result = $this->subject->_call('sectionIndex', 'field'); + $subject->parent_cObj = $cObject; + $result = $subject->sectionIndex('field'); self::assertEquals('OVERLAID', $result[0]['title']); } @@ -177,28 +160,23 @@ public static function sectionIndexFiltersDataProvider(): array #[Test] public function sectionIndexFilters(int $expectedAmount, array $dataRow): void { + $this->prepareSectionIndexTest(); $statementMock = $this->createMock(Result::class); $statementMock->method('fetchAssociative')->willReturn($dataRow, false); - - $this->prepareSectionIndexTest(); - $this->subject = $this->getAccessibleMockForAbstractClass(AbstractMenuContentObject::class); - $this->subject->_set('mconf', [ + $subject = new AbstractMenuContentObjectFixture(); + $subject->mconf = [ 'sectionIndex.' => [ 'type' => 'header', ], - ]); - - $pageRepository = $this->getMockBuilder(PageRepository::class)->disableOriginalConstructor()->getMock(); + ]; + $pageRepository = $this->createMock(PageRepository::class); $pageRepository->expects(self::once())->method('getPage')->willReturn(['sys_language_uid' => 1]); $pageRepository->expects(self::once())->method('getPage')->willReturn([]); - $this->subject->_set('sys_page', $pageRepository); - - $cObject = $this->getMockBuilder(ContentObjectRenderer::class)->getMock(); + $subject->sys_page = $pageRepository; + $cObject = $this->createMock(ContentObjectRenderer::class); $cObject->expects(self::once())->method('exec_getQuery')->willReturn($statementMock); - $this->subject->_set('parent_cObj', $cObject); - - $result = $this->subject->_call('sectionIndex', 'field'); - self::assertCount($expectedAmount, $result); + $subject->parent_cObj = $cObject; + self::assertCount($expectedAmount, $subject->sectionIndex('field')); } public static function sectionIndexQueriesWithDifferentColPosDataProvider(): array @@ -239,38 +217,25 @@ public static function sectionIndexQueriesWithDifferentColPosDataProvider(): arr #[Test] public function sectionIndexQueriesWithDifferentColPos(array $configuration, string $colPosFromStdWrapValue, string $whereClausePrefix): void { + $this->prepareSectionIndexTest(); $statementMock = $this->createMock(Result::class); $statementMock->method('fetchAssociative')->willReturn([]); - - $this->prepareSectionIndexTest(); - $this->subject = $this->getAccessibleMockForAbstractClass(AbstractMenuContentObject::class); - $this->subject->_set('mconf', ['sectionIndex.' => $configuration]); - + $subject = new AbstractMenuContentObjectFixture(); + $subject->mconf = ['sectionIndex.' => $configuration]; $pageRepository = $this->getMockBuilder(PageRepository::class)->disableOriginalConstructor()->getMock(); $pageRepository->expects(self::once())->method('getPage')->willReturn(['uid' => 12]); - $this->subject->_set('sys_page', $pageRepository); - + $subject->sys_page = $pageRepository; $queryConfiguration = [ 'pidInList' => 12, 'orderBy' => 'field', 'languageField' => 'sys_language_uid', 'where' => $whereClausePrefix, ]; - - $cObject = $this->getMockBuilder(ContentObjectRenderer::class)->getMock(); - $cObject - ->expects(self::once()) - ->method('stdWrapValue') - ->with('useColPos', $configuration) - ->willReturn($colPosFromStdWrapValue); - $cObject - ->expects(self::once()) - ->method('exec_getQuery') - ->with('tt_content', $queryConfiguration) - ->willReturn($statementMock); - $this->subject->parent_cObj = $cObject; - - $this->subject->_call('sectionIndex', 'field', 12); + $cObject = $this->createMock(ContentObjectRenderer::class); + $cObject->expects(self::once())->method('stdWrapValue')->with('useColPos', $configuration)->willReturn($colPosFromStdWrapValue); + $cObject->expects(self::once())->method('exec_getQuery')->with('tt_content', $queryConfiguration)->willReturn($statementMock); + $subject->parent_cObj = $cObject; + $subject->sectionIndex('field', 12); } public static function isItemStateChecksExcludeUidListDataProvider(): array @@ -360,41 +325,26 @@ public static function isItemStateChecksExcludeUidListDataProvider(): array #[Test] public function isItemStateChecksExcludeUidList(array $menuItems, string $excludeUidList, bool $expectedResult): void { - $subject = $this->getAccessibleMockForAbstractClass(AbstractMenuContentObject::class, [], '', true, true, true, ['getRuntimeCache']); + $this->prepareSectionIndexTest(); $request = new ServerRequest(); $pageInformation = new PageInformation(); $pageInformation->setPageRecord([]); $request = $request->withAttribute('frontend.page.information', $pageInformation); - $subject->_set('request', $request); - - $runtimeCacheMock = $this->getMockBuilder(FrontendInterface::class)->getMock(); - $runtimeCacheMock->method('get')->with(self::anything())->willReturn(false); - $runtimeCacheMock->method('set')->with(self::anything()); - $subject->method('getRuntimeCache')->willReturn($runtimeCacheMock); - - $cObjectMock = $this->getMockBuilder(ContentObjectRenderer::class)->getMock(); - $cObjectMock - ->expects(self::once()) - ->method('stdWrapValue') - ->with('excludeUidList', ['excludeUidList' => $excludeUidList]) - ->willReturn($excludeUidList); - + $subject = new AbstractMenuContentObjectFixture(); + $subject->request = $request; + $cObjectMock = $this->createMock(ContentObjectRenderer::class); + $cObjectMock->expects(self::once())->method('stdWrapValue')->with('excludeUidList', ['excludeUidList' => $excludeUidList])->willReturn($excludeUidList); $typoScriptFrontendControllerMock = $this->createMock(TypoScriptFrontendController::class); $cObjectMock->method('getTypoScriptFrontendController')->willReturn($typoScriptFrontendControllerMock); - $subject->parent_cObj = $cObjectMock; - - $this->prepareSectionIndexTest(); - - $pageRepository = $this->getMockBuilder(PageRepository::class)->disableOriginalConstructor()->getMock(); + $pageRepository = $this->createMock(PageRepository::class); $pageRepository->expects(self::once())->method('getMenu')->willReturn($menuItems); - $subject->_set('sys_page', $pageRepository); - $subject->_set('menuArr', [ + $subject->sys_page = $pageRepository; + $subject->menuArr = [ 0 => ['uid' => 42], - ]); - $subject->_set('conf', ['excludeUidList' => $excludeUidList]); - - self::assertEquals($expectedResult, $subject->_call('isItemState', 'IFSUB', 0)); + ]; + $subject->conf = ['excludeUidList' => $excludeUidList]; + self::assertEquals($expectedResult, $subject->isItemState('IFSUB', 0)); } public static function menuTypoLinkCreatesExpectedTypoLinkConfigurationDataProvider(): array @@ -559,13 +509,11 @@ public static function menuTypoLinkCreatesExpectedTypoLinkConfigurationDataProvi public function menuTypoLinkCreatesExpectedTypoLinkConfiguration(array $expected, array $mconf, array $page, string $oTarget, string|int $addParams = '', string|int $typeOverride = '', int|string|null $overrideId = null): void { $expected['page'] = new Page($page); - $cObject = $this->getMockBuilder(ContentObjectRenderer::class) - ->onlyMethods(['createLink']) - ->getMock(); + $cObject = $this->createMock(ContentObjectRenderer::class); $cObject->expects(self::once())->method('createLink')->with('|', $expected); - $this->subject = $this->getAccessibleMockForAbstractClass(AbstractMenuContentObject::class); - $this->subject->_set('parent_cObj', $cObject); - $this->subject->_set('mconf', $mconf); - $this->subject->_call('menuTypoLink', $page, $oTarget, $addParams, $typeOverride, $overrideId); + $subject = new AbstractMenuContentObjectFixture(); + $subject->parent_cObj = $cObject; + $subject->mconf = $mconf; + $subject->menuTypoLink($page, $oTarget, $addParams, $typeOverride, $overrideId); } } diff --git a/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/Fixtures/AbstractMenuContentObjectFixture.php b/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/Fixtures/AbstractMenuContentObjectFixture.php new file mode 100644 index 000000000000..4b8638246578 --- /dev/null +++ b/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/Fixtures/AbstractMenuContentObjectFixture.php @@ -0,0 +1,52 @@ +createMockedLoggerAndLogManager(); - $this->frontendControllerMock = $this - ->getMockBuilder(TypoScriptFrontendController::class) - ->disableOriginalConstructor() - ->getMock(); - } - - ////////////////////// - // Utility functions - ////////////////////// - /** - * Avoid logging to the file system (file writer is currently the only configured writer) - */ - protected function createMockedLoggerAndLogManager(): void - { $logManagerMock = $this->getMockBuilder(LogManager::class)->getMock(); $loggerMock = $this->getMockBuilder(LoggerInterface::class)->getMock(); - $logManagerMock - ->method('getLogger') - ->willReturn($loggerMock); + $logManagerMock->method('getLogger')->willReturn($loggerMock); GeneralUtility::setSingletonInstance(LogManager::class, $logManagerMock); } - /** - * @return array The test data for forceAbsoluteUrlReturnsAbsoluteUrl - */ public static function forceAbsoluteUrlReturnsCorrectAbsoluteUrlDataProvider(): array { return [ @@ -164,28 +139,13 @@ public static function forceAbsoluteUrlReturnsCorrectAbsoluteUrlDataProvider(): ]; } - /** - * @param string $expected The expected URL - * @param string $url The URL to parse and manipulate - * @param array $configuration The configuration array - */ #[DataProvider('forceAbsoluteUrlReturnsCorrectAbsoluteUrlDataProvider')] #[Test] public function forceAbsoluteUrlReturnsCorrectAbsoluteUrl(string $expected, string $url, array $configuration): void { - Environment::initialize( - Environment::getContext(), - true, - false, - Environment::getProjectPath(), - Environment::getPublicPath(), - Environment::getVarPath(), - Environment::getConfigPath(), - Environment::getPublicPath() . '/index.php', - Environment::isWindows() ? 'WINDOWS' : 'UNIX' - ); - $this->frontendControllerMock->absRefPrefix = ''; - $cObj = new ContentObjectRenderer($this->frontendControllerMock, new Container()); + $frontendControllerMock = $this->createMock(TypoScriptFrontendController::class); + $frontendControllerMock->absRefPrefix = ''; + $cObj = new ContentObjectRenderer($frontendControllerMock, new Container()); // Force hostname $serverRequest = new ServerRequest( 'http://localhost/index.php', @@ -195,31 +155,15 @@ public function forceAbsoluteUrlReturnsCorrectAbsoluteUrl(string $expected, stri ['HTTP_HOST' => 'localhost', 'SCRIPT_NAME' => '/index.php'] ); $cObj->setRequest($serverRequest); - $subject = $this->getAccessibleMock( - AbstractTypolinkBuilder::class, - ['build'], - [$cObj, $this->frontendControllerMock] - ); - - self::assertEquals($expected, $subject->_call('forceAbsoluteUrl', $url, $configuration)); + $subject = new AbstractTypolinkBuilderFixture($cObj, $frontendControllerMock); + self::assertEquals($expected, $subject->forceAbsoluteUrl($url, $configuration)); } #[Test] public function forceAbsoluteUrlReturnsCorrectAbsoluteUrlWithSubfolder(): void { - Environment::initialize( - Environment::getContext(), - true, - false, - Environment::getProjectPath(), - Environment::getPublicPath(), - Environment::getVarPath(), - Environment::getConfigPath(), - Environment::getPublicPath() . '/index.php', - Environment::isWindows() ? 'WINDOWS' : 'UNIX' - ); - $cObj = new ContentObjectRenderer($this->frontendControllerMock, new Container()); - + $frontendControllerMock = $this->createMock(TypoScriptFrontendController::class); + $cObj = new ContentObjectRenderer($frontendControllerMock, new Container()); // Force hostname $serverRequest = new ServerRequest( 'http://localhost/subfolder/index.php', @@ -229,26 +173,15 @@ public function forceAbsoluteUrlReturnsCorrectAbsoluteUrlWithSubfolder(): void ['HTTP_HOST' => 'localhost', 'SCRIPT_NAME' => '/subfolder/index.php'] ); $cObj->setRequest($serverRequest); - $subject = $this->getAccessibleMock( - AbstractTypolinkBuilder::class, - ['build'], - [$cObj, $this->frontendControllerMock] - ); - + $subject = new AbstractTypolinkBuilderFixture($cObj, $frontendControllerMock); $expected = 'http://localhost/subfolder/fileadmin/my.pdf'; $url = 'fileadmin/my.pdf'; $configuration = [ 'forceAbsoluteUrl' => '1', ]; - - self::assertEquals($expected, $subject->_call('forceAbsoluteUrl', $url, $configuration)); + self::assertEquals($expected, $subject->forceAbsoluteUrl($url, $configuration)); } - /** - * Data provider for resolveTargetAttribute - * - * @return array [[$expected, $conf, $name],] - */ public static function resolveTargetAttributeDataProvider(): array { $targetName = StringUtility::getUniqueId('name_'); @@ -256,23 +189,23 @@ public static function resolveTargetAttributeDataProvider(): array return [ 'Take target from $conf, if $conf[$targetName] is set.' => [ - $target, - [$targetName => $target], // $targetName is set - $targetName, + 'expected' => $target, + 'conf' => [$targetName => $target], // $targetName is set + 'name' => $targetName, ], ' If all hopes fail, an empty string is returned. ' => [ - '', - [], - $targetName, + 'expected' => '', + 'conf' => [], + 'name' => $targetName, ], 'It finally applies stdWrap' => [ - 'wrap_target', - [$targetName . '.' => + 'expected' => 'wrap_target', + 'conf' => [$targetName . '.' => [ 'ifEmpty' => 'wrap_target' ], ], - $targetName, + 'name' => $targetName, ], ]; } @@ -284,7 +217,8 @@ public function canResolveTheTargetAttribute( array $conf, string $name, ): void { - $cObj = new ContentObjectRenderer($this->frontendControllerMock, new Container()); + $frontendControllerMock = $this->createMock(TypoScriptFrontendController::class); + $cObj = new ContentObjectRenderer($frontendControllerMock, new Container()); $serverRequest = new ServerRequest( 'http://localhost/subfolder/index.php', 'GET', @@ -296,12 +230,7 @@ public function canResolveTheTargetAttribute( $container = new Container(); $container->set(EventDispatcherInterface::class, new NoopEventDispatcher()); GeneralUtility::setContainer($container); - $subject = $this->getAccessibleMockForAbstractClass(AbstractTypolinkBuilder::class, [$cObj, $this->frontendControllerMock]); - $actual = $subject->_call( - 'resolveTargetAttribute', - $conf, - $name, - ); - self::assertEquals($expected, $actual); + $subject = new AbstractTypolinkBuilderFixture($cObj, $frontendControllerMock); + self::assertEquals($expected, $subject->resolveTargetAttribute($conf, $name)); } } diff --git a/typo3/sysext/frontend/Tests/Unit/Typolink/Fixtures/AbstractTypolinkBuilderFixture.php b/typo3/sysext/frontend/Tests/Unit/Typolink/Fixtures/AbstractTypolinkBuilderFixture.php new file mode 100644 index 000000000000..4f168a5223e2 --- /dev/null +++ b/typo3/sysext/frontend/Tests/Unit/Typolink/Fixtures/AbstractTypolinkBuilderFixture.php @@ -0,0 +1,40 @@ +getAccessibleMockForAbstractClass(AbstractCoreMatcher::class, [], '', false); + $subject = new AbstractCoreMatcherFixture(); $configuration = [ 'foo/bar->baz' => [ 'requiredArg1' => 42, @@ -35,14 +35,14 @@ public function validateMatcherDefinitionsRunsFineWithProperDefinition(): void ], ], ]; - $matcher->_set('matcherDefinitions', $configuration); - $matcher->_call('validateMatcherDefinitions', ['requiredArg1']); + $subject->matcherDefinitions = $configuration; + $subject->validateMatcherDefinitions(['requiredArg1']); } #[Test] public function validateMatcherDefinitionsThrowsIfRequiredArgIsNotInConfig(): void { - $matcher = $this->getAccessibleMockForAbstractClass(AbstractCoreMatcher::class, [], '', false); + $subject = new AbstractCoreMatcherFixture(); $configuration = [ 'foo/bar->baz' => [ 'someNotRequiredConfig' => '', @@ -51,31 +51,31 @@ public function validateMatcherDefinitionsThrowsIfRequiredArgIsNotInConfig(): vo ], ], ]; - $matcher->_set('matcherDefinitions', $configuration); + $subject->matcherDefinitions = $configuration; $this->expectException(\InvalidArgumentException::class); $this->expectExceptionCode(1500492001); - $matcher->_call('validateMatcherDefinitions', ['requiredArg1']); + $subject->validateMatcherDefinitions(['requiredArg1']); } #[Test] public function validateMatcherDefinitionsThrowsWithMissingRestFiles(): void { - $matcher = $this->getAccessibleMockForAbstractClass(AbstractCoreMatcher::class, [], '', false); + $subject = new AbstractCoreMatcherFixture(); $configuration = [ 'foo/bar->baz' => [ 'restFiles' => [], ], ]; - $matcher->_set('matcherDefinitions', $configuration); + $subject->matcherDefinitions = $configuration; $this->expectException(\InvalidArgumentException::class); $this->expectExceptionCode(1500496068); - $matcher->_call('validateMatcherDefinitions', []); + $subject->validateMatcherDefinitions([]); } #[Test] public function validateMatcherDefinitionsThrowsWithEmptySingleRestFile(): void { - $matcher = $this->getAccessibleMockForAbstractClass(AbstractCoreMatcher::class, [], '', false); + $subject = new AbstractCoreMatcherFixture(); $configuration = [ 'foo/bar->baz' => [ 'restFiles' => [ @@ -84,24 +84,24 @@ public function validateMatcherDefinitionsThrowsWithEmptySingleRestFile(): void ], ], ]; - $matcher->_set('matcherDefinitions', $configuration); + $subject->matcherDefinitions = $configuration; $this->expectException(\InvalidArgumentException::class); $this->expectExceptionCode(1500735983); - $matcher->_call('validateMatcherDefinitions', []); + $subject->validateMatcherDefinitions([]); } #[Test] public function initializeMethodNameArrayThrowsWithInvalidKeys(): void { - $matcher = $this->getAccessibleMockForAbstractClass(AbstractCoreMatcher::class, [], '', false); + $subject = new AbstractCoreMatcherFixture(); $configuration = [ 'no\method\given' => [ 'restFiles' => [], ], ]; - $matcher->_set('matcherDefinitions', $configuration); + $subject->matcherDefinitions = $configuration; $this->expectException(\RuntimeException::class); $this->expectExceptionCode(1500557309); - $matcher->_call('initializeFlatMatcherDefinitions'); + $subject->initializeFlatMatcherDefinitions(); } } diff --git a/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/Fixtures/AbstractCoreMatcherFixture.php b/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/Fixtures/AbstractCoreMatcherFixture.php new file mode 100644 index 000000000000..d5a597b03319 --- /dev/null +++ b/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/Fixtures/AbstractCoreMatcherFixture.php @@ -0,0 +1,35 @@ +