performance improvements (#2329)
* remove work from constructor * refactor twig extensions * upgrade theme * replace sub-request with direct template rendering
This commit is contained in:
47
tests/Twig/Runtime/EncoreExtensionTest.php
Normal file
47
tests/Twig/Runtime/EncoreExtensionTest.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Tests\Twig\Runtime;
|
||||
|
||||
use App\Twig\Runtime\EncoreExtension;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
use Symfony\WebpackEncoreBundle\Asset\EntrypointLookupInterface;
|
||||
|
||||
/**
|
||||
* @covers \App\Twig\Runtime\EncoreExtension
|
||||
*/
|
||||
class EncoreExtensionTest extends TestCase
|
||||
{
|
||||
protected function getSut(array $files = []): EncoreExtension
|
||||
{
|
||||
$entryLookup = $this->createMock(EntrypointLookupInterface::class);
|
||||
$entryLookup->expects($this->any())->method('getCssFiles')->willReturn($files);
|
||||
|
||||
$container = new Container(new ParameterBag([]));
|
||||
$container->set(EntrypointLookupInterface::class, $entryLookup);
|
||||
|
||||
return new EncoreExtension($container, __DIR__ . '/../');
|
||||
}
|
||||
|
||||
public function testGetSubscribedServices()
|
||||
{
|
||||
self::assertEquals([EntrypointLookupInterface::class], EncoreExtension::getSubscribedServices());
|
||||
}
|
||||
|
||||
public function testGetEncoreEntryCssSource()
|
||||
{
|
||||
$sut = $this->getSut(['test.css', 'test1.css']);
|
||||
$css = 'body { margin: 0; }p
|
||||
{
|
||||
color: red; font-style: italic; }';
|
||||
self::assertEquals($css, $sut->getEncoreEntryCssSource('blub'));
|
||||
}
|
||||
}
|
||||
33
tests/Twig/Runtime/ExporterExtensionTest.php
Normal file
33
tests/Twig/Runtime/ExporterExtensionTest.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Tests\Twig\Runtime;
|
||||
|
||||
use App\Export\ServiceExport;
|
||||
use App\Twig\Runtime\ExporterExtension;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @covers \App\Twig\Runtime\ExporterExtension
|
||||
*/
|
||||
class ExporterExtensionTest extends TestCase
|
||||
{
|
||||
protected function getSut(): ExporterExtension
|
||||
{
|
||||
$service = new ServiceExport();
|
||||
|
||||
return new ExporterExtension($service);
|
||||
}
|
||||
|
||||
public function testGetExporter()
|
||||
{
|
||||
$sut = $this->getSut();
|
||||
self::assertEquals([], $sut->getTimesheetExporter());
|
||||
}
|
||||
}
|
||||
80
tests/Twig/Runtime/MarkdownExtensionTest.php
Normal file
80
tests/Twig/Runtime/MarkdownExtensionTest.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Tests\Twig\Runtime;
|
||||
|
||||
use App\Configuration\ConfigLoaderInterface;
|
||||
use App\Configuration\SystemConfiguration;
|
||||
use App\Twig\Runtime\MarkdownExtension;
|
||||
use App\Utils\Markdown;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @covers \App\Twig\Runtime\MarkdownExtension
|
||||
*/
|
||||
class MarkdownExtensionTest extends TestCase
|
||||
{
|
||||
public function testMarkdownToHtml()
|
||||
{
|
||||
$loader = $this->createMock(ConfigLoaderInterface::class);
|
||||
$config = new SystemConfiguration($loader, ['timesheet' => ['markdown_content' => true]]);
|
||||
$sut = new MarkdownExtension(new Markdown(), $config);
|
||||
$this->assertEquals('<p><em>test</em></p>', $sut->markdownToHtml('*test*'));
|
||||
$this->assertEquals('<p># foobar</p>', $sut->markdownToHtml('# foobar'));
|
||||
}
|
||||
|
||||
public function testTimesheetContent()
|
||||
{
|
||||
$loader = $this->createMock(ConfigLoaderInterface::class);
|
||||
$config = new SystemConfiguration($loader, ['timesheet' => ['markdown_content' => false]]);
|
||||
$sut = new MarkdownExtension(new Markdown(), $config);
|
||||
$this->assertEquals(
|
||||
"- test<br />\n- foo",
|
||||
$sut->timesheetContent("- test\n- foo")
|
||||
);
|
||||
$this->assertEquals('', $sut->timesheetContent(null));
|
||||
$this->assertEquals('', $sut->timesheetContent(''));
|
||||
|
||||
$config = new SystemConfiguration($loader, ['timesheet' => ['markdown_content' => true]]);
|
||||
$sut = new MarkdownExtension(new Markdown(), $config);
|
||||
$this->assertEquals(
|
||||
"<ul>\n<li>test</li>\n<li>foo</li>\n</ul>\n<p>foo <strong>bar</strong></p>",
|
||||
$sut->timesheetContent("- test\n- foo\n\nfoo __bar__")
|
||||
);
|
||||
}
|
||||
|
||||
public function testCommentContent()
|
||||
{
|
||||
$loader = $this->createMock(ConfigLoaderInterface::class);
|
||||
$config = new SystemConfiguration($loader, ['timesheet' => ['markdown_content' => false]]);
|
||||
$sut = new MarkdownExtension(new Markdown(), $config);
|
||||
$this->assertEquals(
|
||||
"<p>- test<br />\n- foo</p>",
|
||||
$sut->commentContent("- test\n- foo", true)
|
||||
);
|
||||
$this->assertEquals(
|
||||
"- test\n- foo",
|
||||
$sut->commentContent("- test\n- foo", false)
|
||||
);
|
||||
|
||||
$loremIpsum = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.';
|
||||
|
||||
$this->assertEquals('', $sut->commentContent(null));
|
||||
$this->assertEquals('', $sut->commentContent(''));
|
||||
$this->assertEquals('<p>' . $loremIpsum . '</p>', $sut->commentContent($loremIpsum, true));
|
||||
$this->assertEquals('Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut l …', $sut->commentContent($loremIpsum));
|
||||
|
||||
$config = new SystemConfiguration($loader, ['timesheet' => ['markdown_content' => true]]);
|
||||
$sut = new MarkdownExtension(new Markdown(), $config);
|
||||
$this->assertEquals(
|
||||
"<ul>\n<li>test</li>\n<li>foo</li>\n</ul>\n<p>foo <strong>bar</strong></p>",
|
||||
$sut->commentContent("- test\n- foo\n\nfoo __bar__")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -12,16 +12,21 @@ namespace App\Tests\Twig\Runtime;
|
||||
use App\Entity\User;
|
||||
use App\Event\ThemeEvent;
|
||||
use App\Tests\Mocks\Security\CurrentUserFactory;
|
||||
use App\Twig\Runtime\ThemeEventExtension;
|
||||
use App\Twig\Runtime\ThemeExtension;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Bridge\Twig\AppVariable;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
||||
use Twig\Environment;
|
||||
use Twig\Loader\FilesystemLoader;
|
||||
|
||||
/**
|
||||
* @covers \App\Twig\Runtime\ThemeEventExtension
|
||||
* @covers \App\Twig\Runtime\ThemeExtension
|
||||
*/
|
||||
class ThemeEventExtensionTest extends TestCase
|
||||
{
|
||||
protected function getSut(bool $hasListener = true): ThemeEventExtension
|
||||
protected function getSut(bool $hasListener = true): ThemeExtension
|
||||
{
|
||||
$dispatcher = $this->createMock(EventDispatcherInterface::class);
|
||||
$dispatcher->method('hasListeners')->willReturn($hasListener);
|
||||
@@ -29,20 +34,39 @@ class ThemeEventExtensionTest extends TestCase
|
||||
|
||||
$user = (new CurrentUserFactory($this))->create(new User());
|
||||
|
||||
return new ThemeEventExtension($dispatcher, $user);
|
||||
return new ThemeExtension($dispatcher);
|
||||
}
|
||||
|
||||
protected function getEnvironment(): Environment
|
||||
{
|
||||
$mock = $this->getMockBuilder(UsernamePasswordToken::class)->onlyMethods(['getUser'])->disableOriginalConstructor()->getMock();
|
||||
$mock->method('getUser')->willReturn(new User());
|
||||
/** @var UsernamePasswordToken $token */
|
||||
$token = $mock;
|
||||
|
||||
$tokenStorage = new TokenStorage();
|
||||
$tokenStorage->setToken($token);
|
||||
|
||||
$app = new AppVariable();
|
||||
$app->setTokenStorage($tokenStorage);
|
||||
|
||||
$environment = new Environment(new FilesystemLoader());
|
||||
$environment->addGlobal('app', $app);
|
||||
|
||||
return $environment;
|
||||
}
|
||||
|
||||
public function testTrigger()
|
||||
{
|
||||
$sut = $this->getSut();
|
||||
$event = $sut->trigger('foo', []);
|
||||
$event = $sut->trigger($this->getEnvironment(), 'foo', []);
|
||||
self::assertInstanceOf(ThemeEvent::class, $event);
|
||||
}
|
||||
|
||||
public function testTriggerWithoutListener()
|
||||
{
|
||||
$sut = $this->getSut(false);
|
||||
$event = $sut->trigger('foo', []);
|
||||
$event = $sut->trigger($this->getEnvironment(), 'foo', []);
|
||||
self::assertInstanceOf(ThemeEvent::class, $event);
|
||||
}
|
||||
|
||||
|
||||
33
tests/Twig/Runtime/TimesheetExtensionTest.php
Normal file
33
tests/Twig/Runtime/TimesheetExtensionTest.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Tests\Twig\Runtime;
|
||||
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Repository\TimesheetRepository;
|
||||
use App\Twig\Runtime\TimesheetExtension;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @covers \App\Twig\Runtime\TimesheetExtension
|
||||
*/
|
||||
class TimesheetExtensionTest extends TestCase
|
||||
{
|
||||
public function testGetExporter()
|
||||
{
|
||||
$entries = [new Timesheet(), new Timesheet()];
|
||||
|
||||
$repository = $this->createMock(TimesheetRepository::class);
|
||||
$repository->method('getActiveEntries')->willReturn($entries);
|
||||
|
||||
$sut = new TimesheetExtension($repository);
|
||||
self::assertEquals($entries, $sut->activeEntries(new User()));
|
||||
}
|
||||
}
|
||||
91
tests/Twig/Runtime/WidgetExtensionTest.php
Normal file
91
tests/Twig/Runtime/WidgetExtensionTest.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Tests\Twig\Runtime;
|
||||
|
||||
use App\Twig\Runtime\WidgetExtension;
|
||||
use App\Widget\Type\More;
|
||||
use App\Widget\WidgetInterface;
|
||||
use App\Widget\WidgetRendererInterface;
|
||||
use App\Widget\WidgetService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @covers \App\Twig\Runtime\WidgetExtension
|
||||
*/
|
||||
class WidgetExtensionTest extends TestCase
|
||||
{
|
||||
protected function getSut($hasWidget = null, $getWidget = null, $renderer = null): WidgetExtension
|
||||
{
|
||||
$service = $this->createMock(WidgetService::class);
|
||||
if (null !== $hasWidget) {
|
||||
$service->expects($this->once())->method('hasWidget')->willReturn($hasWidget);
|
||||
}
|
||||
if (null !== $getWidget) {
|
||||
$service->expects($this->once())->method('getWidget')->willReturn($getWidget);
|
||||
}
|
||||
if (null !== $renderer) {
|
||||
$service->expects($this->once())->method('findRenderer')->willReturn($renderer);
|
||||
}
|
||||
|
||||
return new WidgetExtension($service);
|
||||
}
|
||||
|
||||
public function testRenderWidgetForInvalidValue()
|
||||
{
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Widget must either implement WidgetInterface or be a string');
|
||||
|
||||
$sut = $this->getSut();
|
||||
/* @phpstan-ignore-next-line */
|
||||
$sut->renderWidget(true);
|
||||
}
|
||||
|
||||
public function testRenderWidgetForUnknownWidget()
|
||||
{
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Unknown widget "test" requested');
|
||||
|
||||
$sut = $this->getSut(false);
|
||||
$sut->renderWidget('test');
|
||||
}
|
||||
|
||||
public function testRenderWidgetByString()
|
||||
{
|
||||
$widget = new More();
|
||||
$sut = $this->getSut(true, $widget, new TestRenderer());
|
||||
$options = ['foo' => 'bar', 'dataType' => 'blub'];
|
||||
$result = $sut->renderWidget('test', $options);
|
||||
$data = json_decode($result, true);
|
||||
$this->assertEquals($options, $data);
|
||||
}
|
||||
|
||||
public function testRenderWidgetObject()
|
||||
{
|
||||
$widget = new More();
|
||||
$sut = $this->getSut(null, null, new TestRenderer());
|
||||
$options = ['foo' => 'bar', 'dataType' => 'blub'];
|
||||
$result = $sut->renderWidget($widget, $options);
|
||||
$data = json_decode($result, true);
|
||||
$this->assertEquals($options, $data);
|
||||
}
|
||||
}
|
||||
|
||||
class TestRenderer implements WidgetRendererInterface
|
||||
{
|
||||
public function supports(WidgetInterface $widget): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function render(WidgetInterface $widget, array $options = []): string
|
||||
{
|
||||
return json_encode($widget->getOptions($options));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user