Next major version 2 with PHP 8.1, Symfony 6, Tabler UI, 2FA ... (#2902)

This commit is contained in:
Kevin Papst
2022-12-31 21:19:55 +01:00
committed by GitHub
parent 95e06746bd
commit 90a0fd8a22
2164 changed files with 83700 additions and 86426 deletions

View 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\Export\Annotation;
use App\Export\Annotation\Expose;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Export\Annotation\Expose
*/
class ExposeTest extends TestCase
{
public function testConstruct(): void
{
$sut = new Expose();
self::assertNull($sut->name);
self::assertNull($sut->label);
self::assertEquals('string', $sut->type);
self::assertNull($sut->exp);
}
public function testWithValues(): void
{
$sut = new Expose('name', 'label', 'integer', 'obj.name === null ? 111 : obj.name');
self::assertEquals('name', $sut->name);
self::assertEquals('label', $sut->label);
self::assertEquals('integer', $sut->type);
self::assertEquals('obj.name === null ? 111 : obj.name', $sut->exp);
}
public function testUnknownWithValues(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Unknown type "number" on annotation "App\Export\Annotation\Expose".');
$sut = new Expose('name', 'label', 'number', 'obj.name === null ? 111 : obj.name');
}
}

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\Export\Annotation;
use App\Export\Annotation\Order;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Export\Annotation\Order
*/
class OrderTest extends TestCase
{
public function testConstruct(): void
{
$sut = new Order();
self::assertEquals([], $sut->order);
}
public function testWithValues(): void
{
$sut = new Order(['foo' => 'test', 'bla' => 123]);
self::assertEquals(['foo' => 'test', 'bla' => 123], $sut->order);
}
}

View File

@@ -1,37 +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\Export;
use App\Export\ExportContext;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Export\ExportContext
*/
class ExportContextTest extends TestCase
{
public function testEmptyObject()
{
$sut = new ExportContext();
self::assertIsArray($sut->getOptions());
self::assertEmpty($sut->getOptions());
self::assertNull($sut->getOption('unknown'));
}
public function testSetterAndGetter()
{
$sut = new ExportContext();
self::assertNull($sut->getOption('unknown'));
$sut->setOption('unknown', 'foo');
self::assertEquals('foo', $sut->getOption('unknown'));
}
}

View File

@@ -32,8 +32,7 @@ class ExportFilenameTest extends TestCase
self::assertEquals($datePrefix . '-kimai-export', $sut->getFilename());
self::assertEquals($datePrefix . '-kimai-export', (string) $sut);
$customer = new Customer();
$customer->setName('foo');
$customer = new Customer('foo');
$query = new TimesheetQuery();
$query->addCustomer($customer);
$sut = new ExportFilename($query);
@@ -64,11 +63,11 @@ class ExportFilenameTest extends TestCase
self::assertEquals($datePrefix . '-ss_n_--Demo_ProjecT1', $sut->getFilename());
$user = new User();
$user->setUsername('thorsten');
$user->setUserIdentifier('ayumi');
$query->addUser($user);
$sut = new ExportFilename($query);
self::assertEquals($datePrefix . '-ss_n_--Demo_ProjecT1-thorsten', $sut->getFilename());
self::assertEquals($datePrefix . '-ss_n_--Demo_ProjecT1-ayumi', $sut->getFilename());
$user->setAlias('Martin Müller-Lüdenscheidt');
$sut = new ExportFilename($query);
@@ -86,8 +85,7 @@ class ExportFilenameTest extends TestCase
$sut = new ExportFilename($query);
self::assertEquals($datePrefix . '-ss_n_-', $sut->getFilename());
$customer = new Customer();
$customer->setName('Customer AAAA');
$customer = new Customer('Customer AAAA');
$query->addCustomer($customer);
$sut = new ExportFilename($query);

View File

@@ -9,7 +9,7 @@
namespace App\Tests\Export\Renderer;
use App\Configuration\LanguageFormattings;
use App\Configuration\LocaleService;
use App\Entity\Activity;
use App\Entity\ActivityMeta;
use App\Entity\Customer;
@@ -26,7 +26,7 @@ use App\Event\CustomerMetaDisplayEvent;
use App\Event\ProjectMetaDisplayEvent;
use App\Event\TimesheetMetaDisplayEvent;
use App\Export\ExportRendererInterface;
use App\Export\RendererInterface;
use App\Export\TimesheetExportInterface;
use App\Repository\Query\TimesheetQuery;
use App\Twig\LocaleFormatExtensions;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
@@ -40,14 +40,14 @@ abstract class AbstractRendererTest extends KernelTestCase
{
/**
* @param string $classname
* @return RendererInterface
* @return ExportRendererInterface|TimesheetExportInterface
*/
protected function getAbstractRenderer(string $classname)
{
$languages = [
'en' => [
'date' => 'Y.m.d',
'duration' => '%h:%m h',
'duration' => '%h:%m',
'time' => 'H:i',
]
];
@@ -57,7 +57,7 @@ abstract class AbstractRendererTest extends KernelTestCase
$security->expects($this->any())->method('isGranted')->willReturn(true);
$translator = $this->createMock(TranslatorInterface::class);
$dateExtension = new LocaleFormatExtensions(new LanguageFormattings($languages), $security);
$dateExtension = new LocaleFormatExtensions(new LocaleService($languages), $security);
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new MetaFieldColumnSubscriber());
@@ -71,8 +71,7 @@ abstract class AbstractRendererTest extends KernelTestCase
*/
protected function render(ExportRendererInterface $renderer)
{
$customer = new Customer();
$customer->setName('Customer Name');
$customer = new Customer('Customer Name');
$customer->setNumber('A-0123456789');
$customer->setVatId('DE-9876543210');
$customer->setMetaField((new CustomerMeta())->setName('customer-foo')->setValue('customer-bar')->setIsVisible(true));
@@ -89,19 +88,21 @@ abstract class AbstractRendererTest extends KernelTestCase
$activity->setProject($project);
$activity->setMetaField((new ActivityMeta())->setName('activity-foo')->setValue('activity-bar')->setIsVisible(true));
$userMethods = ['getId', 'getPreferenceValue', 'getUsername'];
$userMethods = ['getId', 'getPreferenceValue', 'getUsername', 'getUserIdentifier'];
$user1 = $this->getMockBuilder(User::class)->onlyMethods($userMethods)->disableOriginalConstructor()->getMock();
$user1->method('getId')->willReturn(1);
$user1->method('getPreferenceValue')->willReturn('50');
$user1->method('getUsername')->willReturn('foo-bar');
$user1->method('getUserIdentifier')->willReturn('foo-bar');
$user2 = $this->getMockBuilder(User::class)->onlyMethods($userMethods)->disableOriginalConstructor()->getMock();
$user2->method('getId')->willReturn(2);
$user2->method('getUsername')->willReturn('hello-world');
$user2->method('getUserIdentifier')->willReturn('hello-world');
$timesheet = new Timesheet();
$timesheet
->setDuration(3600)
->setDuration(3600) // 60 minutes
->setRate(293.27)
->setUser($user1)
->setActivity($activity)
@@ -145,11 +146,14 @@ abstract class AbstractRendererTest extends KernelTestCase
->addTag((new Tag())->setName('foo'))
;
$userKevin = new User();
$userKevin->setUserIdentifier('kevin');
$timesheet5 = new Timesheet();
$timesheet5
->setDuration(400)
->setFixedRate(84)
->setUser((new User())->setUsername('kevin'))
->setUser($userKevin)
->setActivity($activity)
->setProject($project)
->setBegin(new \DateTime('2019-06-16 12:00:00'))
@@ -160,11 +164,14 @@ abstract class AbstractRendererTest extends KernelTestCase
->setMetaField((new TimesheetMeta())->setName('foo2')->setValue('meta-bar2')->setIsVisible(true))
;
$userNivek = new User();
$userNivek->setUserIdentifier('nivek');
$timesheet6 = new Timesheet();
$timesheet6
->setDuration(400)
->setFixedRate(-100.92)
->setUser((new User())->setUsername('nivek'))
->setUser($userNivek)
->setActivity($activity)
->setProject($project)
->setBegin(new \DateTime('2019-06-16 12:00:00'))

View File

@@ -17,7 +17,6 @@ use Symfony\Component\HttpFoundation\BinaryFileResponse;
* @covers \App\Export\Base\AbstractSpreadsheetRenderer
* @covers \App\Export\Base\RendererTrait
* @covers \App\Export\Renderer\CsvRenderer
* @covers \App\Export\Renderer\AbstractSpreadsheetRenderer
* @group integration
*/
class CsvRendererTest extends AbstractRendererTest

View File

@@ -46,7 +46,7 @@ class HtmlRendererTest extends AbstractRendererTest
{
$kernel = self::bootKernel();
/** @var Environment $twig */
$twig = $kernel->getContainer()->get('twig');
$twig = self::getContainer()->get('twig');
$token = $this->createMock(TokenInterface::class);
$token->expects($this->any())->method('getUser')->willReturn(new User());
@@ -57,7 +57,7 @@ class HtmlRendererTest extends AbstractRendererTest
$app = $twig->getGlobals()['app'];
$twig->addGlobal('app', $app);
$app->setTokenStorage($tokenStorage);
$stack = $kernel->getContainer()->get('request_stack');
$stack = self::getContainer()->get('request_stack');
$request = new Request();
$request->setLocale('en');
$stack->push($request);
@@ -74,7 +74,7 @@ class HtmlRendererTest extends AbstractRendererTest
$content = $response->getContent();
$this->assertStringContainsString('<h2 id="doc-title" contenteditable="true"', $content);
$this->assertStringContainsString('<h3 id="doc-summary" contenteditable="true" data-original="Summary">Summary</h3>', $content);
$this->assertStringContainsString('<h3 class="card-title" id="doc-summary" contenteditable="true" data-original="Summary">Summary</h3>', $content);
$this->assertEquals(1, substr_count($content, 'id="export-summary"'));
$this->assertEquals(1, substr_count($content, 'id="export-records"'));
$this->assertEquals(1, substr_count($content, 'id="summary-project"'));
@@ -82,7 +82,7 @@ class HtmlRendererTest extends AbstractRendererTest
$this->assertStringContainsString('<td>Customer Name</td>', $content);
$this->assertStringContainsString('<td>project name</td>', $content);
$this->assertStringContainsString('<span class="duration-format" data-duration="7000">01:56 h</span>', $content);
$this->assertStringContainsString('<span class="duration-format" data-duration-decimal="1.94" data-duration="1:56">1:56</span>', $content);
$this->assertStringContainsString('<td class="cost summary-rate">€2,437.12</td>', $content);
$this->assertStringContainsString('-€100.92', $content);

View File

@@ -11,8 +11,8 @@ namespace App\Tests\Export\Renderer;
use App\Export\Renderer\PDFRenderer;
use App\Export\Renderer\PdfRendererFactory;
use App\Pdf\HtmlToPdfConverter;
use App\Project\ProjectStatisticService;
use App\Utils\HtmlToPdfConverter;
use PHPUnit\Framework\TestCase;
use Twig\Environment;

View File

@@ -10,12 +10,11 @@
namespace App\Tests\Export\Renderer;
use App\Export\Renderer\PDFRenderer;
use App\Pdf\HtmlToPdfConverter;
use App\Pdf\MPdfConverter;
use App\Project\ProjectStatisticService;
use App\Tests\Mocks\FileHelperFactory;
use App\Utils\HtmlToPdfConverter;
use App\Utils\MPdfConverter;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Twig\Environment;
/**
@@ -26,22 +25,6 @@ use Twig\Environment;
*/
class PdfRendererTest extends AbstractRendererTest
{
public function testDisposition()
{
$sut = new PDFRenderer(
$this->createMock(Environment::class),
$this->createMock(HtmlToPdfConverter::class),
$this->createMock(ProjectStatisticService::class)
);
$this->assertEquals(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $sut->getDisposition());
$sut->setDispositionInline(false);
$this->assertEquals(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $sut->getDisposition());
$sut->setDispositionInline(true);
$this->assertEquals(ResponseHeaderBag::DISPOSITION_INLINE, $sut->getDisposition());
$sut->setDispositionInline(false);
$this->assertEquals(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $sut->getDisposition());
}
public function testConfiguration()
{
$sut = new PDFRenderer(
@@ -64,8 +47,8 @@ class PdfRendererTest extends AbstractRendererTest
{
$kernel = self::bootKernel();
/** @var Environment $twig */
$twig = $kernel->getContainer()->get('twig');
$stack = $kernel->getContainer()->get('request_stack');
$twig = self::getContainer()->get('twig');
$stack = self::getContainer()->get('request_stack');
$cacheDir = $kernel->getContainer()->getParameter('kernel.cache_dir');
$converter = new MPdfConverter((new FileHelperFactory($this))->create(), $cacheDir);
$request = new Request();
@@ -74,12 +57,15 @@ class PdfRendererTest extends AbstractRendererTest
$sut = new PDFRenderer($twig, $converter, $this->createMock(ProjectStatisticService::class));
$response = $this->render($sut);
$prefix = date('Ymd');
$response = $this->render($sut);
$this->assertEquals('application/pdf', $response->headers->get('Content-Type'));
$this->assertEquals('attachment; filename=' . $prefix . '-Customer_Name-project_name.pdf', $response->headers->get('Content-Disposition'));
$this->assertNotEmpty($response->getContent());
$sut->setDispositionInline(true);
$response = $this->render($sut);
$this->assertEquals('inline; filename=' . $prefix . '-Customer_Name-project_name.pdf', $response->headers->get('Content-Disposition'));
}
}

View File

@@ -17,7 +17,6 @@ use Symfony\Component\HttpFoundation\BinaryFileResponse;
* @covers \App\Export\Base\AbstractSpreadsheetRenderer
* @covers \App\Export\Base\RendererTrait
* @covers \App\Export\Renderer\XlsxRenderer
* @covers \App\Export\Renderer\AbstractSpreadsheetRenderer
* @group integration
*/
class XlsxRendererTest extends AbstractRendererTest

View File

@@ -14,7 +14,6 @@ use App\Entity\Project;
use App\Export\Spreadsheet\AnnotatedObjectExporter;
use App\Export\Spreadsheet\Extractor\AnnotationExtractor;
use App\Export\Spreadsheet\SpreadsheetExporter;
use Doctrine\Common\Annotations\AnnotationReader;
use PHPUnit\Framework\TestCase;
use Symfony\Contracts\Translation\TranslatorInterface;
@@ -26,11 +25,11 @@ class AnnotatedObjectExporterTest extends TestCase
public function testExport()
{
$spreadsheetExporter = new SpreadsheetExporter($this->createMock(TranslatorInterface::class));
$annotationExtractor = new AnnotationExtractor(new AnnotationReader());
$annotationExtractor = new AnnotationExtractor();
$project = new Project();
$project->setName('test project');
$project->setCustomer((new Customer())->setName('A customer'));
$project->setCustomer(new Customer('A customer'));
$project->setComment('Lorem Ipsum');
$project->setOrderNumber('1234567890');
$project->setBudget(123456.7890);

View File

@@ -11,39 +11,26 @@ namespace App\Tests\Export\Spreadsheet\Entities;
use App\Export\Annotation as Exporter;
/**
* @Exporter\Order({"a-time", "publicProperty", "a-date", "something", "privateProperty"})
* @Exporter\Expose("accessor", label="label.accessor", exp="object.accessorMethod()")
* @Exporter\Expose("a-date", label="label.type-date", exp="object.getDateTime()", type="date")
* @Exporter\Expose("a-time", label="label.type-time", exp="object.getDateTime()", type="time")
*/
#[Exporter\Order(['a-time', 'publicProperty', 'a-date', 'something', 'privateProperty'])]
#[Exporter\Expose(name: 'accessor', label: 'accessor', exp: 'object.accessorMethod()')]
#[Exporter\Expose(name: 'a-date', label: 'type-date', exp: 'object.getDateTime()', type: 'date')]
#[Exporter\Expose(name: 'a-time', label: 'type-time', exp: 'object.getDateTime()', type: 'time')]
class DemoFull
{
/**
* @Exporter\Expose(label="label.Public-Property", type="string")
*/
public $publicProperty = 'public-property';
/**
* @Exporter\Expose("fake-name", label="label.Protected-Property", type="boolean")
*/
protected $protectedProperty = false;
/**
* @Exporter\Expose(label="label.Private-Property", type="integer")
* @phpstan-ignore-next-line
*/
private $privateProperty = 123;
#[Exporter\Expose(label: 'Public-Property', type: 'string')]
public string $publicProperty = 'public-property';
#[Exporter\Expose(name: 'fake-name', label: 'Protected-Property', type: 'boolean')]
protected bool $protectedProperty = false;
#[Exporter\Expose(label: 'Private-Property', type: 'integer')]
private int $privateProperty = 123; // @phpstan-ignore-line
/**
* @Exporter\Expose(label="label.Public-Method")
*/
#[Exporter\Expose(label: 'Public-Method')]
public function publicMethod(): string
{
return 'public-method';
}
/**
* @Exporter\Expose(label="label.Protected-Method", type="datetime")
*/
#[Exporter\Expose(label: 'Protected-Method', type: 'datetime')]
protected function protectedMethod(): \DateTime
{
return new \DateTime();
@@ -54,18 +41,14 @@ class DemoFull
return new \DateTime();
}
/**
* @Exporter\Expose("renamedDuration", label="label.duration", type="duration")
*/
#[Exporter\Expose(name: 'renamedDuration', label: 'duration', type: 'duration')]
protected function duration(): int
{
return 12345;
}
/**
* @Exporter\Expose(name="fake-method", label="label.Private-Method", type="boolean")
* @phpstan-ignore-next-line
*/
// @phpstan-ignore-next-line
#[Exporter\Expose(name: 'fake-method', label: 'Private-Method', type: 'boolean')]
private function privateMethod(): bool
{
return true;

View File

@@ -13,9 +13,7 @@ use App\Export\Annotation as Exporter;
class ExpressionOnMethod
{
/**
* @Exporter\Expose("accessor", label="label.accessor", exp="object.foo")
*/
#[Exporter\Expose(name: 'accessor', label: 'accessor', exp: 'object.foo')]
public function foo()
{
}

View File

@@ -13,9 +13,6 @@ use App\Export\Annotation as Exporter;
class ExpressionOnProperty
{
/**
* @Exporter\Expose("accessor", label="label.accessor", exp="object.foo")
* @phpstan-ignore-next-line
*/
private $foo;
#[Exporter\Expose(name: 'accessor', label: 'accessor', exp: 'object.foo')]
private $foo; // @phpstan-ignore-line
}

View File

@@ -13,9 +13,7 @@ use App\Export\Annotation as Exporter;
class MethodRequiresParams
{
/**
* @Exporter\Expose("accessor", label="label.accessor")
*/
#[Exporter\Expose(name: 'accessor', label: 'accessor')]
public function foo(string $foo)
{
}

View File

@@ -11,9 +11,7 @@ namespace App\Tests\Export\Spreadsheet\Entities;
use App\Export\Annotation as Exporter;
/**
* @Exporter\Expose("accessor", label="label.accessor")
*/
#[Exporter\Expose(name: 'accessor', label: 'accessor')]
class MissingExpressionOnClass
{
}

View File

@@ -11,9 +11,7 @@ namespace App\Tests\Export\Spreadsheet\Entities;
use App\Export\Annotation as Exporter;
/**
* @Exporter\Expose(label="label.accessor", exp="foo")
*/
#[Exporter\Expose(label: 'accessor', exp: 'foo')]
class MissingNameOnClass
{
}

View File

@@ -18,7 +18,6 @@ use App\Export\Spreadsheet\Extractor\AnnotationExtractor;
use App\Export\Spreadsheet\Extractor\MetaFieldExtractor;
use App\Export\Spreadsheet\SpreadsheetExporter;
use App\Repository\Query\ProjectQuery;
use Doctrine\Common\Annotations\AnnotationReader;
use PHPUnit\Framework\TestCase;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
@@ -35,15 +34,17 @@ class EntityWithMetaFieldsExporterTest extends TestCase
$event->addField((new ProjectMeta())->setName('foo meta')->setIsVisible(true));
$event->addField((new ProjectMeta())->setName('hidden meta')->setIsVisible(false));
$event->addField((new ProjectMeta())->setName('bar meta')->setIsVisible(true));
return $event;
});
$spreadsheetExporter = new SpreadsheetExporter($this->createMock(TranslatorInterface::class));
$annotationExtractor = new AnnotationExtractor(new AnnotationReader());
$annotationExtractor = new AnnotationExtractor();
$metaFieldExtractor = new MetaFieldExtractor($dispatcher);
$project = new Project();
$project->setName('test project');
$project->setCustomer((new Customer())->setName('A customer'));
$project->setCustomer(new Customer('A customer'));
$project->setComment('Lorem Ipsum');
$project->setOrderNumber('1234567890');
$project->setBudget(123456.7890);

View File

@@ -18,7 +18,6 @@ use App\Tests\Export\Spreadsheet\Entities\ExpressionOnProperty;
use App\Tests\Export\Spreadsheet\Entities\MethodRequiresParams;
use App\Tests\Export\Spreadsheet\Entities\MissingExpressionOnClass;
use App\Tests\Export\Spreadsheet\Entities\MissingNameOnClass;
use Doctrine\Common\Annotations\AnnotationReader;
use PHPUnit\Framework\TestCase;
/**
@@ -31,7 +30,7 @@ class AnnotationExtractorTest extends TestCase
{
public function testExtract()
{
$sut = new AnnotationExtractor(new AnnotationReader());
$sut = new AnnotationExtractor();
$columns = $sut->extract(DemoFull::class);
@@ -43,16 +42,16 @@ class AnnotationExtractorTest extends TestCase
}
$expected = [
['label.type-time', 'time', new \DateTime()],
['label.Public-Property', 'string', 'public-property'],
['label.type-date', 'date', new \DateTime()],
['label.Private-Property', 'integer', 123],
['label.accessor', 'string', 'accessor-method'],
['label.Protected-Property', 'boolean', false],
['label.Public-Method', 'string', 'public-method'],
['label.Protected-Method', 'datetime', new \DateTime()],
['label.duration', 'duration', 12345],
['label.Private-Method', 'boolean', true],
['type-time', 'time', new \DateTime()],
['Public-Property', 'string', 'public-property'],
['type-date', 'date', new \DateTime()],
['Private-Property', 'integer', 123],
['accessor', 'string', 'accessor-method'],
['Protected-Property', 'boolean', false],
['Public-Method', 'string', 'public-method'],
['Protected-Method', 'datetime', new \DateTime()],
['duration', 'duration', 12345],
['Private-Method', 'boolean', true],
];
$i = 0;
@@ -72,7 +71,7 @@ class AnnotationExtractorTest extends TestCase
public function testExceptionOnInvalidType()
{
$sut = new AnnotationExtractor(new AnnotationReader());
$sut = new AnnotationExtractor();
$this->expectException(ExtractorException::class);
$this->expectExceptionMessage('AnnotationExtractor needs a non-empty class name for work');
@@ -83,7 +82,7 @@ class AnnotationExtractorTest extends TestCase
public function testExceptionOnEmptyString()
{
$sut = new AnnotationExtractor(new AnnotationReader());
$sut = new AnnotationExtractor();
$this->expectException(ExtractorException::class);
$this->expectExceptionMessage('AnnotationExtractor needs a non-empty class name for work');
@@ -93,50 +92,50 @@ class AnnotationExtractorTest extends TestCase
public function testExceptionOnMissingExpression()
{
$sut = new AnnotationExtractor(new AnnotationReader());
$sut = new AnnotationExtractor();
$this->expectException(ExtractorException::class);
$this->expectExceptionMessage('@Expose needs an expression attribute on class level hierarchy, check App\Tests\Export\Spreadsheet\Entities\MissingExpressionOnClass::class');
$this->expectExceptionMessage('@Expose needs the "exp" attribute on class level hierarchy, check App\Tests\Export\Spreadsheet\Entities\MissingExpressionOnClass::class');
$sut->extract(MissingExpressionOnClass::class);
}
public function testExceptionOnMissingName()
{
$sut = new AnnotationExtractor(new AnnotationReader());
$sut = new AnnotationExtractor();
$this->expectException(ExtractorException::class);
$this->expectExceptionMessage('@Expose needs a name attribute on class level hierarchy, check App\Tests\Export\Spreadsheet\Entities\MissingNameOnClass::class');
$this->expectExceptionMessage('@Expose needs the "name" attribute on class level hierarchy, check App\Tests\Export\Spreadsheet\Entities\MissingNameOnClass::class');
$sut->extract(MissingNameOnClass::class);
}
public function testExceptionExpressionOnProperty()
{
$sut = new AnnotationExtractor(new AnnotationReader());
$sut = new AnnotationExtractor();
$this->expectException(ExtractorException::class);
$this->expectExceptionMessage('@Expose only supports the expression attribute on class level hierarchy, check App\Tests\Export\Spreadsheet\Entities\ExpressionOnProperty::$foo');
$this->expectExceptionMessage('@Expose only supports the "exp" attribute on class level hierarchy, check App\Tests\Export\Spreadsheet\Entities\ExpressionOnProperty::$foo');
$sut->extract(ExpressionOnProperty::class);
}
public function testExceptionExpressionOnMethod()
{
$sut = new AnnotationExtractor(new AnnotationReader());
$sut = new AnnotationExtractor();
$this->expectException(ExtractorException::class);
$this->expectExceptionMessage('@Expose only supports the expression attribute on class level hierarchy, check App\Tests\Export\Spreadsheet\Entities\ExpressionOnMethod::foo()');
$this->expectExceptionMessage('@Expose only supports the "exp" attribute on method level hierarchy, check App\Tests\Export\Spreadsheet\Entities\ExpressionOnMethod::foo()');
$sut->extract(ExpressionOnMethod::class);
}
public function testExceptionExpressionOnMethodWithRequiredParameters()
{
$sut = new AnnotationExtractor(new AnnotationReader());
$sut = new AnnotationExtractor();
$this->expectException(ExtractorException::class);
$this->expectExceptionMessage('@Expose does not support method App\Tests\Export\Spreadsheet\Entities\MethodRequiresParams::foo(...), it has required parameters.');
$this->expectExceptionMessage('@Expose does not support method App\Tests\Export\Spreadsheet\Entities\MethodRequiresParams::foo(...) as it has required parameters.');
$sut->extract(MethodRequiresParams::class);
}

View File

@@ -32,6 +32,8 @@ class MetaFieldExtractorTest extends TestCase
$event->addField((new ProjectMeta())->setName('foo')->setIsVisible(true));
$event->addField((new ProjectMeta())->setName('no')->setIsVisible(false));
$event->addField((new ProjectMeta())->setName('bar')->setIsVisible(true));
return $event;
});
$sut = new MetaFieldExtractor($dispatcher);

View File

@@ -28,9 +28,11 @@ class UserPreferenceExtractorTest extends TestCase
{
$dispatcher = $this->createMock(EventDispatcherInterface::class);
$dispatcher->expects(self::once())->method('dispatch')->willReturnCallback(function (UserPreferenceDisplayEvent $event) {
$event->addPreference((new UserPreference())->setName('foo')->setEnabled(true));
$event->addPreference((new UserPreference())->setName('no')->setEnabled(false));
$event->addPreference((new UserPreference())->setName('bar')->setEnabled(true));
$event->addPreference(new UserPreference('foo'));
$event->addPreference((new UserPreference('no'))->setEnabled(false));
$event->addPreference(new UserPreference('bar'));
return $event;
});
$sut = new UserPreferenceExtractor($dispatcher);
@@ -49,7 +51,7 @@ class UserPreferenceExtractorTest extends TestCase
$definition = $columns[1];
self::assertEquals('bar', $definition->getLabel());
self::assertEquals('string', $definition->getType());
self::assertEquals('tralalalala', \call_user_func($definition->getAccessor(), (new User())->addPreference((new UserPreference())->setName('bar')->setValue('tralalalala'))));
self::assertEquals('tralalalala', \call_user_func($definition->getAccessor(), (new User())->addPreference((new UserPreference('bar', 'tralalalala')))));
}
public function testCheckType()

View File

@@ -15,7 +15,6 @@ use App\Export\Spreadsheet\Extractor\AnnotationExtractor;
use App\Export\Spreadsheet\Extractor\UserPreferenceExtractor;
use App\Export\Spreadsheet\SpreadsheetExporter;
use App\Export\Spreadsheet\UserExporter;
use Doctrine\Common\Annotations\AnnotationReader;
use PHPUnit\Framework\TestCase;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
@@ -28,12 +27,12 @@ class UserExporterTest extends TestCase
public function testExport()
{
$spreadsheetExporter = new SpreadsheetExporter($this->createMock(TranslatorInterface::class));
$annotationExtractor = new AnnotationExtractor(new AnnotationReader());
$annotationExtractor = new AnnotationExtractor();
$userPreferenceExtractor = new UserPreferenceExtractor($this->createMock(EventDispatcherInterface::class));
$user = new User();
$user->setAccountNumber('F-747864');
$user->setUsername('test user');
$user->setUserIdentifier('test user');
$user->setAvatar('Lorem Ipsum');
$user->setTimezone('Europe/Berlin');
$user->setColor('#ececec');

View File

@@ -9,7 +9,7 @@
namespace App\Tests\Export\Timesheet;
use App\Configuration\LanguageFormattings;
use App\Configuration\LocaleService;
use App\Entity\Activity;
use App\Entity\ActivityMeta;
use App\Entity\Customer;
@@ -46,17 +46,20 @@ abstract class AbstractRendererTest extends KernelTestCase
$languages = [
'en' => [
'date' => 'Y.m.d',
'duration' => '%h:%m h',
'duration' => '%h:%m',
'time' => 'H:i',
]
];
$user = new User();
$user->setUserIdentifier('ssdf');
$security = $this->createMock(Security::class);
$security->expects($this->any())->method('getUser')->willReturn(new User());
$security->expects($this->any())->method('getUser')->willReturn($user);
$security->expects($this->any())->method('isGranted')->willReturn(true);
$translator = $this->getMockBuilder(TranslatorInterface::class)->getMock();
$dateExtension = new LocaleFormatExtensions(new LanguageFormattings($languages), $security);
$dateExtension = new LocaleFormatExtensions(new LocaleService($languages), $security);
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new MetaFieldColumnSubscriber());
@@ -70,8 +73,7 @@ abstract class AbstractRendererTest extends KernelTestCase
*/
protected function render(TimesheetExportInterface $renderer)
{
$customer = new Customer();
$customer->setName('Customer Name');
$customer = new Customer('Customer Name');
$customer->setNumber('A-0123456789');
$customer->setVatId('DE-9876543210');
$customer->setMetaField((new CustomerMeta())->setName('customer-foo')->setValue('customer-bar')->setIsVisible(true));
@@ -88,15 +90,17 @@ abstract class AbstractRendererTest extends KernelTestCase
$activity->setProject($project);
$activity->setMetaField((new ActivityMeta())->setName('activity-foo')->setValue('activity-bar')->setIsVisible(true));
$userMethods = ['getId', 'getPreferenceValue', 'getUsername'];
$userMethods = ['getId', 'getPreferenceValue', 'getUsername', 'getUserIdentifier'];
$user1 = $this->getMockBuilder(User::class)->onlyMethods($userMethods)->disableOriginalConstructor()->getMock();
$user1->method('getId')->willReturn(1);
$user1->method('getPreferenceValue')->willReturn('50');
$user1->method('getUsername')->willReturn('foo-bar');
$user1->method('getUserIdentifier')->willReturn('foo-bar');
$user2 = $this->getMockBuilder(User::class)->onlyMethods($userMethods)->disableOriginalConstructor()->getMock();
$user2->method('getId')->willReturn(2);
$user2->method('getUsername')->willReturn('hello-world');
$user2->method('getUserIdentifier')->willReturn('hello-world');
$timesheet = new Timesheet();
$timesheet
@@ -143,11 +147,14 @@ abstract class AbstractRendererTest extends KernelTestCase
->addTag((new Tag())->setName('foo'))
;
$user = new User();
$user->setUserIdentifier('kevin');
$timesheet5 = new Timesheet();
$timesheet5
->setDuration(400)
->setFixedRate(84)
->setUser((new User())->setUsername('kevin'))
->setUser($user)
->setActivity($activity)
->setProject($project)
->setBegin(new \DateTime('2019-06-16 12:00:00'))

View File

@@ -38,8 +38,8 @@ class HtmlRendererTest extends AbstractRendererTest
{
$kernel = self::bootKernel();
/** @var Environment $twig */
$twig = $kernel->getContainer()->get('twig');
$stack = $kernel->getContainer()->get('request_stack');
$twig = self::getContainer()->get('twig');
$stack = self::getContainer()->get('request_stack');
$request = new Request();
$request->setLocale('en');
$stack->push($request);
@@ -55,6 +55,6 @@ class HtmlRendererTest extends AbstractRendererTest
$content = $response->getContent();
$this->assertStringContainsString('>01:50 h<', $content);
$this->assertStringContainsString('>1:50<', $content);
}
}

View File

@@ -10,10 +10,10 @@
namespace App\Tests\Export\Timesheet;
use App\Export\Timesheet\PDFRenderer;
use App\Pdf\HtmlToPdfConverter;
use App\Pdf\MPdfConverter;
use App\Project\ProjectStatisticService;
use App\Tests\Mocks\FileHelperFactory;
use App\Utils\HtmlToPdfConverter;
use App\Utils\MPdfConverter;
use Symfony\Component\HttpFoundation\Request;
use Twig\Environment;
@@ -40,8 +40,8 @@ class PdfRendererTest extends AbstractRendererTest
{
$kernel = self::bootKernel();
/** @var Environment $twig */
$twig = $kernel->getContainer()->get('twig');
$stack = $kernel->getContainer()->get('request_stack');
$twig = self::getContainer()->get('twig');
$stack = self::getContainer()->get('request_stack');
$cacheDir = $kernel->getContainer()->getParameter('kernel.cache_dir');
$converter = new MPdfConverter((new FileHelperFactory($this))->create(), $cacheDir);
$request = new Request();

View File

@@ -31,11 +31,10 @@ class TimesheetExportRepositoryTest extends TestCase
$sut = new TimesheetExportRepository($repository);
/* @phpstan-ignore-next-line */
$sut->setExported([new Timesheet(), null, new \stdClass(), new Timesheet(), new Activity()]);
// test else for empty array
/* @phpstan-ignore-next-line */
$sut->setExported([new Customer(), new Project()]);
$sut->setExported([new Customer('foo'), new Project()]);
}
public function testSetType()