added fixed-rate and hourly-rate for customer, project and activity (#304)
This commit is contained in:
@@ -9,14 +9,45 @@
|
||||
|
||||
namespace App\Tests\Controller;
|
||||
|
||||
use App\Controller\ActivityController;
|
||||
use App\Entity\User;
|
||||
use App\Tests\DataFixtures\TimesheetFixtures;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \App\Controller\ActivityController
|
||||
* @group integration
|
||||
*/
|
||||
class ActivityControllerTest extends ControllerBaseTest
|
||||
{
|
||||
public function testIsSecure()
|
||||
public function testRecentActivitiesAction()
|
||||
{
|
||||
$this->markTestSkipped('no public route available');
|
||||
$kernel = self::bootKernel();
|
||||
$container = $kernel->getContainer();
|
||||
|
||||
$em = $container->get('doctrine.orm.entity_manager');
|
||||
$user = $em->getRepository(User::class)->getById(1);
|
||||
|
||||
$storage = new TokenStorage();
|
||||
$storage->setToken(new UsernamePasswordToken($user, [], 'foo'));
|
||||
$container->set('security.token_storage', $storage);
|
||||
|
||||
$fixture = new TimesheetFixtures();
|
||||
$fixture->setUser($user);
|
||||
$fixture->setAmount(1);
|
||||
$fixture->setStartDate(new \DateTime('-30 days'));
|
||||
$this->importFixture($em, $fixture);
|
||||
|
||||
$controller = $container->get(ActivityController::class);
|
||||
$controller->setContainer($container);
|
||||
$response = $controller->recentActivitiesAction();
|
||||
|
||||
$content = $response->getContent();
|
||||
|
||||
$this->assertTrue($response->isSuccessful());
|
||||
$this->assertContains('<li class="dropdown notifications-menu">', $content);
|
||||
$this->assertContains('<span class="label label-success">1</span>', $content);
|
||||
$this->assertContains('<a href="/en/timesheet/start/1">', $content);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,48 +48,59 @@ class ProfileControllerTest extends ControllerBaseTest
|
||||
$this->assertFalse($client->getResponse()->isSuccessful());
|
||||
}
|
||||
|
||||
public function testUpdateApiToken()
|
||||
public function testEditAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
|
||||
$this->request($client, '/profile/' . UserFixtures::USERNAME_USER);
|
||||
$this->request($client, '/profile/' . UserFixtures::USERNAME_USER . '/edit');
|
||||
|
||||
/** @var User $user */
|
||||
$user = $client->getContainer()->get('security.token_storage')->getToken()->getUser();
|
||||
/** @var EncoderFactoryInterface $passwordEncoder */
|
||||
$passwordEncoder = $client->getContainer()->get('test.PasswordEncoder');
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
$user = $this->getUserByRole($em, User::ROLE_USER);
|
||||
|
||||
$this->assertTrue($passwordEncoder->getEncoder($user)->isPasswordValid($user->getApiToken(), UserFixtures::DEFAULT_API_TOKEN, $user->getSalt()));
|
||||
$this->assertFalse($passwordEncoder->getEncoder($user)->isPasswordValid($user->getApiToken(), 'test123', $user->getSalt()));
|
||||
$this->assertEquals(UserFixtures::USERNAME_USER, $user->getUsername());
|
||||
$this->assertEquals('John Doe', $user->getAlias());
|
||||
$this->assertEquals('Developer', $user->getTitle());
|
||||
$this->assertEquals(UserFixtures::DEFAULT_AVATAR, $user->getAvatar());
|
||||
$this->assertEquals('john_user@example.com', $user->getEmail());
|
||||
$this->assertTrue($user->isEnabled());
|
||||
|
||||
$form = $client->getCrawler()->filter('form[name=user_api_token]')->form();
|
||||
$form = $client->getCrawler()->filter('form[name=user_edit]')->form();
|
||||
$client->submit($form, [
|
||||
'user_api_token' => [
|
||||
'plainApiToken' => [
|
||||
'first' => 'test123',
|
||||
'second' => 'test123',
|
||||
]
|
||||
'user_edit' => [
|
||||
'alias' => 'Johnny',
|
||||
'title' => 'Code Monkey',
|
||||
'avatar' => '/fake/image.jpg',
|
||||
'email' => 'updated@example.com',
|
||||
'enabled' => 0,
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertIsRedirect($client, $this->createUrl('/profile/' . urlencode(UserFixtures::USERNAME_USER)));
|
||||
$this->assertIsRedirect($client, $this->createUrl('/profile/' . urlencode(UserFixtures::USERNAME_USER) . '/edit'));
|
||||
$client->followRedirect();
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
|
||||
$this->assertHasFlashSuccess($client);
|
||||
|
||||
$user = $client->getContainer()->get('security.token_storage')->getToken()->getUser();
|
||||
$this->assertFalse($passwordEncoder->getEncoder($user)->isPasswordValid($user->getApiToken(), UserFixtures::DEFAULT_API_TOKEN, $user->getSalt()));
|
||||
$this->assertTrue($passwordEncoder->getEncoder($user)->isPasswordValid($user->getApiToken(), 'test123', $user->getSalt()));
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
$user = $this->getUserByRole($em, User::ROLE_USER);
|
||||
|
||||
$this->assertEquals(UserFixtures::USERNAME_USER, $user->getUsername());
|
||||
$this->assertEquals('Johnny', $user->getAlias());
|
||||
$this->assertEquals('Code Monkey', $user->getTitle());
|
||||
$this->assertEquals('/fake/image.jpg', $user->getAvatar());
|
||||
$this->assertEquals('updated@example.com', $user->getEmail());
|
||||
$this->assertFalse($user->isEnabled());
|
||||
}
|
||||
|
||||
public function testUpdatePassword()
|
||||
public function testPasswordAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
|
||||
$this->request($client, '/profile/' . UserFixtures::USERNAME_USER);
|
||||
$this->request($client, '/profile/' . UserFixtures::USERNAME_USER . '/password');
|
||||
|
||||
/** @var User $user */
|
||||
$user = $client->getContainer()->get('security.token_storage')->getToken()->getUser();
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
$user = $this->getUserByRole($em, User::ROLE_USER);
|
||||
|
||||
/** @var EncoderFactoryInterface $passwordEncoder */
|
||||
$passwordEncoder = $client->getContainer()->get('test.PasswordEncoder');
|
||||
|
||||
@@ -107,14 +118,92 @@ class ProfileControllerTest extends ControllerBaseTest
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertIsRedirect($client, $this->createUrl('/profile/' . urlencode(UserFixtures::USERNAME_USER)));
|
||||
$this->assertIsRedirect($client, $this->createUrl('/profile/' . urlencode(UserFixtures::USERNAME_USER) . '/password'));
|
||||
$client->followRedirect();
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
|
||||
$this->assertHasFlashSuccess($client);
|
||||
|
||||
$user = $client->getContainer()->get('security.token_storage')->getToken()->getUser();
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
$user = $this->getUserByRole($em, User::ROLE_USER);
|
||||
|
||||
$this->assertFalse($passwordEncoder->getEncoder($user)->isPasswordValid($user->getPassword(), UserFixtures::DEFAULT_PASSWORD, $user->getSalt()));
|
||||
$this->assertTrue($passwordEncoder->getEncoder($user)->isPasswordValid($user->getPassword(), 'test123', $user->getSalt()));
|
||||
}
|
||||
|
||||
public function testApiTokenAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
|
||||
$this->request($client, '/profile/' . UserFixtures::USERNAME_USER . '/api-token');
|
||||
|
||||
/** @var User $user */
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
$user = $this->getUserByRole($em, User::ROLE_USER);
|
||||
/** @var EncoderFactoryInterface $passwordEncoder */
|
||||
$passwordEncoder = $client->getContainer()->get('test.PasswordEncoder');
|
||||
|
||||
$this->assertTrue($passwordEncoder->getEncoder($user)->isPasswordValid($user->getApiToken(), UserFixtures::DEFAULT_API_TOKEN, $user->getSalt()));
|
||||
$this->assertFalse($passwordEncoder->getEncoder($user)->isPasswordValid($user->getApiToken(), 'test123', $user->getSalt()));
|
||||
$this->assertEquals(UserFixtures::USERNAME_USER, $user->getUsername());
|
||||
|
||||
$form = $client->getCrawler()->filter('form[name=user_api_token]')->form();
|
||||
$client->submit($form, [
|
||||
'user_api_token' => [
|
||||
'plainApiToken' => [
|
||||
'first' => 'test123',
|
||||
'second' => 'test123',
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertIsRedirect($client, $this->createUrl('/profile/' . urlencode(UserFixtures::USERNAME_USER) . '/api-token'));
|
||||
$client->followRedirect();
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
|
||||
$this->assertHasFlashSuccess($client);
|
||||
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
$user = $this->getUserByRole($em, User::ROLE_USER);
|
||||
|
||||
$this->assertFalse($passwordEncoder->getEncoder($user)->isPasswordValid($user->getApiToken(), UserFixtures::DEFAULT_API_TOKEN, $user->getSalt()));
|
||||
$this->assertTrue($passwordEncoder->getEncoder($user)->isPasswordValid($user->getApiToken(), 'test123', $user->getSalt()));
|
||||
}
|
||||
|
||||
public function testRolesActionIsSecured()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
|
||||
$this->request($client, '/profile/' . UserFixtures::USERNAME_USER . '/roles');
|
||||
$this->assertFalse($client->getResponse()->isSuccessful());
|
||||
}
|
||||
|
||||
public function testRolesAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
|
||||
$this->request($client, '/profile/' . UserFixtures::USERNAME_USER . '/roles');
|
||||
|
||||
/** @var User $user */
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
$user = $this->getUserByRole($em, User::ROLE_USER);
|
||||
|
||||
$this->assertEquals(['ROLE_USER'], $user->getRoles());
|
||||
|
||||
$form = $client->getCrawler()->filter('form[name=user_roles]')->form();
|
||||
$client->submit($form, [
|
||||
'user_roles[roles]' => [
|
||||
'ROLE_TEAMLEAD',
|
||||
'ROLE_SUPER_ADMIN',
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertIsRedirect($client, $this->createUrl('/profile/' . urlencode(UserFixtures::USERNAME_USER) . '/roles'));
|
||||
$client->followRedirect();
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
|
||||
$this->assertHasFlashSuccess($client);
|
||||
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
$user = $this->getUserByRole($em, User::ROLE_USER);
|
||||
|
||||
$this->assertEquals(['ROLE_TEAMLEAD', 'ROLE_SUPER_ADMIN', 'ROLE_USER'], $user->getRoles());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace App\Tests\Controller;
|
||||
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Tests\DataFixtures\TimesheetFixtures;
|
||||
|
||||
@@ -36,7 +37,81 @@ class TimesheetControllerTest extends ControllerBaseTest
|
||||
$client = $this->getClientForAuthenticatedUser();
|
||||
$this->request($client, '/timesheet/create');
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
// TODO more tests
|
||||
|
||||
$form = $client->getCrawler()->filter('form[name=timesheet_edit_form]')->form();
|
||||
$client->submit($form, [
|
||||
'timesheet_edit_form' => [
|
||||
'description' => 'Testing is fun!'
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertIsRedirect($client, $this->createUrl('/timesheet/'));
|
||||
$client->followRedirect();
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
$this->assertHasFlashSuccess($client);
|
||||
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
/** @var Timesheet $timesheet */
|
||||
$timesheet = $em->getRepository(Timesheet::class)->find(1);
|
||||
$this->assertInstanceOf(\DateTime::class, $timesheet->getBegin());
|
||||
$this->assertNull($timesheet->getEnd());
|
||||
$this->assertEquals('Testing is fun!', $timesheet->getDescription());
|
||||
$this->assertEquals(0, $timesheet->getRate());
|
||||
$this->assertNull($timesheet->getHourlyRate());
|
||||
$this->assertNull($timesheet->getFixedRate());
|
||||
}
|
||||
|
||||
public function testStartAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser();
|
||||
$this->request($client, '/timesheet/start/1');
|
||||
|
||||
$this->assertIsRedirect($client, $this->createUrl('/timesheet/'));
|
||||
$client->followRedirect();
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
$this->assertHasFlashSuccess($client);
|
||||
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
/** @var Timesheet $timesheet */
|
||||
$timesheet = $em->getRepository(Timesheet::class)->find(1);
|
||||
$this->assertInstanceOf(\DateTime::class, $timesheet->getBegin());
|
||||
$this->assertNull($timesheet->getEnd());
|
||||
$this->assertEquals(1, $timesheet->getActivity()->getId());
|
||||
}
|
||||
|
||||
public function testStopAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser();
|
||||
$this->request($client, '/timesheet/create');
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
|
||||
$form = $client->getCrawler()->filter('form[name=timesheet_edit_form]')->form();
|
||||
$client->submit($form, [
|
||||
'timesheet_edit_form' => [
|
||||
'description' => 'Testing is fun!',
|
||||
'fixedRate' => 100,
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertIsRedirect($client, $this->createUrl('/timesheet/'));
|
||||
$client->followRedirect();
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
$this->assertHasFlashSuccess($client);
|
||||
|
||||
$this->request($client, '/timesheet/1/stop');
|
||||
$this->assertIsRedirect($client, $this->createUrl('/timesheet/'));
|
||||
$client->followRedirect();
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
$this->assertHasFlashSuccess($client);
|
||||
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
/** @var Timesheet $timesheet */
|
||||
$timesheet = $em->getRepository(Timesheet::class)->find(1);
|
||||
$this->assertInstanceOf(\DateTime::class, $timesheet->getBegin());
|
||||
$this->assertInstanceOf(\DateTime::class, $timesheet->getEnd());
|
||||
$this->assertEquals(100, $timesheet->getRate());
|
||||
$this->assertEquals(100, $timesheet->getFixedRate());
|
||||
$this->assertNull($timesheet->getHourlyRate());
|
||||
}
|
||||
|
||||
public function testCreateActionWithFromAndToValues()
|
||||
@@ -44,7 +119,55 @@ class TimesheetControllerTest extends ControllerBaseTest
|
||||
$client = $this->getClientForAuthenticatedUser();
|
||||
$this->request($client, '/timesheet/create?from=2018-08-02T20%3A00%3A00&to=2018-08-02T20%3A30%3A00');
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
// TODO more tests
|
||||
|
||||
$form = $client->getCrawler()->filter('form[name=timesheet_edit_form]')->form();
|
||||
$client->submit($form, [
|
||||
'timesheet_edit_form' => [
|
||||
'hourlyRate' => 100,
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertIsRedirect($client, $this->createUrl('/timesheet/'));
|
||||
$client->followRedirect();
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
$this->assertHasFlashSuccess($client);
|
||||
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
/** @var Timesheet $timesheet */
|
||||
$timesheet = $em->getRepository(Timesheet::class)->find(1);
|
||||
$this->assertInstanceOf(\DateTime::class, $timesheet->getBegin());
|
||||
$this->assertInstanceOf(\DateTime::class, $timesheet->getEnd());
|
||||
$this->assertEquals(50, $timesheet->getRate());
|
||||
$this->assertEquals('2018-08-02T20:00:00+00:00', $timesheet->getBegin()->format(\DateTime::ATOM));
|
||||
$this->assertEquals('2018-08-02T20:30:00+00:00', $timesheet->getEnd()->format(\DateTime::ATOM));
|
||||
}
|
||||
|
||||
public function testCreateActionWithBeginAndEndValues()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser();
|
||||
$this->request($client, '/timesheet/create?begin=2018-08-02&end=2018-08-02');
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
|
||||
$form = $client->getCrawler()->filter('form[name=timesheet_edit_form]')->form();
|
||||
$client->submit($form, [
|
||||
'timesheet_edit_form' => [
|
||||
'hourlyRate' => 100,
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertIsRedirect($client, $this->createUrl('/timesheet/'));
|
||||
$client->followRedirect();
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
$this->assertHasFlashSuccess($client);
|
||||
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
/** @var Timesheet $timesheet */
|
||||
$timesheet = $em->getRepository(Timesheet::class)->find(1);
|
||||
$this->assertInstanceOf(\DateTime::class, $timesheet->getBegin());
|
||||
$this->assertInstanceOf(\DateTime::class, $timesheet->getEnd());
|
||||
$this->assertEquals(800, $timesheet->getRate());
|
||||
$this->assertEquals('2018-08-02T10:00:00+00:00', $timesheet->getBegin()->format(\DateTime::ATOM));
|
||||
$this->assertEquals('2018-08-02T18:00:00+00:00', $timesheet->getEnd()->format(\DateTime::ATOM));
|
||||
}
|
||||
|
||||
public function testEditAction()
|
||||
|
||||
@@ -44,10 +44,13 @@ class TimesheetFixtures extends Fixture
|
||||
protected $startDate = '2018-04-01';
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
* @param string|\DateTime $date
|
||||
*/
|
||||
public function setStartDate($date)
|
||||
{
|
||||
if ($date instanceof \DateTime) {
|
||||
$date = $date->format('Y-m-d');
|
||||
}
|
||||
$this->startDate = $date;
|
||||
}
|
||||
|
||||
|
||||
50
tests/Entity/ActivityTest.php
Normal file
50
tests/Entity/ActivityTest.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?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\Entity;
|
||||
|
||||
use App\Entity\Activity;
|
||||
|
||||
/**
|
||||
* @covers \App\Entity\Activity
|
||||
*/
|
||||
class ActivityTest extends AbstractEntityTest
|
||||
{
|
||||
public function testDefaultValues()
|
||||
{
|
||||
$sut = new Activity();
|
||||
$this->assertNull($sut->getId());
|
||||
$this->assertNull($sut->getProject());
|
||||
$this->assertNull($sut->getName());
|
||||
$this->assertNull($sut->getComment());
|
||||
$this->assertTrue($sut->getVisible());
|
||||
// timesheets
|
||||
$this->assertNull($sut->getFixedRate());
|
||||
$this->assertNull($sut->getHourlyRate());
|
||||
}
|
||||
|
||||
public function testSetterAndGetter()
|
||||
{
|
||||
$sut = new Activity();
|
||||
$this->assertInstanceOf(Activity::class, $sut->setName('foo-bar'));
|
||||
$this->assertEquals('foo-bar', $sut->getName());
|
||||
$this->assertEquals('foo-bar', (string) $sut);
|
||||
|
||||
$this->assertInstanceOf(Activity::class, $sut->setVisible(false));
|
||||
$this->assertFalse($sut->getVisible());
|
||||
|
||||
$this->assertInstanceOf(Activity::class, $sut->setComment('hello world'));
|
||||
$this->assertEquals('hello world', $sut->getComment());
|
||||
|
||||
$this->assertInstanceOf(Activity::class, $sut->setFixedRate(13.47));
|
||||
$this->assertEquals(13.47, $sut->getFixedRate());
|
||||
$this->assertInstanceOf(Activity::class, $sut->setHourlyRate(99));
|
||||
$this->assertEquals(99, $sut->getHourlyRate());
|
||||
}
|
||||
}
|
||||
90
tests/Entity/CustomerTest.php
Normal file
90
tests/Entity/CustomerTest.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?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\Entity;
|
||||
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Project;
|
||||
|
||||
/**
|
||||
* @covers \App\Entity\Customer
|
||||
*/
|
||||
class CustomerTest extends AbstractEntityTest
|
||||
{
|
||||
public function testDefaultValues()
|
||||
{
|
||||
$sut = new Customer();
|
||||
$this->assertNull($sut->getId());
|
||||
$this->assertNull($sut->getName());
|
||||
$this->assertNull($sut->getNumber());
|
||||
$this->assertNull($sut->getComment());
|
||||
// projects
|
||||
$this->assertTrue($sut->getVisible());
|
||||
|
||||
$this->assertNull($sut->getCompany());
|
||||
$this->assertNull($sut->getContact());
|
||||
$this->assertNull($sut->getAddress());
|
||||
$this->assertNull($sut->getCountry());
|
||||
$this->assertEquals('EUR', $sut->getCurrency());
|
||||
$this->assertEquals('EUR', Customer::DEFAULT_CURRENCY);
|
||||
$this->assertNull($sut->getPhone());
|
||||
$this->assertNull($sut->getFax());
|
||||
$this->assertNull($sut->getMobile());
|
||||
$this->assertNull($sut->getMail());
|
||||
$this->assertNull($sut->getHomepage());
|
||||
$this->assertNull($sut->getTimezone());
|
||||
|
||||
$this->assertNull($sut->getFixedRate());
|
||||
$this->assertNull($sut->getHourlyRate());
|
||||
}
|
||||
|
||||
public function testSetterAndGetter()
|
||||
{
|
||||
$sut = new Customer();
|
||||
$this->assertInstanceOf(Customer::class, $sut->setName('foo-bar'));
|
||||
$this->assertEquals('foo-bar', $sut->getName());
|
||||
$this->assertEquals('foo-bar', (string) $sut);
|
||||
|
||||
$this->assertInstanceOf(Customer::class, $sut->setVisible(false));
|
||||
$this->assertFalse($sut->getVisible());
|
||||
|
||||
$this->assertInstanceOf(Customer::class, $sut->setComment('hello world'));
|
||||
$this->assertEquals('hello world', $sut->getComment());
|
||||
|
||||
$projects = [(new Project())->setName('Test')];
|
||||
$this->assertInstanceOf(Customer::class, $sut->setProjects($projects));
|
||||
$this->assertSame($projects, $sut->getProjects());
|
||||
|
||||
$this->assertInstanceOf(Customer::class, $sut->setCompany('test company'));
|
||||
$this->assertEquals('test company', $sut->getCompany());
|
||||
|
||||
$this->assertInstanceOf(Customer::class, $sut->setContact('test contact'));
|
||||
$this->assertEquals('test contact', $sut->getContact());
|
||||
|
||||
$this->assertInstanceOf(Customer::class, $sut->setPhone('0123456789'));
|
||||
$this->assertEquals('0123456789', $sut->getPhone());
|
||||
|
||||
$this->assertInstanceOf(Customer::class, $sut->setFax('asdfghjkl'));
|
||||
$this->assertEquals('asdfghjkl', $sut->getFax());
|
||||
|
||||
$this->assertInstanceOf(Customer::class, $sut->setMobile('76576534'));
|
||||
$this->assertEquals('76576534', $sut->getMobile());
|
||||
|
||||
$this->assertInstanceOf(Customer::class, $sut->setMail('test@example.com'));
|
||||
$this->assertEquals('test@example.com', $sut->getMail());
|
||||
|
||||
$this->assertInstanceOf(Customer::class, $sut->setHomepage('https://www.example.com'));
|
||||
$this->assertEquals('https://www.example.com', $sut->getHomepage());
|
||||
|
||||
$this->assertInstanceOf(Customer::class, $sut->setFixedRate(13.47));
|
||||
$this->assertEquals(13.47, $sut->getFixedRate());
|
||||
$this->assertInstanceOf(Customer::class, $sut->setHourlyRate(99));
|
||||
$this->assertEquals(99, $sut->getHourlyRate());
|
||||
}
|
||||
}
|
||||
68
tests/Entity/ProjectTest.php
Normal file
68
tests/Entity/ProjectTest.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?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\Entity;
|
||||
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Project;
|
||||
|
||||
/**
|
||||
* @covers \App\Entity\Project
|
||||
*/
|
||||
class ProjectTest extends AbstractEntityTest
|
||||
{
|
||||
public function testDefaultValues()
|
||||
{
|
||||
$sut = new Project();
|
||||
$this->assertNull($sut->getId());
|
||||
$this->assertNull($sut->getCustomer());
|
||||
$this->assertNull($sut->getName());
|
||||
$this->assertNull($sut->getOrderNumber());
|
||||
$this->assertNull($sut->getComment());
|
||||
$this->assertTrue($sut->getVisible());
|
||||
$this->assertEquals(0.0, $sut->getBudget());
|
||||
// activities
|
||||
$this->assertNull($sut->getFixedRate());
|
||||
$this->assertNull($sut->getHourlyRate());
|
||||
}
|
||||
|
||||
public function testSetterAndGetter()
|
||||
{
|
||||
$sut = new Project();
|
||||
|
||||
$customer = (new Customer())->setName('customer');
|
||||
$this->assertInstanceOf(Project::class, $sut->setCustomer($customer));
|
||||
$this->assertSame($customer, $sut->getCustomer());
|
||||
|
||||
$this->assertInstanceOf(Project::class, $sut->setName('123456789'));
|
||||
$this->assertEquals('123456789', (string) $sut);
|
||||
|
||||
$this->assertInstanceOf(Project::class, $sut->setOrderNumber('123456789'));
|
||||
$this->assertEquals('123456789', $sut->getOrderNumber());
|
||||
|
||||
$this->assertInstanceOf(Project::class, $sut->setComment('a comment'));
|
||||
$this->assertEquals('a comment', $sut->getComment());
|
||||
|
||||
$this->assertInstanceOf(Project::class, $sut->setVisible(false));
|
||||
$this->assertFalse($sut->getVisible());
|
||||
|
||||
$this->assertInstanceOf(Project::class, $sut->setBudget(12345.67));
|
||||
$this->assertEquals(12345.67, $sut->getBudget());
|
||||
|
||||
$activities = [(new Activity())->setName('foo')];
|
||||
$this->assertInstanceOf(Project::class, $sut->setActivities($activities));
|
||||
$this->assertSame($activities, $sut->getActivities());
|
||||
|
||||
$this->assertInstanceOf(Project::class, $sut->setFixedRate(13.47));
|
||||
$this->assertEquals(13.47, $sut->getFixedRate());
|
||||
$this->assertInstanceOf(Project::class, $sut->setHourlyRate(99));
|
||||
$this->assertEquals(99, $sut->getHourlyRate());
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
namespace App\Tests\Timesheet\Calculator;
|
||||
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Project;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Entity\UserPreference;
|
||||
@@ -22,19 +25,20 @@ class RateCalculatorTest extends TestCase
|
||||
{
|
||||
public const HOURLY_RATE = 75;
|
||||
|
||||
public function testCalculateWithHourlyRate()
|
||||
public function testCalculateWithTimesheetHourlyRate()
|
||||
{
|
||||
$record = new Timesheet();
|
||||
$record->setEnd(new \DateTime());
|
||||
$record->setDuration(1800);
|
||||
$record->setHourlyRate(100);
|
||||
$record->setActivity(new Activity());
|
||||
|
||||
$sut = new RateCalculator([]);
|
||||
$sut->calculate($record);
|
||||
$this->assertEquals(50, $record->getRate());
|
||||
}
|
||||
|
||||
public function testCalculateWithFixedRate()
|
||||
public function testCalculateWithTimesheetFixedRate()
|
||||
{
|
||||
$record = new Timesheet();
|
||||
$record->setEnd(new \DateTime());
|
||||
@@ -42,17 +46,94 @@ class RateCalculatorTest extends TestCase
|
||||
$record->setFixedRate(10);
|
||||
// make sure that fixed rate is always applied, even if hourly rate is set
|
||||
$record->setHourlyRate(99);
|
||||
$record->setActivity(new Activity());
|
||||
|
||||
$sut = new RateCalculator([]);
|
||||
$sut->calculate($record);
|
||||
$this->assertEquals(10, $record->getRate());
|
||||
}
|
||||
|
||||
protected function getTestUser()
|
||||
public function getRateTestData()
|
||||
{
|
||||
yield 'a0' => [0.0, 0, 0, null, null, null, null, null, null, null, null];
|
||||
yield 'a1' => [0.0, 1800, 0, null, null, null, null, null, null, null, null];
|
||||
yield 'a2' => [0.5, 1800, 1, null, null, null, null, null, null, null, null];
|
||||
yield 'a3' => [0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
yield 'b1' => [1.5, 1800, 1, 3, null, 5, null, 7, null, 9, null];
|
||||
yield 'b2' => [2.5, 1800, 1, null, null, 5, null, 7, null, 9, null];
|
||||
yield 'b3' => [3.5, 1800, 1, null, null, null, null, 7, null, 9, null];
|
||||
yield 'b4' => [4.5, 1800, 1, null, null, null, null, null, null, 9, null];
|
||||
yield 'b5' => [2.0, 1800, 1, null, 2, null, 3, null, 4, null, 5];
|
||||
yield 'b6' => [3.0, 1800, 1, null, null, null, 3, null, 4, null, 5];
|
||||
yield 'b7' => [4.0, 1800, 1, null, null, null, null, null, 4, null, 5];
|
||||
yield 'b8' => [3.0, 1800, 1, null, null, null, 3, null, null, null, 5];
|
||||
yield 'b9' => [2.0, 1800, 1, null, 2, null, null, null, null, null, 5];
|
||||
yield 'c0' => [5.0, 1800, 100, 10, null, null, null, null, null, null, null];
|
||||
yield 'd0' => [10, 1800, 100, null, 10, null, null, null, null, null, null];
|
||||
yield 'e0' => [10, 1800, 100, null, null, 20, null, null, null, null, null];
|
||||
yield 'f0' => [20, 1800, 100, null, null, null, 20, null, null, null, null];
|
||||
yield 'g0' => [15, 1800, 100, null, null, null, null, 30, null, null, null];
|
||||
yield 'h0' => [30, 1800, 100, null, null, null, null, null, 30, null, null];
|
||||
yield 'i0' => [20, 1800, 100, null, null, null, null, null, null, 40, null];
|
||||
yield 'j0' => [40, 1800, 100, null, null, null, null, null, null, null, 40];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getRateTestData
|
||||
*/
|
||||
public function testRates(
|
||||
$exptectedRate,
|
||||
$duration,
|
||||
$userRate,
|
||||
$timesheetHourly,
|
||||
$timesheetFixed,
|
||||
$activityHourly,
|
||||
$activityFixed,
|
||||
$projectHourly,
|
||||
$projectFixed,
|
||||
$customerHourly,
|
||||
$customerFixed
|
||||
) {
|
||||
$customer = new Customer();
|
||||
$customer
|
||||
->setHourlyRate($customerHourly)
|
||||
->setFixedRate($customerFixed)
|
||||
;
|
||||
|
||||
$project = new Project();
|
||||
$project
|
||||
->setHourlyRate($projectHourly)
|
||||
->setFixedRate($projectFixed)
|
||||
->setCustomer($customer)
|
||||
;
|
||||
|
||||
$activity = new Activity();
|
||||
$activity
|
||||
->setHourlyRate($activityHourly)
|
||||
->setFixedRate($activityFixed)
|
||||
->setProject($project)
|
||||
;
|
||||
|
||||
$timesheet = new Timesheet();
|
||||
$timesheet
|
||||
->setEnd(new \DateTime())
|
||||
->setHourlyRate($timesheetHourly)
|
||||
->setFixedRate($timesheetFixed)
|
||||
->setActivity($activity)
|
||||
->setDuration($duration)
|
||||
->setUser($this->getTestUser($userRate))
|
||||
;
|
||||
|
||||
$sut = new RateCalculator([]);
|
||||
$sut->calculate($timesheet);
|
||||
$this->assertEquals($exptectedRate, $timesheet->getRate());
|
||||
}
|
||||
|
||||
protected function getTestUser($rate = self::HOURLY_RATE)
|
||||
{
|
||||
$pref = new UserPreference();
|
||||
$pref->setName(UserPreference::HOURLY_RATE);
|
||||
$pref->setValue(self::HOURLY_RATE);
|
||||
$pref->setValue($rate);
|
||||
|
||||
$user = new User();
|
||||
$user->setPreferences([$pref]);
|
||||
@@ -67,6 +148,8 @@ class RateCalculatorTest extends TestCase
|
||||
$record->setDuration(1800);
|
||||
$record->setFixedRate(100);
|
||||
$record->setHourlyRate(100);
|
||||
$record->setActivity(new Activity());
|
||||
|
||||
$this->assertEquals(0, $record->getRate());
|
||||
|
||||
$sut = new RateCalculator([]);
|
||||
@@ -98,6 +181,8 @@ class RateCalculatorTest extends TestCase
|
||||
$record->setUser($this->getTestUser());
|
||||
$record->setBegin($start);
|
||||
$record->setDuration($seconds);
|
||||
$record->setActivity(new Activity());
|
||||
|
||||
$this->assertEquals(0, $record->getRate());
|
||||
|
||||
$record->setEnd($end);
|
||||
@@ -129,6 +214,8 @@ class RateCalculatorTest extends TestCase
|
||||
$record->setUser($this->getTestUser());
|
||||
$record->setBegin($start);
|
||||
$record->setDuration($seconds);
|
||||
$record->setActivity(new Activity());
|
||||
|
||||
$this->assertEquals(0, $record->getRate());
|
||||
|
||||
$record->setEnd($end);
|
||||
|
||||
@@ -12,14 +12,19 @@ namespace App\Tests\Validator\Constraints;
|
||||
use App\Entity\User;
|
||||
use App\Validator\Constraints\Role;
|
||||
use App\Validator\Constraints\RoleValidator;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
|
||||
|
||||
/**
|
||||
* @covers \App\Validator\Constraints\RoleValidator
|
||||
*/
|
||||
class RoleValidatorTest extends TestCase
|
||||
class RoleValidatorTest extends ConstraintValidatorTestCase
|
||||
{
|
||||
protected function createValidator()
|
||||
{
|
||||
return new RoleValidator();
|
||||
}
|
||||
|
||||
public function getValidRoles()
|
||||
{
|
||||
return [
|
||||
@@ -36,24 +41,59 @@ class RoleValidatorTest extends TestCase
|
||||
*/
|
||||
public function testConstraintIsInvalid()
|
||||
{
|
||||
$validator = new RoleValidator();
|
||||
$validator->validate('foo', new NotBlank());
|
||||
$this->validator->validate('foo', new NotBlank());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getValidRoles
|
||||
* @param string $role
|
||||
*/
|
||||
public function testConstraintWithValidRole($role)
|
||||
{
|
||||
$constraint = new Role();
|
||||
$validator = new RoleValidator();
|
||||
$validator->validate($role, $constraint);
|
||||
// the above line would break if the role is invalid, we need the next assert to mark the test as valid
|
||||
$this->assertNull(null);
|
||||
$this->validator->validate($role, $constraint);
|
||||
$this->assertNoViolation();
|
||||
}
|
||||
|
||||
public function testValidationError()
|
||||
public function testNullIsInvalid()
|
||||
{
|
||||
$this->markTestIncomplete(__CLASS__ . ': validation message not tested yet');
|
||||
$this->validator->validate(null, new Role(['message' => 'myMessage']));
|
||||
|
||||
$this->buildViolation('myMessage')
|
||||
->setParameter('{{ value }}', 'null')
|
||||
->setCode(Role::ROLE_ERROR)
|
||||
->assertRaised();
|
||||
}
|
||||
|
||||
public function getInvalidRoles()
|
||||
{
|
||||
return [
|
||||
['foo'],
|
||||
[0],
|
||||
['role_user'],
|
||||
['ROLE-CUSTOMER'],
|
||||
['anonymous'],
|
||||
[''],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getInvalidRoles
|
||||
* @param mixed $role
|
||||
*/
|
||||
public function testValidationError($role)
|
||||
{
|
||||
$constraint = new Role([
|
||||
'message' => 'myMessage',
|
||||
]);
|
||||
|
||||
$this->validator->validate($role, $constraint);
|
||||
|
||||
$expectedFormat = is_string($role) ? '"' . $role . '"' : $role;
|
||||
|
||||
$this->buildViolation('myMessage')
|
||||
->setParameter('{{ value }}', $expectedFormat)
|
||||
->setCode(Role::ROLE_ERROR)
|
||||
->assertRaised();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user