added fixed-rate and hourly-rate for customer, project and activity (#304)

This commit is contained in:
Kevin Papst
2018-09-06 23:37:25 +02:00
committed by GitHub
parent 6163f33abf
commit 8cae5e8b3f
32 changed files with 1173 additions and 154 deletions

View File

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

View File

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

View File

@@ -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()

View File

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

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

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

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

View File

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

View File

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