refactored invoice and export screens (#1046)
This commit is contained in:
@@ -9,8 +9,10 @@
|
||||
|
||||
namespace App\Tests\Controller;
|
||||
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Tests\DataFixtures\TimesheetFixtures;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
/**
|
||||
* @group integration
|
||||
@@ -27,7 +29,7 @@ class ExportControllerTest extends ControllerBaseTest
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
|
||||
|
||||
$this->request($client, '/export/');
|
||||
$this->request($client, '/export/?preview=');
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
|
||||
$this->assertHasNoEntriesWithFilter($client);
|
||||
@@ -47,7 +49,7 @@ class ExportControllerTest extends ControllerBaseTest
|
||||
;
|
||||
$this->importFixture($em, $fixture);
|
||||
|
||||
$this->request($client, '/export/');
|
||||
$this->request($client, '/export/?preview=');
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
|
||||
// make sure all existing records are displayed
|
||||
@@ -55,7 +57,7 @@ class ExportControllerTest extends ControllerBaseTest
|
||||
$this->assertDataTableRowCount($client, 'datatable_export', 20);
|
||||
|
||||
// assert export type buttons are available
|
||||
$expected = ['csv', 'html', 'pdf', 'ods', 'xlsx'];
|
||||
$expected = ['csv', 'html', 'pdf', 'xlsx'];
|
||||
$node = $client->getCrawler()->filter('#export-buttons button');
|
||||
$this->assertEquals(count($expected), $node->count());
|
||||
foreach ($node->getIterator() as $button) {
|
||||
@@ -100,6 +102,7 @@ class ExportControllerTest extends ControllerBaseTest
|
||||
public function testExportAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
|
||||
/** @var EntityManager $em */
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
|
||||
$begin = new \DateTime('first day of this month');
|
||||
@@ -121,7 +124,8 @@ class ExportControllerTest extends ControllerBaseTest
|
||||
|
||||
// don't add daterange to make sure the current month is the default range
|
||||
$client->submit($form, [
|
||||
'type' => 'html'
|
||||
'type' => 'html',
|
||||
'markAsExported' => 1
|
||||
]);
|
||||
|
||||
$response = $client->getResponse();
|
||||
@@ -137,5 +141,11 @@ class ExportControllerTest extends ControllerBaseTest
|
||||
$node = $client->getCrawler()->filter('section.export div#export-records table.dataTable tbody tr');
|
||||
// 20 rows + the summary footer
|
||||
$this->assertEquals(21, $node->count());
|
||||
|
||||
$timesheets = $em->getRepository(Timesheet::class)->findAll();
|
||||
/** @var Timesheet $timesheet */
|
||||
foreach ($timesheets as $timesheet) {
|
||||
$this->assertTrue($timesheet->isExported());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
namespace App\Tests\Controller;
|
||||
|
||||
use App\Entity\InvoiceTemplate;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Form\Type\DateRangeType;
|
||||
use App\Tests\DataFixtures\InvoiceFixtures;
|
||||
use App\Tests\DataFixtures\TimesheetFixtures;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
/**
|
||||
* @group integration
|
||||
@@ -28,7 +30,7 @@ class InvoiceControllerTest extends ControllerBaseTest
|
||||
|
||||
public function testIndexActionRedirectsToCreateTemplate()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
|
||||
$this->request($client, '/invoice/');
|
||||
$this->assertIsRedirect($client, '/invoice/template/create');
|
||||
@@ -42,7 +44,7 @@ class InvoiceControllerTest extends ControllerBaseTest
|
||||
$fixture = new InvoiceFixtures();
|
||||
$this->importFixture($em, $fixture);
|
||||
|
||||
$this->request($client, '/invoice/');
|
||||
$this->request($client, '/invoice/?preview=');
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
|
||||
$this->assertHasNoEntriesWithFilter($client);
|
||||
@@ -50,7 +52,7 @@ class InvoiceControllerTest extends ControllerBaseTest
|
||||
|
||||
public function testListTemplateAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
$fixture = new InvoiceFixtures();
|
||||
@@ -64,7 +66,7 @@ class InvoiceControllerTest extends ControllerBaseTest
|
||||
|
||||
public function testCreateTemplateAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->request($client, '/invoice/template/create');
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
|
||||
@@ -88,7 +90,7 @@ class InvoiceControllerTest extends ControllerBaseTest
|
||||
|
||||
public function testCopyTemplateAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
|
||||
$fixture = new InvoiceFixtures();
|
||||
@@ -117,6 +119,7 @@ class InvoiceControllerTest extends ControllerBaseTest
|
||||
public function testPrintAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
|
||||
/** @var EntityManager $em */
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
|
||||
$fixture = new InvoiceFixtures();
|
||||
@@ -138,66 +141,50 @@ class InvoiceControllerTest extends ControllerBaseTest
|
||||
$dateRange = $begin->format('Y-m-d') . DateRangeType::DATE_SPACER . $end->format('Y-m-d');
|
||||
|
||||
$form = $client->getCrawler()->filter('#invoice-print-form')->form();
|
||||
$node = $form->getFormNode();
|
||||
$node->setAttribute('action', $this->createUrl('/invoice/?preview='));
|
||||
$node->setAttribute('method', 'GET');
|
||||
$client->submit($form, [
|
||||
'template' => 1,
|
||||
'user' => '',
|
||||
'daterange' => $dateRange,
|
||||
'customer' => 1,
|
||||
]);
|
||||
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
|
||||
// no datatable should be displayed
|
||||
// no warning should be displayed
|
||||
$node = $client->getCrawler()->filter('div.callout.callout-warning.lead');
|
||||
$this->assertEquals(0, $node->count());
|
||||
|
||||
$node = $client->getCrawler()->filter('div.callout.callout-success.lead');
|
||||
$this->assertNotEmpty($node->text());
|
||||
$this->assertContains('This is a preview of the data that will show up in your invoice document.', $node->text());
|
||||
|
||||
// but the datatable with all timesheets
|
||||
$this->assertDataTableRowCount($client, 'datatable_invoice', 20);
|
||||
|
||||
$form = $client->getCrawler()->filter('#invoice-print-form')->form();
|
||||
$node = $form->getFormNode();
|
||||
$node->setAttribute('action', $this->createUrl('/invoice/print'));
|
||||
$node->setAttribute('method', 'POST');
|
||||
$node->setAttribute('action', $this->createUrl('/invoice/?create='));
|
||||
$node->setAttribute('method', 'GET');
|
||||
$client->submit($form, [
|
||||
'template' => 1,
|
||||
'user' => '',
|
||||
'daterange' => $dateRange,
|
||||
'customer' => 1,
|
||||
'project' => 1,
|
||||
'markAsExported' => 1,
|
||||
]);
|
||||
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
$node = $client->getCrawler()->filter('body');
|
||||
$this->assertEquals(1, $node->count());
|
||||
$this->assertEquals('invoice_print', $node->getIterator()[0]->getAttribute('class'));
|
||||
}
|
||||
|
||||
public function testPrintActionRedirectsToCreateTemplate()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
|
||||
|
||||
$this->request($client, '/invoice/print', 'POST');
|
||||
$this->assertIsRedirect($client, '/invoice/template/create');
|
||||
}
|
||||
|
||||
public function testPrintActionRedirectsToIndex()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
|
||||
$fixture = new InvoiceFixtures();
|
||||
$this->importFixture($em, $fixture);
|
||||
|
||||
$this->request($client, '/invoice/print', 'POST');
|
||||
$this->assertIsRedirect($client, '/invoice/');
|
||||
$timesheets = $em->getRepository(Timesheet::class)->findAll();
|
||||
/** @var Timesheet $timesheet */
|
||||
foreach ($timesheets as $timesheet) {
|
||||
$this->assertTrue($timesheet->isExported());
|
||||
}
|
||||
}
|
||||
|
||||
public function testEditTemplateAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_TEAMLEAD);
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
$fixture = new InvoiceFixtures();
|
||||
@@ -231,8 +218,8 @@ class InvoiceControllerTest extends ControllerBaseTest
|
||||
$fixture = new InvoiceFixtures();
|
||||
$this->importFixture($em, $fixture);
|
||||
|
||||
$this->request($client, '/invoice/template/1/delete?page=1');
|
||||
$this->assertIsRedirect($client, '/invoice/template/page/1');
|
||||
$this->request($client, '/invoice/template/1/delete');
|
||||
$this->assertIsRedirect($client, '/invoice/template');
|
||||
$client->followRedirect();
|
||||
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
|
||||
@@ -210,6 +210,6 @@ class UserControllerTest extends ControllerBaseTest
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/user/permissions');
|
||||
$this->assertHasDataTable($client);
|
||||
$this->assertDataTableRowCount($client, 'datatable_user_admin_permissions', 84);
|
||||
$this->assertDataTableRowCount($client, 'datatable_user_admin_permissions', 80);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ use App\Entity\User;
|
||||
use App\Export\RendererInterface;
|
||||
use App\Repository\Query\TimesheetQuery;
|
||||
use App\Twig\DateExtensions;
|
||||
use App\Twig\Extensions;
|
||||
use App\Utils\LocaleSettings;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@@ -52,9 +51,8 @@ abstract class AbstractRendererTest extends KernelTestCase
|
||||
|
||||
$translator = $this->getMockBuilder(TranslatorInterface::class)->getMock();
|
||||
$dateExtension = new DateExtensions($localeSettings);
|
||||
$extensions = new Extensions($localeSettings);
|
||||
|
||||
return new $classname($translator, $dateExtension, $extensions);
|
||||
return new $classname($translator, $dateExtension);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,7 +32,7 @@ class CsvRendererTest extends AbstractRendererTest
|
||||
public function getTestModel()
|
||||
{
|
||||
return [
|
||||
['01:50 h', '€2,437.12', '€1,947.99', 7, 5, 1, 2, 2]
|
||||
['400', '2437.12', ' EUR 1,947.99 ', 7, 5, 1, 2, 2]
|
||||
];
|
||||
}
|
||||
|
||||
@@ -76,26 +76,27 @@ class CsvRendererTest extends AbstractRendererTest
|
||||
}
|
||||
|
||||
$expected = [
|
||||
0 => '2019.06.16 12:00',
|
||||
1 => '2019.06.16 12:06',
|
||||
2 => 'kevin',
|
||||
3 => 'Customer Name',
|
||||
4 => 'project name',
|
||||
5 => 'activity description',
|
||||
6 => '',
|
||||
7 => '',
|
||||
8 => 'foo,bar',
|
||||
9 => 'meta-bar',
|
||||
10 => 'meta-bar2',
|
||||
11 => '€0.00',
|
||||
12 => '€84.00',
|
||||
13 => '00:06 h',
|
||||
14 => '€0.00',
|
||||
0 => '2019-06-16',
|
||||
1 => '12:00',
|
||||
2 => '12:06',
|
||||
3 => '400',
|
||||
4 => '0',
|
||||
5 => 'kevin',
|
||||
6 => 'Customer Name',
|
||||
7 => 'project name',
|
||||
8 => 'activity description',
|
||||
9 => '',
|
||||
10 => '',
|
||||
11 => 'foo,bar',
|
||||
12 => '',
|
||||
13 => ' EUR 84.00 ',
|
||||
14 => 'meta-bar',
|
||||
15 => 'meta-bar2',
|
||||
];
|
||||
|
||||
self::assertEquals(7, count($all));
|
||||
self::assertEquals(count($expected), count($all[0]));
|
||||
self::assertEquals('foo', $all[4][8]);
|
||||
self::assertEquals('foo', $all[4][11]);
|
||||
|
||||
self::assertEquals($expected, $all[5]);
|
||||
}
|
||||
|
||||
@@ -1,52 +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\Renderer;
|
||||
|
||||
use App\Export\Renderer\OdsRenderer;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
|
||||
/**
|
||||
* @covers \App\Export\Renderer\OdsRenderer
|
||||
* @covers \App\Export\Renderer\AbstractSpreadsheetRenderer
|
||||
* @covers \App\Export\Renderer\RendererTrait
|
||||
* @group integration
|
||||
*/
|
||||
class OdsRendererTest extends AbstractRendererTest
|
||||
{
|
||||
public function testConfiguration()
|
||||
{
|
||||
$sut = $this->getAbstractRenderer(OdsRenderer::class);
|
||||
|
||||
$this->assertEquals('ods', $sut->getId());
|
||||
$this->assertEquals('ods', $sut->getTitle());
|
||||
$this->assertEquals('ods', $sut->getIcon());
|
||||
}
|
||||
|
||||
public function testRender()
|
||||
{
|
||||
$sut = $this->getAbstractRenderer(OdsRenderer::class);
|
||||
|
||||
/** @var BinaryFileResponse $response */
|
||||
$response = $this->render($sut);
|
||||
|
||||
$file = $response->getFile();
|
||||
$this->assertEquals('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', $response->headers->get('Content-Type'));
|
||||
$this->assertEquals('attachment; filename=kimai-export.ods', $response->headers->get('Content-Disposition'));
|
||||
|
||||
$this->assertTrue(file_exists($file->getRealPath()));
|
||||
|
||||
ob_start();
|
||||
$response->sendContent();
|
||||
$content2 = ob_get_clean();
|
||||
$this->assertNotEmpty($content2);
|
||||
|
||||
$this->assertFalse(file_exists($file->getRealPath()));
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ class DebugRendererTest extends TestCase
|
||||
// TODO check values or formats?
|
||||
}
|
||||
|
||||
protected function assertModelStructure(array $model, $hasProject = true, $hasActivity = false)
|
||||
protected function assertModelStructure(array $model, $hasProject = true)
|
||||
{
|
||||
$keys = [
|
||||
'invoice.due_date',
|
||||
@@ -85,10 +85,14 @@ class DebugRendererTest extends TestCase
|
||||
'customer.number',
|
||||
'customer.homepage',
|
||||
'customer.comment',
|
||||
'customer.fixed_rate',
|
||||
'customer.hourly_rate',
|
||||
'customer.meta.foo-customer',
|
||||
'activity.id',
|
||||
'activity.name',
|
||||
'activity.comment',
|
||||
'activity.fixed_rate',
|
||||
'activity.hourly_rate',
|
||||
'activity.meta.foo-activity',
|
||||
];
|
||||
|
||||
@@ -98,18 +102,12 @@ class DebugRendererTest extends TestCase
|
||||
'project.name',
|
||||
'project.comment',
|
||||
'project.order_number',
|
||||
'project.fixed_rate',
|
||||
'project.hourly_rate',
|
||||
'project.meta.foo-project',
|
||||
]);
|
||||
}
|
||||
|
||||
if ($hasActivity) {
|
||||
$keys = array_merge($keys, [
|
||||
'activity.id',
|
||||
'activity.name',
|
||||
'activity.comment',
|
||||
]);
|
||||
}
|
||||
|
||||
$givenKeys = array_keys($model);
|
||||
sort($keys);
|
||||
sort($givenKeys);
|
||||
|
||||
@@ -37,6 +37,15 @@ class ExportQueryTest extends BaseQueryTest
|
||||
$this->assertState($sut);
|
||||
$this->assertExported($sut);
|
||||
$this->assertType($sut);
|
||||
$this->assertMarkAsExported($sut);
|
||||
}
|
||||
|
||||
protected function assertMarkAsExported(ExportQuery $sut)
|
||||
{
|
||||
$this->assertFalse($sut->isMarkAsExported());
|
||||
|
||||
$sut->setMarkAsExported(true);
|
||||
$this->assertTrue($sut->isMarkAsExported());
|
||||
}
|
||||
|
||||
protected function assertUser(ExportQuery $sut)
|
||||
|
||||
123
tests/Repository/Query/InvoiceQueryTest.php
Normal file
123
tests/Repository/Query/InvoiceQueryTest.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?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\Repository\Query;
|
||||
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Project;
|
||||
use App\Entity\User;
|
||||
use App\Repository\Query\InvoiceQuery;
|
||||
|
||||
/**
|
||||
* @covers \App\Repository\Query\InvoiceQuery
|
||||
*/
|
||||
class InvoiceQueryTest extends BaseQueryTest
|
||||
{
|
||||
public function testQuery()
|
||||
{
|
||||
$sut = new InvoiceQuery();
|
||||
|
||||
$this->assertResultType($sut);
|
||||
$this->assertPage($sut);
|
||||
$this->assertPageSize($sut);
|
||||
$this->assertOrderBy($sut, 'begin');
|
||||
$this->assertOrder($sut, InvoiceQuery::ORDER_DESC);
|
||||
|
||||
$this->assertUser($sut);
|
||||
$this->assertCustomer($sut);
|
||||
$this->assertProject($sut);
|
||||
$this->assertActivity($sut);
|
||||
$this->assertState($sut);
|
||||
$this->assertExported($sut);
|
||||
$this->assertMarkAsExported($sut);
|
||||
}
|
||||
|
||||
protected function assertMarkAsExported(InvoiceQuery $sut)
|
||||
{
|
||||
$this->assertFalse($sut->isMarkAsExported());
|
||||
|
||||
$sut->setMarkAsExported(true);
|
||||
$this->assertTrue($sut->isMarkAsExported());
|
||||
}
|
||||
|
||||
protected function assertUser(InvoiceQuery $sut)
|
||||
{
|
||||
$this->assertNull($sut->getUser());
|
||||
|
||||
$expected = new User();
|
||||
$expected->setUsername('foo-bar');
|
||||
$sut->setUser($expected);
|
||||
$this->assertEquals($expected, $sut->getUser());
|
||||
}
|
||||
|
||||
protected function assertCustomer(InvoiceQuery $sut)
|
||||
{
|
||||
$this->assertNull($sut->getCustomer());
|
||||
|
||||
$expected = new Customer();
|
||||
$expected->setName('foo-bar');
|
||||
$sut->setCustomer($expected);
|
||||
$this->assertEquals($expected, $sut->getCustomer());
|
||||
}
|
||||
|
||||
protected function assertProject(InvoiceQuery $sut)
|
||||
{
|
||||
$this->assertNull($sut->getProject());
|
||||
|
||||
$expected = new Project();
|
||||
$expected->setName('foo-bar');
|
||||
$sut->setProject($expected);
|
||||
$this->assertEquals($expected, $sut->getProject());
|
||||
}
|
||||
|
||||
protected function assertActivity(InvoiceQuery $sut)
|
||||
{
|
||||
$this->assertNull($sut->getActivity());
|
||||
|
||||
$expected = new Activity();
|
||||
$expected->setName('foo-bar');
|
||||
$sut->setActivity($expected);
|
||||
$this->assertEquals($expected, $sut->getActivity());
|
||||
}
|
||||
|
||||
protected function assertState(InvoiceQuery $sut)
|
||||
{
|
||||
$this->assertEquals(InvoiceQuery::STATE_ALL, $sut->getState());
|
||||
|
||||
$sut->setState(PHP_INT_MAX);
|
||||
$this->assertEquals(InvoiceQuery::STATE_ALL, $sut->getState());
|
||||
|
||||
$sut->setState(InvoiceQuery::STATE_STOPPED);
|
||||
$this->assertEquals(InvoiceQuery::STATE_STOPPED, $sut->getState());
|
||||
|
||||
$sut->setState(InvoiceQuery::STATE_RUNNING);
|
||||
$this->assertEquals(InvoiceQuery::STATE_RUNNING, $sut->getState());
|
||||
|
||||
$sut->setState(InvoiceQuery::STATE_ALL);
|
||||
$this->assertEquals(InvoiceQuery::STATE_ALL, $sut->getState());
|
||||
}
|
||||
|
||||
protected function assertExported(InvoiceQuery $sut)
|
||||
{
|
||||
$this->assertEquals(InvoiceQuery::STATE_ALL, $sut->getExported());
|
||||
|
||||
$sut->setExported(PHP_INT_MAX);
|
||||
$this->assertEquals(InvoiceQuery::STATE_ALL, $sut->getExported());
|
||||
|
||||
$sut->setExported(InvoiceQuery::STATE_EXPORTED);
|
||||
$this->assertEquals(InvoiceQuery::STATE_EXPORTED, $sut->getExported());
|
||||
|
||||
$sut->setExported(InvoiceQuery::STATE_NOT_EXPORTED);
|
||||
$this->assertEquals(InvoiceQuery::STATE_NOT_EXPORTED, $sut->getExported());
|
||||
|
||||
$sut->setExported(InvoiceQuery::STATE_ALL);
|
||||
$this->assertEquals(InvoiceQuery::STATE_ALL, $sut->getExported());
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ class TimesheetQueryTest extends BaseQueryTest
|
||||
$this->assertOrder($sut, TimesheetQuery::ORDER_DESC);
|
||||
|
||||
$this->assertUser($sut);
|
||||
$this->assertUsers($sut);
|
||||
$this->assertCustomer($sut);
|
||||
$this->assertProject($sut);
|
||||
$this->assertActivity($sut);
|
||||
@@ -48,6 +49,30 @@ class TimesheetQueryTest extends BaseQueryTest
|
||||
$this->assertEquals($expected, $sut->getUser());
|
||||
}
|
||||
|
||||
protected function assertUsers(TimesheetQuery $sut)
|
||||
{
|
||||
$this->assertEmpty($sut->getUsers());
|
||||
|
||||
$user = $this->getMockBuilder(User::class)->disableOriginalConstructor()->getMock();
|
||||
$user->method('getId')->willReturn(1);
|
||||
$sut->addUser($user);
|
||||
|
||||
$user = $this->getMockBuilder(User::class)->disableOriginalConstructor()->getMock();
|
||||
$user->method('getId')->willReturn(1);
|
||||
$sut->addUser($user);
|
||||
|
||||
$user = $this->getMockBuilder(User::class)->disableOriginalConstructor()->getMock();
|
||||
$user->method('getId')->willReturn(13);
|
||||
$sut->addUser($user);
|
||||
|
||||
$user = $this->getMockBuilder(User::class)->disableOriginalConstructor()->getMock();
|
||||
$user->method('getId')->willReturn(27);
|
||||
$sut->addUser($user);
|
||||
$sut->removeUser($user);
|
||||
|
||||
$this->assertCount(2, $sut->getUsers());
|
||||
}
|
||||
|
||||
protected function assertCustomer(TimesheetQuery $sut)
|
||||
{
|
||||
$this->assertNull($sut->getCustomer());
|
||||
|
||||
@@ -73,7 +73,7 @@ abstract class AbstractVoterTest extends TestCase
|
||||
$customers = ['view_customer', 'edit_customer', 'budget_customer', 'delete_customer', 'create_customer'];
|
||||
$customersTeam = ['view_customer', 'edit_teamlead_customer', 'budget_teamlead_customer'];
|
||||
$invoice = ['view_invoice', 'create_invoice'];
|
||||
$invoiceTemplate = ['view_invoice_template', 'create_invoice_template', 'edit_invoice_template', 'delete_invoice_template'];
|
||||
$invoiceTemplate = ['manage_invoice_template'];
|
||||
$timesheet = ['view_own_timesheet', 'start_own_timesheet', 'stop_own_timesheet', 'create_own_timesheet', 'edit_own_timesheet', 'export_own_timesheet', 'delete_own_timesheet'];
|
||||
$timesheetOthers = ['view_other_timesheet', 'start_other_timesheet', 'stop_other_timesheet', 'create_other_timesheet', 'edit_other_timesheet', 'export_other_timesheet', 'delete_other_timesheet'];
|
||||
$profile = ['view_own_profile', 'edit_own_profile', 'password_own_profile', 'preferences_own_profile', 'api-token_own_profile'];
|
||||
|
||||
@@ -1,66 +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\Voter;
|
||||
|
||||
use App\Entity\InvoiceTemplate;
|
||||
use App\Entity\User;
|
||||
use App\Voter\InvoiceTemplateVoter;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
|
||||
/**
|
||||
* @covers \App\Voter\InvoiceTemplateVoter
|
||||
*/
|
||||
class InvoiceTemplateVoterTest extends AbstractVoterTest
|
||||
{
|
||||
/**
|
||||
* @dataProvider getTestData
|
||||
*/
|
||||
public function testVote(User $user, $subject, $attribute, $result)
|
||||
{
|
||||
$token = new UsernamePasswordToken($user, 'foo', 'bar', $user->getRoles());
|
||||
$sut = $this->getVoter(InvoiceTemplateVoter::class, $user);
|
||||
|
||||
$this->assertEquals($result, $sut->vote($token, $subject, [$attribute]));
|
||||
}
|
||||
|
||||
public function getTestData()
|
||||
{
|
||||
$user0 = $this->getUser(0, null);
|
||||
$user1 = $this->getUser(1, User::ROLE_USER);
|
||||
$user2 = $this->getUser(2, User::ROLE_TEAMLEAD);
|
||||
$user3 = $this->getUser(3, User::ROLE_ADMIN);
|
||||
$user4 = $this->getUser(4, User::ROLE_SUPER_ADMIN);
|
||||
|
||||
$result = VoterInterface::ACCESS_GRANTED;
|
||||
foreach ([$user3, $user4] as $user) {
|
||||
yield [$user, new InvoiceTemplate(), 'view', $result];
|
||||
yield [$user, new InvoiceTemplate(), 'edit', $result];
|
||||
yield [$user, new InvoiceTemplate(), 'delete', $result];
|
||||
}
|
||||
|
||||
$result = VoterInterface::ACCESS_DENIED;
|
||||
foreach ([$user0, $user1, $user2] as $user) {
|
||||
yield [$user, new InvoiceTemplate(), 'view', $result];
|
||||
yield [$user, new InvoiceTemplate(), 'edit', $result];
|
||||
yield [$user, new InvoiceTemplate(), 'delete', $result];
|
||||
}
|
||||
|
||||
$result = VoterInterface::ACCESS_ABSTAIN;
|
||||
foreach ([$user0, $user1, $user2] as $user) {
|
||||
yield [$user, new InvoiceTemplate(), 'view_invoice_template', $result];
|
||||
yield [$user, new InvoiceTemplate(), 'edit_invoice_template', $result];
|
||||
yield [$user, new InvoiceTemplate(), 'delete_invoice_template', $result];
|
||||
yield [$user, new \stdClass(), 'view', $result];
|
||||
yield [$user, null, 'edit', $result];
|
||||
yield [$user, $user, 'delete', $result];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ class RolePermissionVoterTest extends AbstractVoterTest
|
||||
$user4 = $this->getUser(4, User::ROLE_SUPER_ADMIN);
|
||||
|
||||
$invoice = [
|
||||
'create_invoice_template' => null,
|
||||
'manage_invoice_template' => null,
|
||||
'view_invoice' => null,
|
||||
'create_invoice' => null,
|
||||
];
|
||||
|
||||
@@ -4,6 +4,7 @@ includes:
|
||||
- %rootDir%/../phpstan-phpunit/extension.neon
|
||||
|
||||
parameters:
|
||||
tmpDir: %rootDir%/../../../var/cache/phpstan
|
||||
ignoreErrors:
|
||||
- '#Access to an undefined property Faker\\Generator::\$stateAbbr.#'
|
||||
- '#Access to an undefined property Faker\\Generator::\$catchPhrase.#'
|
||||
|
||||
Reference in New Issue
Block a user