Skip to content

Commit

Permalink
[TASK] Refactor ViewHelper tests
Browse files Browse the repository at this point in the history
We have a decent test coverage of view helpers, especially
those within ext:fluid. This is an important asset and we're
sure all main functionality works.

Most of the tests rely on ViewHelperBaseTestcase from the
testing framework. This class prepares the main mocking
of view helper dependencies. Reading the code it becomes
obvious that this approach is kinda unfortunate: View
helpers are part of a bigger system - they have some
general dependencies like the rendering context, the
request and render children. This leads to a mocking
party in many unit tests, making the test goal hard to
understand and follow.
The mock preparations and assumptions of internal handling
actively block further separation of concern patches
within ext:fluid since the ViewHelperBaseTestcase breaks
all the time.

The patch refactors all unit tests that extend
ViewHelperBaseTestcase towards functional tests:
Most of them simply create a StandaloneView, feed a
template string for the specific view helper and
string compare the render result. Some FE related VH
tests additionally set up a full frontend and retrieve
a rendered fluid view as sub request.

This makes the tests much easier to read, follow and
understand. The functional tests are now good examples
to show the various features of single VH's.

Change-Id: I6c5d4eeb0c79ba66a18398a5623a591381a6d707
Resolves: #94580
Releases: master
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/69857
Tested-by: core-ci <typo3@b13.com>
Tested-by: Jochen <rothjochen@gmail.com>
Tested-by: Benni Mack <benni@typo3.org>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Jochen <rothjochen@gmail.com>
Reviewed-by: Benni Mack <benni@typo3.org>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
  • Loading branch information
lolli42 committed Jul 19, 2021
1 parent 53bbf19 commit ad3a216
Show file tree
Hide file tree
Showing 116 changed files with 4,488 additions and 8,444 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

namespace TYPO3\CMS\Core\Tests\Functional\ViewHelpers;

use Prophecy\Argument;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Fluid\View\StandaloneView;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;

