performance improvements (#2329)

* remove work from constructor
* refactor twig extensions
* upgrade theme
* replace sub-request with direct template rendering
This commit is contained in:
Kevin Papst
2021-02-20 23:52:01 +01:00
committed by GitHub
parent 9eb25c412e
commit 607d09aefb
40 changed files with 992 additions and 1092 deletions

View File

@@ -77,10 +77,7 @@ class LayoutControllerTest extends ControllerBaseTest
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
$em = $this->getEntityManager();
$user = $this->getUserByRole(User::ROLE_USER);
$this->request($client, '/layou/active_entries');
$this->request($client, '/dashboard/');
$this->assertTrue($client->getResponse()->isSuccessful());
$content = $client->getResponse()->getContent();

View File

@@ -28,13 +28,11 @@ use App\Event\TimesheetMetaDisplayEvent;
use App\Export\ExportRendererInterface;
use App\Export\RendererInterface;
use App\Repository\Query\TimesheetQuery;
use App\Twig\DateExtensions;
use App\Twig\LocaleFormatExtensions;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
@@ -46,7 +44,6 @@ abstract class AbstractRendererTest extends KernelTestCase
*/
protected function getAbstractRenderer(string $classname)
{
$requestStack = new RequestStack();
$languages = [
'en' => [
'date' => 'Y.m.d',
@@ -55,12 +52,8 @@ abstract class AbstractRendererTest extends KernelTestCase
]
];
$request = new Request();
$request->setLocale('en');
$requestStack->push($request);
$translator = $this->createMock(TranslatorInterface::class);
$dateExtension = new DateExtensions($requestStack, new LanguageFormattings($languages));
$dateExtension = new LocaleFormatExtensions(new LanguageFormattings($languages));
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new MetaFieldColumnSubscriber());

View File

@@ -27,13 +27,11 @@ use App\Event\ProjectMetaDisplayEvent;
use App\Event\TimesheetMetaDisplayEvent;
use App\Export\TimesheetExportInterface;
use App\Repository\Query\TimesheetQuery;
use App\Twig\DateExtensions;
use App\Twig\LocaleFormatExtensions;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
@@ -45,7 +43,6 @@ abstract class AbstractRendererTest extends KernelTestCase
*/
protected function getAbstractRenderer(string $classname)
{
$requestStack = new RequestStack();
$languages = [
'en' => [
'date' => 'Y.m.d',
@@ -54,12 +51,8 @@ abstract class AbstractRendererTest extends KernelTestCase
]
];
$request = new Request();
$request->setLocale('en');
$requestStack->push($request);
$translator = $this->getMockBuilder(TranslatorInterface::class)->getMock();
$dateExtension = new DateExtensions($requestStack, new LanguageFormattings($languages));
$dateExtension = new LocaleFormatExtensions(new LanguageFormattings($languages));
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new MetaFieldColumnSubscriber());

View File

@@ -9,7 +9,7 @@
namespace App\Tests\Twig;
use App\Configuration\ThemeConfiguration;
use App\Configuration\SystemConfiguration;
use App\Tests\Configuration\TestConfigLoader;
use App\Twig\ConfigExtension;
use PHPUnit\Framework\TestCase;
@@ -23,7 +23,7 @@ class ConfigExtensionTest extends TestCase
protected function getSut(array $settings, array $loaderSettings = []): ConfigExtension
{
$loader = new TestConfigLoader($loaderSettings);
$config = new ThemeConfiguration($loader, $settings);
$config = new SystemConfiguration($loader, ['theme' => $settings]);
return new ConfigExtension($config);
}

View File

@@ -1,238 +0,0 @@
<?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;
use App\Configuration\LanguageFormattings;
use App\Entity\User;
use App\Twig\DateExtensions;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Twig\TwigFilter;
use Twig\TwigFunction;
/**
* @covers \App\Twig\DateExtensions
* @covers \App\Utils\LocaleFormats
* @covers \App\Utils\LocaleFormatter
*/
class DateExtensionsTest extends TestCase
{
/**
* @param string $locale
* @param array $dateSettings
* @return DateExtensions
*/
protected function getSut($locale, array $dateSettings)
{
$request = new Request();
$request->setLocale($locale);
$requestStack = new RequestStack();
$requestStack->push($request);
return new DateExtensions($requestStack, new LanguageFormattings($dateSettings));
}
public function testGetFilters()
{
$filters = ['month_name', 'day_name', 'date_short', 'date_time', 'date_full', 'date_format', 'time', 'hour24'];
$sut = $this->getSut('de', []);
$twigFilters = $sut->getFilters();
$this->assertCount(\count($filters), $twigFilters);
$i = 0;
foreach ($twigFilters as $filter) {
$this->assertInstanceOf(TwigFilter::class, $filter);
$this->assertEquals($filters[$i++], $filter->getName());
}
}
public function testGetFunctions()
{
$functions = ['get_format_duration', 'create_date'];
$sut = $this->getSut('de', []);
$twigFunctions = $sut->getFunctions();
$this->assertCount(\count($functions), $twigFunctions);
$i = 0;
/** @var TwigFunction $filter */
foreach ($twigFunctions as $filter) {
$this->assertInstanceOf(TwigFunction::class, $filter);
$this->assertEquals($functions[$i++], $filter->getName());
}
}
/**
* @param string $locale
* @param \DateTime|string $date
* @param string $result
* @dataProvider getDateShortData
*/
public function testDateShort($locale, $date, $result)
{
$sut = $this->getSut($locale, [
'de' => ['date' => 'd.m.Y'],
'en' => ['date' => 'Y-m-d'],
'ru' => ['date' => 'd.m.Y'],
]);
$this->assertEquals($result, $sut->dateShort($date));
}
public function getDateShortData()
{
return [
['en', new \DateTime('7 January 2010'), '2010-01-07'],
['en', new \DateTime('2016-06-23'), '2016-06-23'],
['de', new \DateTime('1980-12-14'), '14.12.1980'],
['ru', new \DateTime('1980-12-14'), '14.12.1980'],
['ru', '1980-12-14', '14.12.1980'],
['ru', 1.2345, 1.2345],
];
}
/**
* @param string $locale
* @param \DateTime|string $date
* @param string $result
* @dataProvider getDateTimeData
*/
public function testDateTime($locale, $date, $result)
{
$sut = $this->getSut($locale, [
'de' => ['date_time' => 'd.m.Y H:i:s'],
'en' => ['date_time' => 'Y-m-d h:m A'],
]);
$this->assertEquals($result, $sut->dateTime($date));
}
public function getDateTimeData()
{
return [
['en', new \DateTime('7 January 2010'), '2010-01-07 12:01 AM'],
['de', (new \DateTime('1980-12-14'))->setTime(13, 27, 55), '14.12.1980 13:27:55'],
['de', '1980-12-14 13:27:55', '14.12.1980 13:27:55'],
['de', 1.2345, 1.2345],
];
}
/**
* @dataProvider getDayNameTestData
*/
public function testDayName(string $locale, string $date, string $expectedName, bool $short)
{
$sut = $this->getSut($locale, []);
self::assertEquals($expectedName, $sut->dayName(new \DateTime($date), $short));
}
public function getDayNameTestData()
{
return [
['de', '2020-07-09 12:00:00', 'Donnerstag', false],
['en', '2020-07-09 12:00:00', 'Thursday', false],
['de', '2020-07-09 12:00:00', 'Do.', true],
['en', '2020-07-09 12:00:00', 'Thu', true],
];
}
/**
* @dataProvider getMonthNameTestData
*/
public function testMonthName(string $locale, string $date, string $expectedName, bool $withYear = false)
{
$sut = $this->getSut($locale, []);
self::assertEquals($expectedName, $sut->monthName(new \DateTime($date), $withYear));
}
public function getMonthNameTestData()
{
return [
['de', '2020-07-09 23:59:59', 'Juli', false],
['en', '2020-07-09 23:59:59', 'July', false],
['de', 'January 2016', 'Januar', false],
['en', 'January 2016', 'January', false],
['en', '2016-12-23', 'December', false],
['ru', '2016-12-23', 'декабрь', false],
['de', '2020-07-09 23:59:59', 'Juli 2020', true],
['en', '2020-07-09 23:59:59', 'July 2020', true],
['de', 'January 2016', 'Januar 2016', true],
['en', 'January 2016', 'January 2016', true],
['en', '2015-12-23', 'December 2015', true],
['ru', '2015-12-23', 'декабрь 2015', true],
];
}
public function testDateFormat()
{
$date = new \DateTime('7 January 2010 17:43:21', new \DateTimeZone('Europe/Berlin'));
$sut = $this->getSut('en', []);
$this->assertEquals('2010-01-07T17:43:21+01:00', $sut->dateFormat($date, 'c'));
$this->assertStringStartsWith('2010-01-07T17:43:21', $sut->dateFormat('7 January 2010 17:43:21', 'c'));
// next test checks the fallback for errors while converting the date
/* @phpstan-ignore-next-line */
$this->assertEquals(2010.0107, $sut->dateFormat(2010.0107, 'c'));
}
public function testTime()
{
$time = new \DateTime('2016-06-23');
$time->setTime(17, 53, 23);
$sut = $this->getSut('en', ['en' => ['time' => 'H:i']]);
$this->assertEquals('17:53', $sut->time($time));
$this->assertEquals('17:53', $sut->time('2016-06-23 17:53'));
}
public function testHour24()
{
$sut = $this->getSut('en', [
'en' => ['24_hours' => false],
]);
$this->assertEquals('bar', $sut->hour24('foo', 'bar'));
$sut = $this->getSut('de', [
'de' => ['24_hours' => true],
]);
$this->assertEquals('foo', $sut->hour24('foo', 'bar'));
}
public function testDateTimeFull()
{
$sut = $this->getSut('en', [
'en' => ['date_time_type' => 'yyyy-MM-dd HH:mm:ss'],
]);
$dateTime = new \DateTime('2019-08-17 12:29:47', new \DateTimeZone(date_default_timezone_get()));
$dateTime->setDate(2019, 8, 17);
$dateTime->setTime(12, 29, 47);
$this->assertEquals('2019-08-17 12:29:47', $sut->dateTimeFull($dateTime));
$this->assertEquals('2019-08-17 12:29:47', $sut->dateTimeFull('2019-08-17 12:29:47'));
// next test checks the fallback for errors while converting the date
/* @phpstan-ignore-next-line */
$this->assertEquals(189.45, $sut->dateTimeFull(189.45));
}
public function testCreateDate()
{
$user = new User();
$user->setTimezone('Europe/Berlin');
$sut = $this->getSut('en', []);
$date = $sut->createDate('now', $user);
$this->assertEquals('Europe/Berlin', $date->getTimezone()->getName());
$user->setTimezone('Asia/Dubai');
$date = $sut->createDate('2019-08-27 16:30:45', $user);
$this->assertEquals('2019-08-27T16:30:45+0400', $date->format(DATE_ISO8601));
$this->assertEquals('Asia/Dubai', $date->getTimezone()->getName());
$date = $sut->createDate('2019-08-27 16:30:45', null);
$this->assertEquals(date_default_timezone_get(), $date->getTimezone()->getName());
}
}

View File

@@ -1,39 +0,0 @@
<?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;
use App\Twig\EventExtensions;
use PHPUnit\Framework\TestCase;
use Twig\TwigFunction;
/**
* @covers \App\Twig\EventExtensions
*/
class EventExtensionsTest extends TestCase
{
protected function getSut(): EventExtensions
{
return new EventExtensions();
}
public function testGetFunctions()
{
$functions = ['trigger', 'javascript_translations'];
$sut = $this->getSut();
$twigFunctions = $sut->getFunctions();
self::assertCount(\count($functions), $twigFunctions);
$i = 0;
/** @var TwigFunction $filter */
foreach ($twigFunctions as $filter) {
self::assertInstanceOf(TwigFunction::class, $filter);
self::assertEquals($functions[$i++], $filter->getName());
}
}
}

View File

@@ -11,19 +11,19 @@ namespace App\Tests\Twig;
use App\Configuration\LanguageFormattings;
use App\Entity\Timesheet;
use App\Twig\LocaleExtensions;
use App\Entity\User;
use App\Twig\LocaleFormatExtensions;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Intl\Util\IntlTestHelper;
use Twig\TwigFilter;
use Twig\TwigFunction;
/**
* @covers \App\Twig\LocaleExtensions
* @covers \App\Twig\LocaleFormatExtensions
* @covers \App\Utils\LocaleFormatter
* @covers \App\Utils\LocaleFormats
*/
class LocaleExtensionsTest extends TestCase
class LocaleFormatExtensionsTest extends TestCase
{
private $localeEn = ['en' => ['date' => 'Y-m-d', 'duration' => '%h:%m h']];
private $localeDe = ['de' => ['date' => 'd.m.Y', 'duration' => '%h:%m h']];
@@ -31,28 +31,35 @@ class LocaleExtensionsTest extends TestCase
private $localeFake = ['XX' => ['date' => 'd.m.Y', 'duration' => '%h - %m - %s Zeit']];
/**
* @param array $locales
* @param string $locale
* @return LocaleExtensions
* @param string|array $locale
* @param array|string $dateSettings
* @return LocaleFormatExtensions
*/
protected function getSut($locales, $locale = 'en')
protected function getSut($locale, $dateSettings)
{
$request = new Request();
$request->setLocale($locale);
$requestStack = new RequestStack();
$requestStack->push($request);
$language = $locale;
if (\is_array($locale)) {
$language = $dateSettings;
$dateSettings = $locale;
}
$sut = new LocaleFormatExtensions(new LanguageFormattings($dateSettings));
$sut->setLocale($language);
return new LocaleExtensions($requestStack, new LanguageFormattings($locales));
return $sut;
}
public function testGetFilters()
{
$filters = ['duration', 'duration_decimal', 'money', 'currency', 'country', 'language', 'amount'];
$sut = $this->getSut($this->localeDe);
$filters = [
'month_name', 'day_name', 'date_short', 'date_time', 'date_full', 'date_format', 'time', 'hour24',
'duration', 'duration_decimal', 'money', 'currency', 'country', 'language', 'amount'
];
$i = 0;
$sut = $this->getSut('de', []);
$twigFilters = $sut->getFilters();
$this->assertCount(\count($filters), $twigFilters);
$i = 0;
/** @var TwigFilter $filter */
foreach ($twigFilters as $filter) {
$this->assertInstanceOf(TwigFilter::class, $filter);
$this->assertEquals($filters[$i++], $filter->getName());
@@ -61,11 +68,13 @@ class LocaleExtensionsTest extends TestCase
public function testGetFunctions()
{
$functions = ['locales'];
$sut = $this->getSut($this->localeDe);
$functions = ['get_format_duration', 'create_date', 'locales'];
$i = 0;
$sut = $this->getSut('de', []);
$twigFunctions = $sut->getFunctions();
$this->assertCount(\count($functions), $twigFunctions);
$i = 0;
/** @var TwigFunction $filter */
foreach ($twigFunctions as $filter) {
$this->assertInstanceOf(TwigFunction::class, $filter);
@@ -73,6 +82,175 @@ class LocaleExtensionsTest extends TestCase
}
}
/**
* @param string $locale
* @param \DateTime|string $date
* @param string $result
* @dataProvider getDateShortData
*/
public function testDateShort($locale, $date, $result)
{
$sut = $this->getSut($locale, [
'de' => ['date' => 'd.m.Y'],
'en' => ['date' => 'Y-m-d'],
'ru' => ['date' => 'd.m.Y'],
]);
$this->assertEquals($result, $sut->dateShort($date));
}
public function getDateShortData()
{
return [
['en', new \DateTime('7 January 2010'), '2010-01-07'],
['en', new \DateTime('2016-06-23'), '2016-06-23'],
['de', new \DateTime('1980-12-14'), '14.12.1980'],
['ru', new \DateTime('1980-12-14'), '14.12.1980'],
['ru', '1980-12-14', '14.12.1980'],
['ru', 1.2345, 1.2345],
];
}
/**
* @param string $locale
* @param \DateTime|string $date
* @param string $result
* @dataProvider getDateTimeData
*/
public function testDateTime($locale, $date, $result)
{
$sut = $this->getSut($locale, [
'de' => ['date_time' => 'd.m.Y H:i:s'],
'en' => ['date_time' => 'Y-m-d h:m A'],
]);
$this->assertEquals($result, $sut->dateTime($date));
}
public function getDateTimeData()
{
return [
['en', new \DateTime('7 January 2010'), '2010-01-07 12:01 AM'],
['de', (new \DateTime('1980-12-14'))->setTime(13, 27, 55), '14.12.1980 13:27:55'],
['de', '1980-12-14 13:27:55', '14.12.1980 13:27:55'],
['de', 1.2345, 1.2345],
];
}
/**
* @dataProvider getDayNameTestData
*/
public function testDayName(string $locale, string $date, string $expectedName, bool $short)
{
$sut = $this->getSut($locale, []);
self::assertEquals($expectedName, $sut->dayName(new \DateTime($date), $short));
}
public function getDayNameTestData()
{
return [
['de', '2020-07-09 12:00:00', 'Donnerstag', false],
['en', '2020-07-09 12:00:00', 'Thursday', false],
['de', '2020-07-09 12:00:00', 'Do.', true],
['en', '2020-07-09 12:00:00', 'Thu', true],
];
}
/**
* @dataProvider getMonthNameTestData
*/
public function testMonthName(string $locale, string $date, string $expectedName, bool $withYear = false)
{
$sut = $this->getSut($locale, []);
self::assertEquals($expectedName, $sut->monthName(new \DateTime($date), $withYear));
}
public function getMonthNameTestData()
{
return [
['de', '2020-07-09 23:59:59', 'Juli', false],
['en', '2020-07-09 23:59:59', 'July', false],
['de', 'January 2016', 'Januar', false],
['en', 'January 2016', 'January', false],
['en', '2016-12-23', 'December', false],
['ru', '2016-12-23', 'декабрь', false],
['de', '2020-07-09 23:59:59', 'Juli 2020', true],
['en', '2020-07-09 23:59:59', 'July 2020', true],
['de', 'January 2016', 'Januar 2016', true],
['en', 'January 2016', 'January 2016', true],
['en', '2015-12-23', 'December 2015', true],
['ru', '2015-12-23', 'декабрь 2015', true],
];
}
public function testDateFormat()
{
$date = new \DateTime('7 January 2010 17:43:21', new \DateTimeZone('Europe/Berlin'));
$sut = $this->getSut('en', []);
$this->assertEquals('2010-01-07T17:43:21+01:00', $sut->dateFormat($date, 'c'));
$this->assertStringStartsWith('2010-01-07T17:43:21', $sut->dateFormat('7 January 2010 17:43:21', 'c'));
// next test checks the fallback for errors while converting the date
/* @phpstan-ignore-next-line */
$this->assertEquals(2010.0107, $sut->dateFormat(2010.0107, 'c'));
}
public function testTime()
{
$time = new \DateTime('2016-06-23');
$time->setTime(17, 53, 23);
$sut = $this->getSut('en', ['en' => ['time' => 'H:i']]);
$this->assertEquals('17:53', $sut->time($time));
$this->assertEquals('17:53', $sut->time('2016-06-23 17:53'));
}
public function testHour24()
{
$sut = $this->getSut('en', [
'en' => ['24_hours' => false],
]);
$this->assertEquals('bar', $sut->hour24('foo', 'bar'));
$sut = $this->getSut('de', [
'de' => ['24_hours' => true],
]);
$this->assertEquals('foo', $sut->hour24('foo', 'bar'));
}
public function testDateTimeFull()
{
$sut = $this->getSut('en', [
'en' => ['date_time_type' => 'yyyy-MM-dd HH:mm:ss'],
]);
$dateTime = new \DateTime('2019-08-17 12:29:47', new \DateTimeZone(date_default_timezone_get()));
$dateTime->setDate(2019, 8, 17);
$dateTime->setTime(12, 29, 47);
$this->assertEquals('2019-08-17 12:29:47', $sut->dateTimeFull($dateTime));
$this->assertEquals('2019-08-17 12:29:47', $sut->dateTimeFull('2019-08-17 12:29:47'));
// next test checks the fallback for errors while converting the date
/* @phpstan-ignore-next-line */
$this->assertEquals(189.45, $sut->dateTimeFull(189.45));
}
public function testCreateDate()
{
$user = new User();
$user->setTimezone('Europe/Berlin');
$sut = $this->getSut('en', []);
$date = $sut->createDate('now', $user);
$this->assertEquals('Europe/Berlin', $date->getTimezone()->getName());
$user->setTimezone('Asia/Dubai');
$date = $sut->createDate('2019-08-27 16:30:45', $user);
$this->assertEquals('2019-08-27T16:30:45+0400', $date->format(DATE_ISO8601));
$this->assertEquals('Asia/Dubai', $date->getTimezone()->getName());
$date = $sut->createDate('2019-08-27 16:30:45', null);
$this->assertEquals(date_default_timezone_get(), $date->getTimezone()->getName());
}
public function testLocales()
{
$locales = [
@@ -82,7 +260,7 @@ class LocaleExtensionsTest extends TestCase
];
$appLocales = array_merge($this->localeEn, $this->localeDe, $this->localeRu);
$sut = $this->getSut($appLocales);
$sut = $this->getSut('en', $appLocales);
$this->assertEquals($locales, $sut->getLocales());
}
@@ -96,7 +274,7 @@ class LocaleExtensionsTest extends TestCase
123 => 123,
];
$sut = $this->getSut($this->localeEn);
$sut = $this->getSut('en', $this->localeEn);
foreach ($symbols as $name => $symbol) {
$this->assertEquals($symbol, $sut->currency($name));
}
@@ -112,7 +290,7 @@ class LocaleExtensionsTest extends TestCase
'12' => '12',
];
$sut = $this->getSut($this->localeEn);
$sut = $this->getSut('en', $this->localeEn);
foreach ($countries as $locale => $name) {
$this->assertEquals($name, $sut->country($locale));
}
@@ -128,7 +306,7 @@ class LocaleExtensionsTest extends TestCase
'12' => '12',
];
$sut = $this->getSut($this->localeEn);
$sut = $this->getSut('en', $this->localeEn);
foreach ($languages as $locale => $name) {
$this->assertEquals($name, $sut->language($locale));
}
@@ -254,7 +432,7 @@ class LocaleExtensionsTest extends TestCase
{
$record = $this->getTimesheet(9437);
$sut = $this->getSut($this->localeEn);
$sut = $this->getSut('en', $this->localeEn);
$this->assertEquals('02:37 h', $sut->duration($record->getDuration()));
$this->assertEquals('2.62', $sut->duration($record->getDuration(), true));
@@ -284,7 +462,7 @@ class LocaleExtensionsTest extends TestCase
{
$record = $this->getTimesheet(9437);
$sut = $this->getSut($this->localeEn);
$sut = $this->getSut('en', $this->localeEn);
$this->assertEquals('2.62', $sut->durationDecimal($record->getDuration()));
// test Timesheet object

View File

@@ -7,17 +7,16 @@
* file that was distributed with this source code.
*/
namespace App\Tests\Twig;
namespace App\Tests\Twig\Runtime;
use App\Twig\EncoreExtension;
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;
use Twig\TwigFunction;
/**
* @covers \App\Twig\EncoreExtension
* @covers \App\Twig\Runtime\EncoreExtension
*/
class EncoreExtensionTest extends TestCase
{
@@ -29,7 +28,7 @@ class EncoreExtensionTest extends TestCase
$container = new Container(new ParameterBag([]));
$container->set(EntrypointLookupInterface::class, $entryLookup);
return new EncoreExtension($container, __DIR__);
return new EncoreExtension($container, __DIR__ . '/../');
}
public function testGetSubscribedServices()
@@ -37,20 +36,6 @@ class EncoreExtensionTest extends TestCase
self::assertEquals([EntrypointLookupInterface::class], EncoreExtension::getSubscribedServices());
}
public function testGetFunctions()
{
$functions = ['encore_entry_css_source'];
$sut = $this->getSut();
$twigFunctions = $sut->getFunctions();
self::assertCount(\count($functions), $twigFunctions);
$i = 0;
/** @var TwigFunction $filter */
foreach ($twigFunctions as $filter) {
self::assertInstanceOf(TwigFunction::class, $filter);
self::assertEquals($functions[$i++], $filter->getName());
}
}
public function testGetEncoreEntryCssSource()
{
$sut = $this->getSut(['test.css', 'test1.css']);

View 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());
}
}

