Release 2.32 (#5411)
* bump packages * dynamic invoice options * make sure that invoice previews can be detected * support for mpdf associated files * do not include any future times in work contract calculation * re-add username column in Excel spreadsheet * deactivate internal rate editing * show if plugin update exists * shorten name to Kimai only, without Time-Tracking * remove check for existing id in work contract * fix metafield already defined in search * helper methods to unlock months * new translation * send event on unlock month
This commit is contained in:
@@ -51,7 +51,7 @@ class PasswordResetControllerTest extends AbstractControllerBaseTestCase
|
||||
|
||||
$content = $response->getContent();
|
||||
self::assertNotFalse($content);
|
||||
self::assertStringContainsString('<title>Kimai – Time Tracking</title>', $content);
|
||||
self::assertStringContainsString('<title>Kimai</title>', $content);
|
||||
self::assertStringContainsString('Reset your password', $content);
|
||||
self::assertStringContainsString('<form class="card-body security-password-reset" action="/en/resetting/send-email" method="post" autocomplete="off">', $content);
|
||||
self::assertStringContainsString('<input autocomplete="username" type="text"', $content);
|
||||
|
||||
@@ -45,7 +45,7 @@ class SecurityControllerTest extends AbstractControllerBaseTestCase
|
||||
self::assertTrue($client->getResponse()->isSuccessful());
|
||||
|
||||
$content = $response->getContent();
|
||||
self::assertStringContainsString('<title>Kimai – Time Tracking</title>', $content);
|
||||
self::assertStringContainsString('<title>Kimai</title>', $content);
|
||||
self::assertStringContainsString('<form action="/en/login_check" method="post"', $content);
|
||||
self::assertStringContainsString('<input autocomplete="username" type="text" id="username" name="_username"', $content);
|
||||
self::assertStringContainsString('<input autocomplete="new-password" id="password" name="_password" type="password"', $content);
|
||||
|
||||
@@ -56,7 +56,7 @@ class SelfRegistrationControllerTest extends AbstractControllerBaseTestCase
|
||||
self::assertTrue($response->isSuccessful());
|
||||
|
||||
$content = $response->getContent();
|
||||
self::assertStringContainsString('<title>Kimai – Time Tracking</title>', $content);
|
||||
self::assertStringContainsString('<title>Kimai</title>', $content);
|
||||
self::assertStringContainsString('Register a new account', $content);
|
||||
self::assertStringContainsString('<form name="user_registration_form" method="post" action="/en/register/"', $content);
|
||||
self::assertStringContainsString('<input type="email"', $content);
|
||||
@@ -115,7 +115,7 @@ class SelfRegistrationControllerTest extends AbstractControllerBaseTestCase
|
||||
$this->createUser($client, 'example', 'register@example.com', 'test1234');
|
||||
|
||||
$content = $client->getResponse()->getContent();
|
||||
self::assertStringContainsString('<title>Kimai – Time Tracking</title>', $content);
|
||||
self::assertStringContainsString('<title>Kimai</title>', $content);
|
||||
self::assertStringContainsString('An e-mail has been sent to register@example.com. It contains a link you must click to activate your account.', $content);
|
||||
self::assertStringContainsString('<a href="/en/login">', $content);
|
||||
}
|
||||
|
||||
@@ -21,14 +21,14 @@ class ThemeJavascriptTranslationsEventTest extends TestCase
|
||||
|
||||
public function testDefaultValues(): void
|
||||
{
|
||||
$sut = new ThemeJavascriptTranslationsEvent();
|
||||
$sut = new ThemeJavascriptTranslationsEvent(); // @phpstan-ignore new.deprecated
|
||||
|
||||
self::assertCount(self::COUNTER, $sut->getTranslations());
|
||||
}
|
||||
|
||||
public function testGetterAndSetter(): void
|
||||
{
|
||||
$sut = new ThemeJavascriptTranslationsEvent();
|
||||
$sut = new ThemeJavascriptTranslationsEvent(); // @phpstan-ignore new.deprecated
|
||||
$sut->setTranslation('foo', 'bar');
|
||||
$sut->setTranslation('hello', 'world', 'testing');
|
||||
|
||||
|
||||
34
tests/Event/WorkingTimeApproveMonthEventTest.php
Normal file
34
tests/Event/WorkingTimeApproveMonthEventTest.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?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\Event;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Event\WorkingTimeApproveMonthEvent;
|
||||
use App\WorkingTime\Model\Month;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @covers \App\Event\WorkingTimeApproveMonthEvent
|
||||
*/
|
||||
class WorkingTimeApproveMonthEventTest extends TestCase
|
||||
{
|
||||
public function testGetter(): void
|
||||
{
|
||||
$user = new User();
|
||||
$approver = new User();
|
||||
$approvalMonth = new Month(new \DateTimeImmutable('2023-02-10'), $user);
|
||||
|
||||
$sut = new WorkingTimeApproveMonthEvent($approvalMonth, $approver);
|
||||
|
||||
self::assertSame($user, $sut->getUser()); // @phpstan-ignore method.deprecated
|
||||
self::assertSame($approvalMonth, $sut->getMonth());
|
||||
self::assertSame($approver, $sut->getApprovedBy());
|
||||
}
|
||||
}
|
||||
33
tests/Event/WorkingTimeUnlockMonthEventTest.php
Normal file
33
tests/Event/WorkingTimeUnlockMonthEventTest.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\Event;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Event\WorkingTimeUnlockMonthEvent;
|
||||
use App\WorkingTime\Model\Month;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @covers \App\Event\WorkingTimeUnlockMonthEvent
|
||||
*/
|
||||
class WorkingTimeUnlockMonthEventTest extends TestCase
|
||||
{
|
||||
public function testGetter(): void
|
||||
{
|
||||
$user = new User();
|
||||
$approver = new User();
|
||||
$approvalMonth = new Month(new \DateTimeImmutable('2023-02-10'), $user);
|
||||
|
||||
$sut = new WorkingTimeUnlockMonthEvent($approvalMonth, $approver);
|
||||
|
||||
self::assertSame($approvalMonth, $sut->getMonth());
|
||||
self::assertSame($approver, $sut->getUnlockedBy());
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ abstract class AbstractActionsSubscriberTestCase extends TestCase
|
||||
protected function createSubscriber(string $className, ...$grants): AbstractActionsSubscriber
|
||||
{
|
||||
$auth = $this->createMock(AuthorizationCheckerInterface::class);
|
||||
$auth->method('isGranted')->willReturnOnConsecutiveCalls(...$grants);
|
||||
$auth->method('isGranted')->willReturnOnConsecutiveCalls(...$grants); // @phpstan-ignore argument.named
|
||||
$router = $this->createMock(UrlGeneratorInterface::class);
|
||||
$router->method('generate')->willReturnArgument(0);
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ class EmailSubscriberTest extends TestCase
|
||||
$events = EmailSubscriber::getSubscribedEvents();
|
||||
self::assertArrayHasKey(EmailEvent::class, $events);
|
||||
$methodName = $events[EmailEvent::class][0];
|
||||
self::assertIsString($methodName);
|
||||
self::assertTrue(method_exists(EmailSubscriber::class, $methodName));
|
||||
}
|
||||
|
||||
|
||||
@@ -31,10 +31,12 @@ class LastLoginSubscriberTest extends TestCase
|
||||
|
||||
self::assertArrayHasKey(UserInteractiveLoginEvent::class, $events);
|
||||
$methodName = $events[UserInteractiveLoginEvent::class];
|
||||
self::assertIsString($methodName);
|
||||
self::assertTrue(method_exists(LastLoginSubscriber::class, $methodName));
|
||||
|
||||
self::assertArrayHasKey(LoginSuccessEvent::class, $events);
|
||||
$methodName = $events[LoginSuccessEvent::class];
|
||||
self::assertIsString($methodName);
|
||||
self::assertTrue(method_exists(LastLoginSubscriber::class, $methodName));
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ class MenuSubscriberTest extends TestCase
|
||||
$events = MenuSubscriber::getSubscribedEvents();
|
||||
self::assertArrayHasKey(ConfigureMainMenuEvent::class, $events);
|
||||
$methodName = $events[ConfigureMainMenuEvent::class][0];
|
||||
self::assertIsString($methodName);
|
||||
self::assertTrue(method_exists(MenuSubscriber::class, $methodName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ class PagerfantaExceptionSubscriberTest extends TestCase
|
||||
$events = PagerfantaExceptionSubscriber::getSubscribedEvents();
|
||||
self::assertArrayHasKey(KernelEvents::EXCEPTION, $events);
|
||||
$methodName = $events[KernelEvents::EXCEPTION][0];
|
||||
self::assertIsString($methodName);
|
||||
self::assertTrue(method_exists(PagerfantaExceptionSubscriber::class, $methodName));
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ class ProfileSubscriberTest extends TestCase
|
||||
|
||||
self::assertArrayHasKey(LoginSuccessEvent::class, $events);
|
||||
$methodName = $events[LoginSuccessEvent::class];
|
||||
self::assertIsString($methodName);
|
||||
self::assertTrue(method_exists(LastLoginSubscriber::class, $methodName));
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ class UserDetailsSubscriberTest extends TestCase
|
||||
$events = UserDetailsSubscriber::getSubscribedEvents();
|
||||
self::assertArrayHasKey(UserDetailsEvent::class, $events);
|
||||
$methodName = $events[UserDetailsEvent::class][0];
|
||||
self::assertIsString($methodName);
|
||||
self::assertTrue(method_exists(UserDetailsSubscriber::class, $methodName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ class UserPreferenceSubscriberTest extends TestCase
|
||||
$events = UserPreferenceSubscriber::getSubscribedEvents();
|
||||
self::assertArrayHasKey(PrepareUserEvent::class, $events);
|
||||
$methodName = $events[PrepareUserEvent::class][0];
|
||||
self::assertIsString($methodName);
|
||||
self::assertTrue(method_exists(UserPreferenceSubscriber::class, $methodName));
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ class WizardSubscriberTest extends TestCase
|
||||
$events = WizardSubscriber::getSubscribedEvents();
|
||||
self::assertArrayHasKey(KernelEvents::REQUEST, $events);
|
||||
$methodName = $events[KernelEvents::REQUEST][0];
|
||||
self::assertIsString($methodName);
|
||||
self::assertTrue(method_exists(WizardSubscriber::class, $methodName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ class CsvRendererTest extends AbstractRendererTestCase
|
||||
'0',
|
||||
'0',
|
||||
'84',
|
||||
'Kevin',
|
||||
'kevin',
|
||||
'',
|
||||
'Customer Name',
|
||||
@@ -142,6 +143,7 @@ class CsvRendererTest extends AbstractRendererTestCase
|
||||
'0',
|
||||
'0',
|
||||
'-100.92',
|
||||
'niveK',
|
||||
'nivek',
|
||||
'',
|
||||
'Customer Name',
|
||||
@@ -168,6 +170,6 @@ class CsvRendererTest extends AbstractRendererTestCase
|
||||
self::assertEquals($expected, $all[5]);
|
||||
self::assertEquals($expected2, $all[6]);
|
||||
self::assertEquals(\count($expected), \count($all[0]));
|
||||
self::assertEquals('foo', $all[4][16]);
|
||||
self::assertEquals('foo', $all[4][17]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,17 +52,19 @@ abstract class AbstractRendererTestCase extends KernelTestCase
|
||||
$activity->setProject($project);
|
||||
$activity->setMetaField((new ActivityMeta())->setName('activity-foo')->setValue('activity-bar')->setIsVisible(true));
|
||||
|
||||
$userMethods = ['getId', 'getPreferenceValue', 'getUsername', 'getUserIdentifier'];
|
||||
$userMethods = ['getId', 'getPreferenceValue', 'getUsername', 'getUserIdentifier', 'getAlias'];
|
||||
$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('getAlias')->willReturn('Foo Bar');
|
||||
$user1->method('getUserIdentifier')->willReturn('foo-bar');
|
||||
$user1->method('getUsername')->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('getAlias')->willReturn('Hello World');
|
||||
$user2->method('getUserIdentifier')->willReturn('hello-world');
|
||||
$user2->method('getUsername')->willReturn('hello-world');
|
||||
|
||||
$timesheet = new Timesheet();
|
||||
$timesheet
|
||||
@@ -111,6 +113,7 @@ abstract class AbstractRendererTestCase extends KernelTestCase
|
||||
;
|
||||
|
||||
$userKevin = new User();
|
||||
$userKevin->setAlias('Kevin');
|
||||
$userKevin->setUserIdentifier('kevin');
|
||||
|
||||
$timesheet5 = new Timesheet();
|
||||
@@ -129,6 +132,7 @@ abstract class AbstractRendererTestCase extends KernelTestCase
|
||||
;
|
||||
|
||||
$userNivek = new User();
|
||||
$userNivek->setAlias('niveK');
|
||||
$userNivek->setUserIdentifier('nivek');
|
||||
|
||||
$timesheet6 = new Timesheet();
|
||||
|
||||
@@ -32,6 +32,8 @@ class InvoiceModelTest extends TestCase
|
||||
self::assertNotNull($sut->getCustomer());
|
||||
self::assertNotNull($sut->getTemplate());
|
||||
|
||||
self::assertFalse($sut->isPreview());
|
||||
self::assertFalse($sut->isHideZeroTax());
|
||||
self::assertNull($sut->getCalculator());
|
||||
self::assertEmpty($sut->getEntries());
|
||||
self::assertIsArray($sut->getEntries());
|
||||
@@ -43,6 +45,12 @@ class InvoiceModelTest extends TestCase
|
||||
$sut->setFormatter($newFormatter);
|
||||
self::assertNotSame($formatter, $sut->getFormatter());
|
||||
self::assertSame($newFormatter, $sut->getFormatter());
|
||||
self::assertEquals([], $sut->getOptions());
|
||||
|
||||
$sut->setPreview(true);
|
||||
$sut->setHideZeroTax(true);
|
||||
self::assertTrue($sut->isPreview());
|
||||
self::assertTrue($sut->isHideZeroTax());
|
||||
}
|
||||
|
||||
public function testEmptyObjectThrowsExceptionOnNumberGenerator(): void
|
||||
@@ -75,6 +83,23 @@ class InvoiceModelTest extends TestCase
|
||||
|
||||
self::assertSame($template, $sut->getTemplate());
|
||||
self::assertInstanceOf(\DateTimeInterface::class, $sut->getDueDate());
|
||||
|
||||
$sut->setOption('foo-int', 123);
|
||||
$sut->setOption('foo-float', 123.45);
|
||||
$sut->setOption('foo-string', '12345');
|
||||
$sut->setOption('foo-null', null);
|
||||
$sut->setOption('foo-bool', true);
|
||||
$sut->setOption('foo-array', ['foo' => 'bar']);
|
||||
$sut->setOption('foo-array2', ['foo', 'bar']);
|
||||
self::assertEquals([
|
||||
'foo-int' => 123,
|
||||
'foo-float' => 123.45,
|
||||
'foo-string' => '12345',
|
||||
'foo-null' => null,
|
||||
'foo-bool' => true,
|
||||
'foo-array' => ['foo' => 'bar'],
|
||||
'foo-array2' => ['foo', 'bar']
|
||||
], $sut->getOptions());
|
||||
}
|
||||
|
||||
public function testDueDate(): void
|
||||
|
||||
@@ -50,7 +50,7 @@ class ThemeEventExtensionTest extends TestCase
|
||||
];
|
||||
}
|
||||
|
||||
protected function getSut(bool $hasListener = true, string $title = null): ThemeExtension
|
||||
protected function getSut(bool $hasListener = true): ThemeExtension
|
||||
{
|
||||
$dispatcher = $this->createMock(EventDispatcherInterface::class);
|
||||
$dispatcher->method('hasListeners')->willReturn($hasListener);
|
||||
@@ -155,18 +155,6 @@ class ThemeEventExtensionTest extends TestCase
|
||||
public function testGetTitle(): void
|
||||
{
|
||||
$sut = $this->getSut(false);
|
||||
self::assertEquals('Kimai – foo', $sut->generateTitle());
|
||||
self::assertEquals('sdfsdf | Kimai – foo', $sut->generateTitle('sdfsdf | '));
|
||||
self::assertEquals('<b>Kimai</b> ... foo', $sut->generateTitle('<b>', '</b> ... '));
|
||||
self::assertEquals('Kimai | foo', $sut->generateTitle(null, ' | '));
|
||||
}
|
||||
|
||||
public function testGetBrandedTitle(): void
|
||||
{
|
||||
$sut = $this->getSut(false, 'MyCompany');
|
||||
self::assertEquals('Kimai – foo', $sut->generateTitle());
|
||||
self::assertEquals('sdfsdf | Kimai – foo', $sut->generateTitle('sdfsdf | '));
|
||||
self::assertEquals('<b>Kimai</b> ... foo', $sut->generateTitle('<b>', '</b> ... '));
|
||||
self::assertEquals('Kimai | foo', $sut->generateTitle(null, ' | '));
|
||||
self::assertEquals('Kimai', $sut->generateTitle());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1311,51 +1311,11 @@ parameters:
|
||||
count: 1
|
||||
path: EventSubscriber/Actions/AbstractActionsSubscriberTestCase.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$method of function method_exists expects string, array\\<int\\|string, int\\|string\\>\\|int\\|string given\\.$#"
|
||||
count: 1
|
||||
path: EventSubscriber/EmailSubscriberTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$method of function method_exists expects string, array\\<int\\|string, array\\<int\\|string, int\\|string\\>\\|int\\|string\\>\\|string given\\.$#"
|
||||
count: 2
|
||||
path: EventSubscriber/LastLoginSubscriberTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$method of function method_exists expects string, array\\<int\\|string, int\\|string\\>\\|int\\|string given\\.$#"
|
||||
count: 1
|
||||
path: EventSubscriber/MenuSubscriberTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$method of function method_exists expects string, array\\<int\\|string, int\\|string\\>\\|int\\|string given\\.$#"
|
||||
count: 1
|
||||
path: EventSubscriber/PagerfantaExceptionSubscriberTest.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\EventSubscriber\\\\ProfileSubscriberTest\\:\\:getInvalidCookies\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: EventSubscriber/ProfileSubscriberTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$method of function method_exists expects string, array\\<int\\|string, array\\<int\\|string, int\\|string\\>\\|int\\|string\\>\\|string given\\.$#"
|
||||
count: 1
|
||||
path: EventSubscriber/ProfileSubscriberTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$method of function method_exists expects string, array\\<int\\|string, int\\|string\\>\\|int\\|string given\\.$#"
|
||||
count: 1
|
||||
path: EventSubscriber/UserDetailsSubscriberTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$method of function method_exists expects string, array\\<int\\|string, int\\|string\\>\\|int\\|string given\\.$#"
|
||||
count: 1
|
||||
path: EventSubscriber/UserPreferenceSubscriberTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$method of function method_exists expects string, array\\<int\\|string, int\\|string\\>\\|int\\|string given\\.$#"
|
||||
count: 1
|
||||
path: EventSubscriber/WizardSubscriberTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$haystack of function substr_count expects string, string\\|false given\\.$#"
|
||||
count: 6
|
||||
|
||||
Reference in New Issue
Block a user