added database driven system configurations with admin screen (#647)

This commit is contained in:
Kevin Papst
2019-03-22 20:58:38 +01:00
committed by GitHub
parent e990ae4800
commit 13d9f8f3f7
142 changed files with 2262 additions and 64727 deletions

View File

@@ -271,6 +271,15 @@ abstract class ControllerBaseTest extends WebTestCase
$this->assertHasFlashSuccess($client, 'Entry was deleted successful');
}
/**
* @param Client $client
* @param string|null $message
*/
protected function assertHasFlashSaveSuccess(Client $client)
{
$this->assertHasFlashSuccess($client, 'Saved changes successful');
}
/**
* @param Client $client
* @param string|null $message
@@ -284,6 +293,19 @@ abstract class ControllerBaseTest extends WebTestCase
}
}
/**
* @param Client $client
* @param string|null $message
*/
protected function assertHasFlashError(Client $client, string $message = null)
{
$node = $client->getCrawler()->filter('div.alert.alert-error.alert-dismissible');
$this->assertNotEmpty($node->text());
if (null !== $message) {
$this->assertContains($message, $node->text());
}
}
/**
* @param Client $client
* @param string $url

View File

@@ -0,0 +1,175 @@
<?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\Controller;
use App\Configuration\SystemConfiguration;
use App\Entity\User;
/**
* @coversDefaultClass \App\Controller\SystemConfigurationController
* @group integration
*/
class SystemConfigurationControllerTest extends ControllerBaseTest
{
public function testIsSecure()
{
$this->assertUrlIsSecured('/admin/system-config/');
$this->assertUrlIsSecuredForRole(User::ROLE_ADMIN, '/admin/system-config/');
}
public function testIndexAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
$this->assertAccessIsGranted($client, '/admin/system-config/');
$expectedForms = $this->getTestDataForms();
$result = $client->getCrawler()->filter('section.content div.box.box-primary');
$this->assertEquals(count($expectedForms), count($result));
$result = $client->getCrawler()->filter('section.content div.box.box-primary form');
$this->assertEquals(count($expectedForms), count($result));
foreach ($expectedForms as $formConfig) {
$result = $client->getCrawler()->filter($formConfig[0]);
$this->assertEquals(1, count($result));
$form = $result->form();
$this->assertStringEndsWith($formConfig[1], $form->getUri());
$this->assertEquals('POST', $form->getMethod());
}
}
public function getTestDataForms()
{
return [
['#system_configuration_form_timesheet', $this->createUrl('/admin/system-config/timesheet')],
['#system_configuration_form_form_customer', $this->createUrl('/admin/system-config/customer')],
];
}
public function testUpdateTimesheetConfig()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
$this->assertAccessIsGranted($client, '/admin/system-config/');
$configService = $client->getContainer()->get(SystemConfiguration::class);
$this->assertEquals(false, $configService->find('timesheet.markdown_content'));
$this->assertEquals(false, $configService->find('timesheet.duration_only'));
$this->assertEquals(true, $configService->find('timesheet.rules.allow_future_times'));
$this->assertEquals(3, $configService->find('timesheet.active_entries.hard_limit'));
$this->assertEquals(1, $configService->find('timesheet.active_entries.soft_limit'));
$form = $client->getCrawler()->filter('#system_configuration_form_timesheet')->form();
$client->submit($form, [
'system_configuration_form' => [
'configuration' => [
['name' => 'timesheet.markdown_content', 'value' => 1],
['name' => 'timesheet.duration_only', 'value' => 1],
['name' => 'timesheet.rules.allow_future_times', 'value' => false],
['name' => 'timesheet.active_entries.hard_limit', 'value' => 99],
['name' => 'timesheet.active_entries.soft_limit', 'value' => 77],
]
]
]);
$this->assertIsRedirect($client, $this->createUrl('/admin/system-config/'));
$client->followRedirect();
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertHasFlashSaveSuccess($client);
$configService = $client->getContainer()->get(SystemConfiguration::class);
$this->assertEquals(true, $configService->find('timesheet.markdown_content'));
$this->assertEquals(true, $configService->find('timesheet.duration_only'));
$this->assertEquals(false, $configService->find('timesheet.rules.allow_future_times'));
$this->assertEquals(99, $configService->find('timesheet.active_entries.hard_limit'));
$this->assertEquals(77, $configService->find('timesheet.active_entries.soft_limit'));
}
public function testUpdateTimesheetConfigValidation()
{
$this->assertFormHasValidationError(
User::ROLE_SUPER_ADMIN,
'/admin/system-config/',
'#system_configuration_form_timesheet',
[
'system_configuration_form' => [
'configuration' => [
['name' => 'timesheet.markdown_content', 'value' => 1],
['name' => 'timesheet.duration_only', 'value' => 1],
['name' => 'timesheet.rules.allow_future_times', 'value' => 1],
['name' => 'timesheet.active_entries.hard_limit', 'value' => -1],
['name' => 'timesheet.active_entries.soft_limit', 'value' => -1],
]
]
],
[
'#system_configuration_form_configuration_3_value',
'#system_configuration_form_configuration_4_value',
],
false
);
}
public function testUpdateCustomerConfig()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
$this->assertAccessIsGranted($client, '/admin/system-config/');
$configService = $client->getContainer()->get(SystemConfiguration::class);
$this->assertEquals('Europe/Berlin', $configService->find('defaults.customer.timezone'));
$this->assertEquals('DE', $configService->find('defaults.customer.country'));
$this->assertEquals('EUR', $configService->find('defaults.customer.currency'));
$form = $client->getCrawler()->filter('#system_configuration_form_form_customer')->form();
$client->submit($form, [
'system_configuration_form' => [
'configuration' => [
['name' => 'defaults.customer.timezone', 'value' => 'Atlantic/Canary'],
['name' => 'defaults.customer.country', 'value' => 'BB'],
['name' => 'defaults.customer.currency', 'value' => 'GBP'],
]
]
]);
$this->assertIsRedirect($client, $this->createUrl('/admin/system-config/'));
$client->followRedirect();
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertHasFlashSaveSuccess($client);
$configService = $client->getContainer()->get(SystemConfiguration::class);
$this->assertEquals('Atlantic/Canary', $configService->find('defaults.customer.timezone'));
$this->assertEquals('BB', $configService->find('defaults.customer.country'));
$this->assertEquals('GBP', $configService->find('defaults.customer.currency'));
}
public function testUpdateCustomerConfigValidation()
{
$this->assertFormHasValidationError(
User::ROLE_SUPER_ADMIN,
'/admin/system-config/',
'#system_configuration_form_form_customer',
[
'system_configuration_form' => [
'configuration' => [
['name' => 'defaults.customer.timezone', 'value' => 'XX'],
['name' => 'defaults.customer.country', 'value' => 1],
['name' => 'defaults.customer.currency', 'value' => 'XXX'],
]
]
],
[
'#system_configuration_form_configuration_0_value',
'#system_configuration_form_configuration_1_value',
'#system_configuration_form_configuration_2_value',
],
true
);
}
}

