set rates via batch update (#1326)

This commit is contained in:
Kevin Papst
2019-12-29 16:52:43 +01:00
committed by GitHub
parent 8aa8f452d5
commit baac4eb698
12 changed files with 258 additions and 49 deletions

View File

@@ -141,7 +141,7 @@ class PermissionControllerTest extends ControllerBaseTest
self::assertEquals(1, $permission->getRole()->getId());
// flush the cache to prevent wrong results
$em->clear(RolePermission::class);
$em->clear();
// update the permission
$this->request($client, '/admin/permissions/roles/1/view_user/0');

View File

@@ -124,7 +124,7 @@ class TagControllerTest extends ControllerBaseTest
$this->assertIsRedirect($client, $this->createUrl('/admin/tags/'));
$client->followRedirect();
$em->clear(Tag::class);
$em->clear();
self::assertEquals(0, $em->getRepository(Tag::class)->count([]));
}
}

View File

@@ -360,7 +360,7 @@ class TimesheetControllerTest extends ControllerBaseTest
$this->assertIsRedirect($client, $this->createUrl('/timesheet/'));
$client->followRedirect();
$em->clear(Timesheet::class);
$em->clear();
self::assertEquals(0, $em->getRepository(Timesheet::class)->count([]));
}
@@ -404,11 +404,12 @@ class TimesheetControllerTest extends ControllerBaseTest
$client->submit($form, [
'timesheet_multi_update' => [
'exported' => true,
'tags' => 'test, foo-bar'
'tags' => 'test, foo-bar',
'fixedRate' => 13,
]
]);
$em->clear(Timesheet::class);
$em->clear();
/** @var Timesheet[] $timesheets */
$timesheets = $em->getRepository(Timesheet::class)->findAll();
@@ -416,6 +417,7 @@ class TimesheetControllerTest extends ControllerBaseTest
foreach ($timesheets as $timesheet) {
self::assertCount(2, $timesheet->getTags());
self::assertTrue($timesheet->isExported());
self::assertEquals(13, $timesheet->getFixedRate());
}
}
}

View File

@@ -14,6 +14,7 @@ use App\Entity\TimesheetMeta;
use App\Entity\User;
use App\Form\Type\DateRangeType;
use App\Tests\DataFixtures\TimesheetFixtures;
use App\Timesheet\Util;
/**
* @group integration
@@ -276,7 +277,7 @@ class TimesheetTeamControllerTest extends ControllerBaseTest
$this->assertIsRedirect($client, $this->createUrl('/team/timesheet/'));
$client->followRedirect();
$em->clear(Timesheet::class);
$em->clear();
self::assertEquals(0, $em->getRepository(Timesheet::class)->count([]));
}
@@ -323,11 +324,12 @@ class TimesheetTeamControllerTest extends ControllerBaseTest
'user' => $newUser->getId(),
'exported' => true,
'replaceTags' => true,
'tags' => 'test, foo-bar, tralalala'
'tags' => 'test, foo-bar, tralalala',
'hourlyRate' => 13.78,
]
]);
$em->clear(Timesheet::class);
$em->clear();
/** @var Timesheet[] $timesheets */
$timesheets = $em->getRepository(Timesheet::class)->findAll();
@@ -336,6 +338,7 @@ class TimesheetTeamControllerTest extends ControllerBaseTest
self::assertCount(3, $timesheet->getTags());
self::assertEquals($newUser->getId(), $timesheet->getUser()->getId());
self::assertTrue($timesheet->isExported());
self::assertEquals(Util::calculateRate(13.78, $timesheet->getDuration()), $timesheet->getRate());
}
}
}

View File

@@ -164,7 +164,7 @@ class UserControllerTest extends ControllerBaseTest
$this->assertHasFlashDeleteSuccess($client);
// SQLIte does not necessarly support onCascade delete, so these timesheet will stay after deletion
// $em->clear(Timesheet::class);
// $em->clear();
// $timesheets = $em->getRepository(Timesheet::class)->count([]);
// $this->assertEquals(0, $timesheets);

View File

@@ -35,6 +35,8 @@ class TimesheetMultiUpdateDTOTest extends TestCase
self::assertEquals([], $sut->getTags());
self::assertNull($sut->getUser());
self::assertFalse($sut->isReplaceTags());
self::assertNull($sut->getFixedRate());
self::assertNull($sut->getHourlyRate());
}
public function testSetterAndGetter()
@@ -86,5 +88,11 @@ class TimesheetMultiUpdateDTOTest extends TestCase
$customer = (new Customer())->setName('sdfsdfsd');
self::assertInstanceOf(TimesheetMultiUpdateDTO::class, $sut->setCustomer($customer));
self::assertSame($customer, $sut->getCustomer());
self::assertInstanceOf(TimesheetMultiUpdateDTO::class, $sut->setFixedRate(12.78));
self::assertEquals(12.78, $sut->getFixedRate());
self::assertInstanceOf(TimesheetMultiUpdateDTO::class, $sut->setHourlyRate(123.45));
self::assertEquals(123.45, $sut->getHourlyRate());
}
}