class IconForRecordViewHelperTest extends FunctionalTestCase
{
/**
* @test
*/
public function renderRendersIconCallingIconFactoryAccordingToGivenArguments(): void
{
$iconProphecy = $this->prophesize(Icon::class);
$iconProphecy->render(Argument::any())->willReturn('icon html');
$iconFactoryProphecy = $this->prophesize(IconFactory::class);
$iconFactoryProphecy->getIconForRecord(Argument::cetera())->willReturn($iconProphecy->reveal());
GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());

$view = new StandaloneView();
$view->setTemplateSource('<core:iconForRecord table="tt_content" row="{uid: 123}" size="large" alternativeMarkupIdentifier="inline" />');
$view->render();

$iconFactoryProphecy->getIconForRecord('tt_content', ['uid' => 123], Icon::SIZE_LARGE)->shouldHaveBeenCalled();
$iconProphecy->render('inline')->shouldHaveBeenCalled();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,122 +15,79 @@
* The TYPO3 project - inspiring people to share!
*/

namespace TYPO3\CMS\Core\Tests\Unit\ViewHelpers;
namespace TYPO3\CMS\Core\Tests\Functional\ViewHelpers;

use Prophecy\Argument;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Type\Icon\IconState;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\ViewHelpers\IconViewHelper;
use TYPO3\TestingFramework\Fluid\Unit\ViewHelpers\ViewHelperBaseTestcase;
use TYPO3\CMS\Fluid\View\StandaloneView;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;

/**
* Test case
*/
class IconViewHelperTest extends ViewHelperBaseTestcase
class IconViewHelperTest extends FunctionalTestCase
{
/**
* @var IconViewHelper
*/
protected $viewHelper;

protected function setUp(): void
{
parent::setUp();
$this->viewHelper = $this->getAccessibleMock(IconViewHelper::class, ['renderChildren']);
$this->injectDependenciesIntoViewHelper($this->viewHelper);
$this->viewHelper->initializeArguments();
}

/**
* @test
*/
public function renderCallsIconFactoryWithDefaultSizeAndDefaultStateAndReturnsResult()
public function renderCallsIconFactoryWithDefaultSizeAndDefaultStateAndReturnsResult(): void
{
$iconFactoryProphecy = $this->prophesize(IconFactory::class);
GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
$iconProphecy = $this->prophesize(Icon::class);

$iconFactoryProphecy->getIcon('myIdentifier', Icon::SIZE_SMALL, null, IconState::cast(IconState::STATE_DEFAULT))->shouldBeCalled()->willReturn($iconProphecy->reveal());
$iconProphecy->render(null)->shouldBeCalled()->willReturn('htmlFoo');

$this->viewHelper->setArguments([
'identifier' => 'myIdentifier',
'size' => Icon::SIZE_SMALL,
'overlay' => null,
'state' => IconState::cast(IconState::STATE_DEFAULT),
'alternativeMarkupIdentifier' => null
]);

self::assertSame('htmlFoo', $this->viewHelper->render());
$view = new StandaloneView();
$view->setTemplateSource('<core:icon identifier="myIdentifier" size="small" state="default" />');
self::assertSame('htmlFoo', $view->render());
}

/**
* @test
*/
public function renderCallsIconFactoryWithGivenSizeAndReturnsResult()
public function renderCallsIconFactoryWithGivenSizeAndReturnsResult(): void
{
$iconFactoryProphecy = $this->prophesize(IconFactory::class);
GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
$iconProphecy = $this->prophesize(Icon::class);

$iconFactoryProphecy->getIcon('myIdentifier', Icon::SIZE_LARGE, null, IconState::cast(IconState::STATE_DEFAULT))->shouldBeCalled()->willReturn($iconProphecy->reveal());
$iconProphecy->render(null)->shouldBeCalled()->willReturn('htmlFoo');

$this->viewHelper->setArguments([
'identifier' => 'myIdentifier',
'size' => Icon::SIZE_LARGE,
'overlay' => null,
'state' => IconState::cast(IconState::STATE_DEFAULT),
'alternativeMarkupIdentifier' => null
]);

self::assertSame('htmlFoo', $this->viewHelper->render());
$view = new StandaloneView();
$view->setTemplateSource('<core:icon identifier="myIdentifier" size="large" state="default" />');
self::assertSame('htmlFoo', $view->render());
}

/**
* @test
*/
public function renderCallsIconFactoryWithGivenStateAndReturnsResult()
public function renderCallsIconFactoryWithGivenStateAndReturnsResult(): void
{
$iconFactoryProphecy = $this->prophesize(IconFactory::class);
GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
$iconProphecy = $this->prophesize(Icon::class);

$iconFactoryProphecy->getIcon('myIdentifier', Icon::SIZE_SMALL, null, IconState::cast(IconState::STATE_DISABLED))->shouldBeCalled()->willReturn($iconProphecy->reveal());
$iconProphecy->render(null)->shouldBeCalled()->willReturn('htmlFoo');

$this->viewHelper->setArguments([
'identifier' => 'myIdentifier',
'size' => Icon::SIZE_SMALL,
'overlay' => null,
'state' => IconState::cast(IconState::STATE_DISABLED),
'alternativeMarkupIdentifier' => null
]);

self::assertSame('htmlFoo', $this->viewHelper->render());
$view = new StandaloneView();
$view->setTemplateSource('<core:icon identifier="myIdentifier" size="small" state="disabled" />');
self::assertSame('htmlFoo', $view->render());
}

/**
* @test
*/
public function renderCallsIconFactoryWithGivenOverlayAndReturnsResult()
public function renderCallsIconFactoryWithGivenOverlayAndReturnsResult(): void
{
$iconFactoryProphecy = $this->prophesize(IconFactory::class);
GeneralUtility::addInstance(IconFactory::class, $iconFactoryProphecy->reveal());
$iconProphecy = $this->prophesize(Icon::class);

$iconFactoryProphecy->getIcon('myIdentifier', Argument::any(), 'overlayString', IconState::cast(IconState::STATE_DEFAULT))->shouldBeCalled()->willReturn($iconProphecy->reveal());
$iconProphecy->render(null)->shouldBeCalled()->willReturn('htmlFoo');

$this->viewHelper->setArguments([
'identifier' => 'myIdentifier',
'size' => Icon::SIZE_LARGE,
'overlay' => 'overlayString',
'state' => IconState::cast(IconState::STATE_DEFAULT),
'alternativeMarkupIdentifier' => null
]);
self::assertSame('htmlFoo', $this->viewHelper->render());
$view = new StandaloneView();
$view->setTemplateSource('<core:icon identifier="myIdentifier" size="large" state="default" overlay="overlayString" />');
self::assertSame('htmlFoo', $view->render());
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 CMS project.
*
Expand All @@ -22,9 +24,7 @@ class EscapeChildrenRenderingStandaloneTest extends FunctionalTestCase
{
protected $testExtensionsToLoad = ['typo3/sysext/fluid/Tests/Functional/Fixtures/Extensions/fluid_test'];

protected $coreExtensionsToLoad = ['fluid'];

public function viewHelperTemplateSourcesDataProvider()
public function viewHelperTemplateSourcesDataProvider(): array
{
return [
'EscapeChildrenEnabledAndEscapeOutputDisabled: Tag syntax with children, properly encodes variable value' =>
Expand Down Expand Up @@ -113,20 +113,15 @@ public function viewHelperTemplateSourcesDataProvider()
}

/**
* @param string $viewHelperTemplate
* @param string $expectedOutput
*
* @test
* @dataProvider viewHelperTemplateSourcesDataProvider
*/
public function renderingTest($viewHelperTemplate, $expectedOutput)
public function renderingTest(string $viewHelperTemplate, string $expectedOutput): void
{
$view = new StandaloneView();
$view->setTemplateSource($viewHelperTemplate);
$view->getRenderingContext()->getViewHelperResolver()->addNamespace('ft', 'TYPO3Fluid\\FluidTest\\ViewHelpers');
$view->getRenderingContext()->getTemplatePaths()->setTemplateSource($viewHelperTemplate);

$view->assign('settings', ['test' => '<strong>Bla</strong>']);

self::assertSame($expectedOutput, $view->render());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 CMS project.
*
Expand All @@ -22,9 +24,7 @@ class EscapeChildrenRenderingTest extends FunctionalTestCase
{
protected $testExtensionsToLoad = ['typo3/sysext/fluid/Tests/Functional/Fixtures/Extensions/fluid_test'];

protected $coreExtensionsToLoad = ['fluid'];

public function viewHelperTemplateSourcesDataProvider()
public function viewHelperTemplateSourcesDataProvider(): array
{
return [
'EscapeChildrenEnabledAndEscapeOutputDisabled: Tag syntax with children, properly encodes variable value' =>
Expand Down Expand Up @@ -113,19 +113,15 @@ public function viewHelperTemplateSourcesDataProvider()
}

/**
* @param string $viewHelperTemplate
* @param string $expectedOutput
*
* @test
* @dataProvider viewHelperTemplateSourcesDataProvider
*/
public function renderingTest($viewHelperTemplate, $expectedOutput)
public function renderingTest(string $viewHelperTemplate, string $expectedOutput)
{
$view = new TemplateView();
$view->assign('settings', ['test' => '<strong>Bla</strong>']);
$view->getRenderingContext()->getViewHelperResolver()->addNamespace('ft', 'TYPO3Fluid\\FluidTest\\ViewHelpers');
$view->getRenderingContext()->getTemplatePaths()->setTemplateSource($viewHelperTemplate);

self::assertSame($expectedOutput, $view->render());
}
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Fluid Rendering Test Extension for TYPO3 [![Build Status](https://travis-ci.org/helhum/fluid_test.svg?branch=master)](https://travis-ci.org/helhum/fluid_test)
# Fluid rendering test extension, used in various fluid functional tests

Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 CMS project.
*
Expand All @@ -13,13 +15,10 @@
* The TYPO3 project - inspiring people to share!
*/

namespace TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\Form\Fixtures;
namespace TYPO3\CMS\Fluid\Tests\Functional\Fixtures\ViewHelpers;

use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;

/**
* Class ExtendsAbstractEntity
*/
class ExtendsAbstractEntity extends AbstractEntity
{
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit ad3a216

Please sign in to comment.