View File

@@ -7,44 +7,19 @@
* file that was distributed with this source code.
*/
namespace App\Tests\Twig;
namespace App\Tests\Twig\Runtime;
use App\Configuration\ConfigLoaderInterface;
use App\Configuration\SystemConfiguration;
use App\Twig\MarkdownExtension;
use App\Twig\Runtime\MarkdownExtension;
use App\Utils\Markdown;
use PHPUnit\Framework\TestCase;
use Twig\Node\Node;
/**
* @covers \App\Twig\MarkdownExtension
* @covers \App\Twig\Runtime\MarkdownExtension
*/
class MarkdownExtensionTest extends TestCase
{
public function testGetFilters()
{
$loader = $this->createMock(ConfigLoaderInterface::class);
$config = new SystemConfiguration($loader, ['timesheet' => ['markdown_content' => true]]);
$sut = new MarkdownExtension(new Markdown(), $config);
$filters = $sut->getFilters();
$this->assertCount(3, $filters);
// make sure that the md2html filter does proper escaping
$this->assertEquals('md2html', $filters[0]->getName());
self::assertEquals('html', $filters[0]->getPreEscape());
self::assertEquals(['html'], $filters[0]->getSafe(new Node()));
// make sure that the desc2html filter does proper escaping
$this->assertEquals('desc2html', $filters[1]->getName());
self::assertEquals('html', $filters[1]->getPreEscape());
self::assertEquals(['html'], $filters[1]->getSafe(new Node()));
// make sure that the comment2html filter does proper escaping
$this->assertEquals('comment2html', $filters[2]->getName());
self::assertEquals('html', $filters[2]->getPreEscape());
self::assertEquals(['html'], $filters[2]->getSafe(new Node()));
}
public function testMarkdownToHtml()
{
$loader = $this->createMock(ConfigLoaderInterface::class);

View File

@@ -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);
}