View File

@@ -0,0 +1,139 @@
<?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\Validator\Constraints;
use App\Entity\Activity;
use App\Entity\Customer;
use App\Entity\Project;
use App\Form\MultiUpdate\TimesheetMultiUpdateDTO;
use App\Validator\Constraints\TimesheetMultiUpdate as TimesheetMultiUpdateConstraint;
use App\Validator\Constraints\TimesheetMultiUpdateValidator;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
/**
* @covers \App\Validator\Constraints\TimesheetMultiUpdateValidator
*/
class TimesheetMultiUpdateValidatorTest extends ConstraintValidatorTestCase
{
protected function createValidator($isGranted = true)
{
return new TimesheetMultiUpdateValidator();
}
public function testConstraintIsInvalid()
{
$this->expectException(UnexpectedTypeException::class);
$this->validator->validate('foo', new NotBlank());
}
public function testProjectMismatch()
{
$activity = new Activity();
$project1 = new Project();
$project2 = new Project();
$activity->setProject($project1);
$timesheet = new TimesheetMultiUpdateDTO();
$timesheet
->setActivity($activity)
->setProject($project2)
;
$this->validator->validate($timesheet, new TimesheetMultiUpdateConstraint(['message' => 'myMessage']));
$this->buildViolation('Project mismatch, project specific activity and timesheet project are different.')
->atPath('property.path.project')
->setCode(TimesheetMultiUpdateConstraint::ACTIVITY_PROJECT_MISMATCH_ERROR)
->assertRaised();
}
public function testProjectWithoutActivity()
{
$timesheet = new TimesheetMultiUpdateDTO();
$timesheet
->setProject(new Project())
;
$this->validator->validate($timesheet, new TimesheetMultiUpdateConstraint(['message' => 'myMessage']));
$this->buildViolation('You need to choose an activity, if the project should be changed.')
->atPath('property.path.activity')
->setCode(TimesheetMultiUpdateConstraint::MISSING_ACTIVITY_ERROR)
->assertRaised();
}
public function testActivityWithoutProject()
{
$timesheet = new TimesheetMultiUpdateDTO();
$timesheet
->setActivity((new Activity())->setProject(new Project()))
;
$this->validator->validate($timesheet, new TimesheetMultiUpdateConstraint(['message' => 'myMessage']));
$this->buildViolation('Missing project.')
->atPath('property.path.project')
->setCode(TimesheetMultiUpdateConstraint::MISSING_PROJECT_ERROR)
->assertRaised();
}
public function testHourlyRateAndFixedRateInParallelAreNotAllowed()
{
$timesheet = new TimesheetMultiUpdateDTO();
$timesheet
->setHourlyRate(10.12)
->setFixedRate(123.45)
;
$this->validator->validate($timesheet, new TimesheetMultiUpdateConstraint(['message' => 'myMessage']));
$this->buildViolation('Cannot set hourly rate and fixed rate at the same time.')
->atPath('property.path.fixedRate')
->setCode(TimesheetMultiUpdateConstraint::HOURLY_RATE_FIXED_RATE)
->buildNextViolation('Cannot set hourly rate and fixed rate at the same time.')
->atPath('property.path.hourlyRate')
->setCode(TimesheetMultiUpdateConstraint::HOURLY_RATE_FIXED_RATE)
->assertRaised();
}
public function testDisabledValues()
{
$customer = new Customer();
$customer->setVisible(false);
$activity = new Activity();
$activity->setVisible(false);
$project = new Project();
$project->setVisible(false);
$project->setCustomer($customer);
$activity->setProject($project);
$timesheet = new TimesheetMultiUpdateDTO();
$timesheet
->setActivity($activity)
->setProject($project)
;
$this->validator->validate($timesheet, new TimesheetMultiUpdateConstraint(['message' => 'myMessage']));
$this->buildViolation('Cannot assign a disabled activity.')
->atPath('property.path.activity')
->setCode(TimesheetMultiUpdateConstraint::DISABLED_ACTIVITY_ERROR)
->buildNextViolation('Cannot assign a disabled project.')
->atPath('property.path.project')
->setCode(TimesheetMultiUpdateConstraint::DISABLED_PROJECT_ERROR)
->buildNextViolation('Cannot assign a disabled customer.')
->atPath('property.path.customer')
->setCode(TimesheetMultiUpdateConstraint::DISABLED_CUSTOMER_ERROR)
->assertRaised();
}
}