View File

@@ -187,7 +187,7 @@ class TimesheetControllerTest extends ControllerBaseTest
$this->assertIsRedirect($client, $this->createUrl('/timesheet/'));
$client->followRedirect();
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertHasFlashSuccess($client);
$this->assertHasFlashSuccess($client, 'Time recording was started');
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
/** @var Timesheet $timesheet */
@@ -198,7 +198,7 @@ class TimesheetControllerTest extends ControllerBaseTest
$this->assertEquals(1, $timesheet->getProject()->getId());
}
public function testStopActionDoesNotShowRateFieldsForUser()
public function testCreateActionDoesNotShowRateFieldsForUser()
{
$client = $this->getClientForAuthenticatedUser();
$this->request($client, '/timesheet/create');
@@ -246,6 +246,40 @@ class TimesheetControllerTest extends ControllerBaseTest
$this->assertNull($timesheet->getHourlyRate());
}
public function testStopActionFailsOnStoppedEntry()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
$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,
'project' => 1,
'activity' => 1,
]
]);
$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);
$this->request($client, '/timesheet/1/stop');
$this->assertIsRedirect($client, $this->createUrl('/timesheet/'));
$client->followRedirect();
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertHasFlashError($client, 'Time recording could not be stopped: Timesheet entry already stopped');
}
public function testCreateActionWithFromAndToValues()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
@@ -336,6 +370,21 @@ class TimesheetControllerTest extends ControllerBaseTest
'Could not find link to documentation'
);
// TODO more assertions
$form = $client->getCrawler()->filter('form[name=timesheet_edit_form]')->form();
$client->submit($form, [
'timesheet_edit_form' => [
'description' => 'foo-bar'
]
]);
$this->assertIsRedirect($client, $this->createUrl('/timesheet/'));
$client->followRedirect();
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertHasFlashSaveSuccess($client);
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
/** @var Timesheet $timesheet */
$timesheet = $em->getRepository(Timesheet::class)->find(1);
$this->assertEquals('foo-bar', $timesheet->getDescription());
}
}