View 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()));
}
}

View File

@@ -7,24 +7,23 @@
* file that was distributed with this source code.
*/
namespace App\Tests\Twig;
namespace App\Tests\Twig\Runtime;
use App\Twig\WidgetExtension;
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;
use Twig\TwigFunction;
/**
* @covers \App\Twig\WidgetExtension
* @covers \App\Twig\Runtime\WidgetExtension
*/
class WidgetExtensionTest extends TestCase
{
protected function getSut($hasWidget = null, $getWidget = null, $renderer = null): WidgetExtension
{
$service = $this->getMockBuilder(WidgetService::class)->disableOriginalConstructor()->onlyMethods(['hasWidget', 'getWidget', 'findRenderer'])->getMock();
$service = $this->createMock(WidgetService::class);
if (null !== $hasWidget) {
$service->expects($this->once())->method('hasWidget')->willReturn($hasWidget);
}
@@ -38,20 +37,6 @@ class WidgetExtensionTest extends TestCase
return new WidgetExtension($service);
}
public function testGetFunctions()
{
$functions = ['render_widget'];
$sut = $this->getSut();
$twigFunctions = $sut->getFunctions();
$this->assertCount(\count($functions), $twigFunctions);
$i = 0;
/** @var TwigFunction $function */
foreach ($twigFunctions as $function) {
$this->assertInstanceOf(TwigFunction::class, $function);
$this->assertEquals($functions[$i++], $function->getName());
}
}
public function testRenderWidgetForInvalidValue()
{
$this->expectException(\InvalidArgumentException::class);

View File

@@ -0,0 +1,87 @@
<?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;
use App\Twig\RuntimeExtensions;
use PHPUnit\Framework\TestCase;
use Twig\Node\Node;
use Twig\TwigFilter;
use Twig\TwigFunction;
/**
* @covers \App\Twig\RuntimeExtensions
*/
class RuntimeExtensionsTest extends TestCase
{
public function testGetFilters()
{
$expected = ['md2html', 'desc2html', 'comment2html'];
$i = 0;
$sut = new RuntimeExtensions();
$twigFilters = $sut->getFilters();
$this->assertCount(\count($expected), $twigFilters);
foreach ($twigFilters as $filter) {
$this->assertInstanceOf(TwigFilter::class, $filter);
$this->assertEquals($expected[$i++], $filter->getName());
}
}
public function testGetFunctions()
{
$expected = ['trigger', 'javascript_translations', 'timesheet_exporter', 'active_timesheets', 'encore_entry_css_source', 'render_widget'];
$i = 0;
$sut = new RuntimeExtensions();
$twigFunctions = $sut->getFunctions();
$this->assertCount(\count($expected), $twigFunctions);
/** @var TwigFunction $filter */
foreach ($twigFunctions as $filter) {
$this->assertInstanceOf(TwigFunction::class, $filter);
$this->assertEquals($expected[$i++], $filter->getName());
}
}
public function testGetFilterDefinition()
{
$sut = new RuntimeExtensions();
$filters = $sut->getFilters();
$found_md2html = false;
$found_desc2html = false;
$found_comment2html = false;
foreach ($filters as $filter) {
switch ($filter->getName()) {
case 'md2html':
self::assertEquals('html', $filters[0]->getPreEscape());
self::assertEquals(['html'], $filters[0]->getSafe(new Node()));
$found_md2html = true;
break;
case 'desc2html':
self::assertEquals('html', $filters[1]->getPreEscape());
self::assertEquals(['html'], $filters[1]->getSafe(new Node()));
$found_desc2html = true;
break;
case 'comment2html':
self::assertEquals('html', $filters[2]->getPreEscape());
self::assertEquals(['html'], $filters[2]->getSafe(new Node()));
$found_comment2html = true;
break;
}
}
self::assertTrue($found_md2html, 'Missing filter: md2html');
self::assertTrue($found_desc2html, 'Missing filter: desc2html');
self::assertTrue($found_comment2html, 'Missing filter: comment2html');
}
}

View File

@@ -1,48 +0,0 @@
<?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;
use App\Export\ServiceExport;
use App\Twig\TimesheetExtension;
use PHPUnit\Framework\TestCase;
use Twig\TwigFunction;
/**
* @covers \App\Twig\TimesheetExtension
*/
class TimesheetExtensionTest extends TestCase
{
protected function getSut(): TimesheetExtension
{
$service = new ServiceExport();
return new TimesheetExtension($service);
}
public function testGetFunctions()
{
$sut = $this->getSut();
$functions = ['timesheet_exporter'];
$twigFunctions = $sut->getFunctions();
$this->assertCount(\count($functions), $twigFunctions);
$i = 0;
/** @var TwigFunction $function */
foreach ($twigFunctions as $function) {
$this->assertInstanceOf(TwigFunction::class, $function);
$this->assertEquals($functions[$i++], $function->getName());
}
}
public function testGetExporter()
{
$sut = $this->getSut();
self::assertEquals([], $sut->getTimesheetExporter());
}
}