detail pages for customers and projects (#1371)
This commit is contained in:
@@ -54,7 +54,6 @@ abstract class APIControllerBaseTest extends ControllerBaseTest
|
||||
|
||||
default:
|
||||
throw new \Exception(sprintf('Unknown role "%s"', $role));
|
||||
break;
|
||||
}
|
||||
|
||||
return $client;
|
||||
|
||||
@@ -47,7 +47,7 @@ class CreateUserCommandTest extends KernelTestCase
|
||||
|
||||
$output = $commandTester->getDisplay();
|
||||
$this->assertStringContainsString('[ERROR] plainPassword (foobar)', $output);
|
||||
$this->assertStringContainsString('The password is too short.', $output);
|
||||
$this->assertStringContainsString('This value is too short. It should have 8 characters or more.', $output);
|
||||
}
|
||||
|
||||
public function testCreateUser()
|
||||
|
||||
@@ -299,7 +299,7 @@ abstract class ControllerBaseTest extends WebTestCase
|
||||
protected function assertHasFlashSuccess(Client $client, string $message = null)
|
||||
{
|
||||
$node = $client->getCrawler()->filter('div.alert.alert-success.alert-dismissible');
|
||||
self::assertNotEmpty($node->text());
|
||||
self::assertGreaterThan(0, $node->count(), 'Could not find flash success message');
|
||||
if (null !== $message) {
|
||||
self::assertStringContainsString($message, $node->text());
|
||||
}
|
||||
@@ -312,7 +312,7 @@ abstract class ControllerBaseTest extends WebTestCase
|
||||
protected function assertHasFlashError(Client $client, string $message = null)
|
||||
{
|
||||
$node = $client->getCrawler()->filter('div.alert.alert-error.alert-dismissible');
|
||||
self::assertNotEmpty($node->text());
|
||||
self::assertGreaterThan(0, $node->count(), 'Could not find flash error message');
|
||||
if (null !== $message) {
|
||||
self::assertStringContainsString($message, $node->text());
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@ namespace App\Tests\Controller;
|
||||
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\CustomerMeta;
|
||||
use App\Entity\Project;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Tests\DataFixtures\CustomerFixtures;
|
||||
use App\Tests\DataFixtures\ProjectFixtures;
|
||||
use App\Tests\DataFixtures\TeamFixtures;
|
||||
use App\Tests\DataFixtures\TimesheetFixtures;
|
||||
use App\Tests\Mocks\CustomerTestMetaFieldSubscriberMock;
|
||||
@@ -69,21 +69,133 @@ class CustomerControllerTest extends ControllerBaseTest
|
||||
$this->assertDataTableRowCount($client, 'datatable_customer_admin', 5);
|
||||
}
|
||||
|
||||
public function testBudgetAction()
|
||||
public function testDetailsAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/customer/1/details');
|
||||
self::assertHasProgressbar($client);
|
||||
|
||||
$node = $client->getCrawler()->filter('div.box#customer_details_box');
|
||||
self::assertEquals(1, $node->count());
|
||||
$node = $client->getCrawler()->filter('div.box#project_list_box');
|
||||
self::assertEquals(1, $node->count());
|
||||
$node = $client->getCrawler()->filter('div.box#budget_box');
|
||||
self::assertEquals(1, $node->count());
|
||||
$node = $client->getCrawler()->filter('div.box#team_listing_box');
|
||||
self::assertEquals(1, $node->count());
|
||||
$node = $client->getCrawler()->filter('div.box#comments_box');
|
||||
self::assertEquals(1, $node->count());
|
||||
$node = $client->getCrawler()->filter('div.box#team_listing_box a.btn-box-tool');
|
||||
self::assertEquals(2, $node->count());
|
||||
}
|
||||
|
||||
public function testAddCommentAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/customer/1/details');
|
||||
$form = $client->getCrawler()->filter('form[name=customer_comment_form]')->form();
|
||||
$client->submit($form, [
|
||||
'customer_comment_form' => [
|
||||
'message' => 'A beautiful and short comment **with some** markdown formatting',
|
||||
]
|
||||
]);
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/customer/1/details'));
|
||||
$client->followRedirect();
|
||||
$node = $client->getCrawler()->filter('div.box#comments_box div.box-comments');
|
||||
self::assertStringContainsString('<p>A beautiful and short comment <strong>with some</strong> markdown formatting</p>', $node->html());
|
||||
}
|
||||
|
||||
public function testDeleteCommentAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/customer/1/details');
|
||||
$form = $client->getCrawler()->filter('form[name=customer_comment_form]')->form();
|
||||
$client->submit($form, [
|
||||
'customer_comment_form' => [
|
||||
'message' => 'Blah foo bar',
|
||||
]
|
||||
]);
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/customer/1/details'));
|
||||
$client->followRedirect();
|
||||
$node = $client->getCrawler()->filter('div.box#comments_box div.box-comments');
|
||||
self::assertStringContainsString('Blah foo bar', $node->html());
|
||||
$node = $client->getCrawler()->filter('div.box#comments_box .box-comment a.confirmation-link');
|
||||
self::assertEquals($this->createUrl('/admin/customer/1/comment_delete'), $node->attr('href'));
|
||||
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->request($client, '/admin/customer/1/comment_delete');
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/customer/1/details'));
|
||||
$client->followRedirect();
|
||||
$node = $client->getCrawler()->filter('div.box#comments_box div.box-comments');
|
||||
self::assertStringContainsString('There were no comments posted yet', $node->html());
|
||||
}
|
||||
|
||||
public function testPinCommentAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/customer/1/details');
|
||||
$form = $client->getCrawler()->filter('form[name=customer_comment_form]')->form();
|
||||
$client->submit($form, [
|
||||
'customer_comment_form' => [
|
||||
'message' => 'Blah foo bar',
|
||||
]
|
||||
]);
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/customer/1/details'));
|
||||
$client->followRedirect();
|
||||
$node = $client->getCrawler()->filter('div.box#comments_box div.box-comments');
|
||||
self::assertStringContainsString('Blah foo bar', $node->html());
|
||||
$node = $client->getCrawler()->filter('div.box#comments_box .box-comment a.btn.active');
|
||||
self::assertEquals(0, $node->count());
|
||||
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->request($client, '/admin/customer/1/comment_pin');
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/customer/1/details'));
|
||||
$client->followRedirect();
|
||||
$node = $client->getCrawler()->filter('div.box#comments_box .box-comment a.btn.active');
|
||||
self::assertEquals(1, $node->count());
|
||||
self::assertEquals($this->createUrl('/admin/customer/1/comment_pin'), $node->attr('href'));
|
||||
}
|
||||
|
||||
public function testCreateDefaultTeamAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/customer/1/details');
|
||||
$node = $client->getCrawler()->filter('div.box#team_listing_box .box-body');
|
||||
self::assertStringContainsString('Visible to everyone, as no team was assigned yet.', $node->text());
|
||||
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->request($client, '/admin/customer/1/create_team');
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/customer/1/details'));
|
||||
$client->followRedirect();
|
||||
$node = $client->getCrawler()->filter('div.box#team_listing_box .box-body');
|
||||
self::assertStringContainsString('Only visible to the following teams and all admins.', $node->text());
|
||||
$node = $client->getCrawler()->filter('div.box#team_listing_box .box-body table tbody tr');
|
||||
self::assertEquals(1, $node->count());
|
||||
}
|
||||
|
||||
public function testProjectsAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/customer/1/projects/1');
|
||||
$node = $client->getCrawler()->filter('div.box#project_list_box .box-body table tbody tr');
|
||||
self::assertEquals(1, $node->count());
|
||||
|
||||
/** @var EntityManager $em */
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
|
||||
$fixture = new TimesheetFixtures();
|
||||
$fixture->setAmount(10);
|
||||
$fixture->setProjects($em->getRepository(Project::class)->findAll());
|
||||
$fixture->setUser($this->getUserByRole($em, User::ROLE_ADMIN));
|
||||
$customer = $em->getRepository(Customer::class)->find(1);
|
||||
$fixture = new ProjectFixtures();
|
||||
$fixture->setAmount(9); // to trigger a second page (every third activity is hidden)
|
||||
$fixture->setCustomers([$customer]);
|
||||
$this->importFixture($em, $fixture);
|
||||
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/customer/1/budget');
|
||||
self::assertHasProgressbar($client);
|
||||
$this->assertAccessIsGranted($client, '/admin/customer/1/projects/1');
|
||||
|
||||
$node = $client->getCrawler()->filter('div.box#project_list_box .box-tools ul.pagination li');
|
||||
self::assertEquals(4, $node->count());
|
||||
|
||||
$node = $client->getCrawler()->filter('div.box#project_list_box .box-body table tbody tr');
|
||||
self::assertEquals(5, $node->count());
|
||||
}
|
||||
|
||||
public function testCreateAction()
|
||||
@@ -107,9 +219,8 @@ class CustomerControllerTest extends ControllerBaseTest
|
||||
'name' => 'Test Customer',
|
||||
]
|
||||
]);
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/customer/'));
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/customer/2/details'));
|
||||
$client->followRedirect();
|
||||
$this->assertHasDataTable($client);
|
||||
$this->assertHasFlashSuccess($client);
|
||||
}
|
||||
|
||||
@@ -137,9 +248,8 @@ class CustomerControllerTest extends ControllerBaseTest
|
||||
'name' => 'Test Customer 2'
|
||||
]
|
||||
]);
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/customer/'));
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/customer/1/details'));
|
||||
$client->followRedirect();
|
||||
$this->assertHasDataTable($client);
|
||||
$this->request($client, '/admin/customer/1/edit');
|
||||
$editForm = $client->getCrawler()->filter('form[name=customer_edit_form]')->form();
|
||||
$this->assertEquals('Test Customer 2', $editForm->get('customer_edit_form[name]')->getValue());
|
||||
|
||||
@@ -38,9 +38,9 @@ class DashboardControllerTest extends ControllerBaseTest
|
||||
]);
|
||||
$this->request($client, '/dashboard/');
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
self::assertEquals(1, $client->getCrawler()->filter('section.content .WidgetUserTeams')->count());
|
||||
self::assertEquals(1, $client->getCrawler()->filter('section.content #WidgetUserTeams')->count());
|
||||
// team 1 has no project assignment right now
|
||||
self::assertEquals(0, $client->getCrawler()->filter('section.content .WidgetUserTeamProjects')->count());
|
||||
self::assertEquals(0, $client->getCrawler()->filter('section.content #WidgetUserTeamProjects')->count());
|
||||
}
|
||||
|
||||
public function testIndexActionForAdmin()
|
||||
|
||||
@@ -29,7 +29,7 @@ class PermissionControllerTest extends ControllerBaseTest
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/permissions');
|
||||
$this->assertHasDataTable($client);
|
||||
$this->assertDataTableRowCount($client, 'datatable_user_admin_permissions', 83);
|
||||
$this->assertDataTableRowCount($client, 'datatable_user_admin_permissions', 101);
|
||||
$this->assertPageActions($client, [
|
||||
'back' => $this->createUrl('/admin/user/'),
|
||||
'roles modal-ajax-form' => $this->createUrl('/admin/permissions/roles/create'),
|
||||
|
||||
@@ -88,7 +88,7 @@ class ProfileControllerTest extends ControllerBaseTest
|
||||
$content = $client->getResponse()->getContent();
|
||||
|
||||
$this->assertStringContainsString('<h3 class="box-title">About me</h3>', $content);
|
||||
$this->assertStringContainsString('<span class="pull-right badge bg-blue">' . $username . '</span>', $content);
|
||||
$this->assertStringContainsString('<td class="text-nowrap pull-right">' . $username . '</td>', $content);
|
||||
}
|
||||
|
||||
public function getTabTestData()
|
||||
@@ -133,8 +133,8 @@ class ProfileControllerTest extends ControllerBaseTest
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
|
||||
$this->request($client, '/profile/' . UserFixtures::USERNAME_USER . '/edit');
|
||||
|
||||
/** @var User $user */
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
/** @var User $user */
|
||||
$user = $this->getUserByRole($em, User::ROLE_USER);
|
||||
|
||||
$this->assertEquals(UserFixtures::USERNAME_USER, $user->getUsername());
|
||||
@@ -209,8 +209,8 @@ class ProfileControllerTest extends ControllerBaseTest
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
|
||||
$this->request($client, '/profile/' . UserFixtures::USERNAME_USER . '/password');
|
||||
|
||||
/** @var User $user */
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
/** @var User $user */
|
||||
$user = $this->getUserByRole($em, User::ROLE_USER);
|
||||
|
||||
/** @var EncoderFactoryInterface $passwordEncoder */
|
||||
@@ -248,8 +248,8 @@ class ProfileControllerTest extends ControllerBaseTest
|
||||
$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');
|
||||
/** @var User $user */
|
||||
$user = $this->getUserByRole($em, User::ROLE_USER);
|
||||
/** @var EncoderFactoryInterface $passwordEncoder */
|
||||
$passwordEncoder = $client->getContainer()->get('test.PasswordEncoder');
|
||||
@@ -293,8 +293,8 @@ class ProfileControllerTest extends ControllerBaseTest
|
||||
$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');
|
||||
/** @var User $user */
|
||||
$user = $this->getUserByRole($em, User::ROLE_USER);
|
||||
|
||||
$this->assertEquals(['ROLE_USER'], $user->getRoles());
|
||||
@@ -385,8 +385,8 @@ class ProfileControllerTest extends ControllerBaseTest
|
||||
$client = $this->getClientForAuthenticatedUser($role);
|
||||
$this->request($client, '/profile/' . $username . '/prefs');
|
||||
|
||||
/** @var User $user */
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
/** @var User $user */
|
||||
$user = $this->getUserByName($em, $username);
|
||||
|
||||
$this->assertEquals($hourlyRateOriginal, $user->getPreferenceValue(UserPreference::HOURLY_RATE));
|
||||
|
||||
@@ -13,6 +13,7 @@ use App\Entity\Project;
|
||||
use App\Entity\ProjectMeta;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\User;
|
||||
use App\Tests\DataFixtures\ActivityFixtures;
|
||||
use App\Tests\DataFixtures\CustomerFixtures;
|
||||
use App\Tests\DataFixtures\ProjectFixtures;
|
||||
use App\Tests\DataFixtures\TeamFixtures;
|
||||
@@ -69,21 +70,150 @@ class ProjectControllerTest extends ControllerBaseTest
|
||||
$this->assertDataTableRowCount($client, 'datatable_project_admin', 5);
|
||||
}
|
||||
|
||||
public function testBudgetAction()
|
||||
public function testDetailsAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
/** @var EntityManager $em */
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
|
||||
$project = $em->getRepository(Project::class)->find(1);
|
||||
|
||||
$fixture = new TimesheetFixtures();
|
||||
$fixture->setAmount(10);
|
||||
$fixture->setProjects($em->getRepository(Project::class)->findAll());
|
||||
$fixture->setProjects([$project]);
|
||||
$fixture->setUser($this->getUserByRole($em, User::ROLE_ADMIN));
|
||||
$this->importFixture($em, $fixture);
|
||||
|
||||
$project = $em->getRepository(Project::class)->find(1);
|
||||
$fixture = new ActivityFixtures();
|
||||
$fixture->setAmount(6); // to trigger a second page
|
||||
$fixture->setProjects([$project]);
|
||||
$this->importFixture($em, $fixture);
|
||||
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/project/1/budget');
|
||||
$this->assertAccessIsGranted($client, '/admin/project/1/details');
|
||||
self::assertHasProgressbar($client);
|
||||
|
||||
$node = $client->getCrawler()->filter('div.box#project_details_box');
|
||||
self::assertEquals(1, $node->count());
|
||||
$node = $client->getCrawler()->filter('div.box#activity_list_box');
|
||||
self::assertEquals(1, $node->count());
|
||||
$node = $client->getCrawler()->filter('div.box#budget_box');
|
||||
self::assertEquals(1, $node->count());
|
||||
$node = $client->getCrawler()->filter('div.box#team_listing_box');
|
||||
self::assertEquals(1, $node->count());
|
||||
$node = $client->getCrawler()->filter('div.box#comments_box');
|
||||
self::assertEquals(1, $node->count());
|
||||
$node = $client->getCrawler()->filter('div.box#team_listing_box a.btn-box-tool');
|
||||
self::assertEquals(2, $node->count());
|
||||
}
|
||||
|
||||
public function testAddCommentAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/project/1/details');
|
||||
$form = $client->getCrawler()->filter('form[name=project_comment_form]')->form();
|
||||
$client->submit($form, [
|
||||
'project_comment_form' => [
|
||||
'message' => 'A beautiful and long comment **with some** markdown formatting',
|
||||
]
|
||||
]);
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/project/1/details'));
|
||||
$client->followRedirect();
|
||||
$node = $client->getCrawler()->filter('div.box#comments_box div.box-comments');
|
||||
self::assertStringContainsString('<p>A beautiful and long comment <strong>with some</strong> markdown formatting</p>', $node->html());
|
||||
}
|
||||
|
||||
public function testDeleteCommentAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/project/1/details');
|
||||
$form = $client->getCrawler()->filter('form[name=project_comment_form]')->form();
|
||||
$client->submit($form, [
|
||||
'project_comment_form' => [
|
||||
'message' => 'Foo bar blub',
|
||||
]
|
||||
]);
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/project/1/details'));
|
||||
$client->followRedirect();
|
||||
$node = $client->getCrawler()->filter('div.box#comments_box div.box-comments');
|
||||
self::assertStringContainsString('Foo bar blub', $node->html());
|
||||
$node = $client->getCrawler()->filter('div.box#comments_box .box-comment a.confirmation-link');
|
||||
self::assertEquals($this->createUrl('/admin/project/1/comment_delete'), $node->attr('href'));
|
||||
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->request($client, '/admin/project/1/comment_delete');
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/project/1/details'));
|
||||
$client->followRedirect();
|
||||
$node = $client->getCrawler()->filter('div.box#comments_box div.box-comments');
|
||||
self::assertStringContainsString('There were no comments posted yet', $node->html());
|
||||
}
|
||||
|
||||
public function testPinCommentAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/project/1/details');
|
||||
$form = $client->getCrawler()->filter('form[name=project_comment_form]')->form();
|
||||
$client->submit($form, [
|
||||
'project_comment_form' => [
|
||||
'message' => 'Foo bar blub',
|
||||
]
|
||||
]);
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/project/1/details'));
|
||||
$client->followRedirect();
|
||||
$node = $client->getCrawler()->filter('div.box#comments_box div.box-comments');
|
||||
self::assertStringContainsString('Foo bar blub', $node->html());
|
||||
$node = $client->getCrawler()->filter('div.box#comments_box .box-comment a.btn.active');
|
||||
self::assertEquals(0, $node->count());
|
||||
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->request($client, '/admin/project/1/comment_pin');
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/project/1/details'));
|
||||
$client->followRedirect();
|
||||
$node = $client->getCrawler()->filter('div.box#comments_box .box-comment a.btn.active');
|
||||
self::assertEquals(1, $node->count());
|
||||
self::assertEquals($this->createUrl('/admin/project/1/comment_pin'), $node->attr('href'));
|
||||
}
|
||||
|
||||
public function testCreateDefaultTeamAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/project/1/details');
|
||||
$node = $client->getCrawler()->filter('div.box#team_listing_box .box-body');
|
||||
self::assertStringContainsString('Visible to everyone, as no team was assigned yet.', $node->text());
|
||||
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->request($client, '/admin/project/1/create_team');
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/project/1/details'));
|
||||
$client->followRedirect();
|
||||
$node = $client->getCrawler()->filter('div.box#team_listing_box .box-body');
|
||||
self::assertStringContainsString('Only visible to the following teams and all admins.', $node->text());
|
||||
$node = $client->getCrawler()->filter('div.box#team_listing_box .box-body table tbody tr');
|
||||
self::assertEquals(1, $node->count());
|
||||
}
|
||||
|
||||
public function testActivitiesAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/project/1/activities/1');
|
||||
self::assertEquals('', $client->getResponse()->getContent());
|
||||
|
||||
/** @var EntityManager $em */
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
$project = $em->getRepository(Project::class)->find(1);
|
||||
$fixture = new ActivityFixtures();
|
||||
$fixture->setAmount(9); // to trigger a second page (every third activity is hidden)
|
||||
$fixture->setProjects([$project]);
|
||||
$this->importFixture($em, $fixture);
|
||||
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
$this->assertAccessIsGranted($client, '/admin/project/1/activities/1');
|
||||
|
||||
$node = $client->getCrawler()->filter('div.box#activity_list_box .box-tools ul.pagination li');
|
||||
self::assertEquals(4, $node->count());
|
||||
|
||||
$node = $client->getCrawler()->filter('div.box#activity_list_box .box-body table tbody tr');
|
||||
self::assertEquals(5, $node->count());
|
||||
}
|
||||
|
||||
public function testCreateAction()
|
||||
@@ -98,9 +228,8 @@ class ProjectControllerTest extends ControllerBaseTest
|
||||
'name' => 'Test 2',
|
||||
]
|
||||
]);
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/project/'));
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/project/2/details'));
|
||||
$client->followRedirect();
|
||||
$this->assertHasDataTable($client);
|
||||
$this->assertHasFlashSuccess($client);
|
||||
}
|
||||
|
||||
@@ -160,9 +289,8 @@ class ProjectControllerTest extends ControllerBaseTest
|
||||
$client->submit($form, [
|
||||
'project_edit_form' => ['name' => 'Test 2']
|
||||
]);
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/project/'));
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/project/1/details'));
|
||||
$client->followRedirect();
|
||||
$this->assertHasDataTable($client);
|
||||
$this->request($client, '/admin/project/1/edit');
|
||||
$editForm = $client->getCrawler()->filter('form[name=project_edit_form]')->form();
|
||||
$this->assertEquals('Test 2', $editForm->get('project_edit_form[name]')->getValue());
|
||||
|
||||
@@ -219,7 +219,7 @@ class SystemConfigurationControllerTest extends ControllerBaseTest
|
||||
$client->submit($form, [
|
||||
'system_configuration_form_theme' => [
|
||||
'configuration' => [
|
||||
['name' => 'theme.select_type', 'value' => 'selectpicker'],
|
||||
['name' => 'theme.autocomplete_chars', 'value' => 5],
|
||||
['name' => 'timesheet.markdown_content', 'value' => 1],
|
||||
]
|
||||
]
|
||||
|
||||
@@ -123,6 +123,29 @@ class TeamControllerTest extends ControllerBaseTest
|
||||
$this->assertEquals('Test Team 2', $editForm->get('team_edit_form[name]')->getValue());
|
||||
}
|
||||
|
||||
public function testEditMemberAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
$fixture = new TeamFixtures();
|
||||
$fixture->setAmount(2);
|
||||
$this->importFixture($em, $fixture);
|
||||
|
||||
$this->assertAccessIsGranted($client, '/admin/teams/1/edit_member');
|
||||
$form = $client->getCrawler()->filter('form[name=team_edit_form]')->form();
|
||||
$this->assertNotEmpty($form->get('team_edit_form[name]')->getValue());
|
||||
$client->submit($form, [
|
||||
'team_edit_form' => [
|
||||
'name' => 'Test Team 2'
|
||||
]
|
||||
]);
|
||||
$this->assertIsRedirect($client, $this->createUrl('/admin/teams/1/edit'));
|
||||
$client->followRedirect();
|
||||
$editForm = $client->getCrawler()->filter('form[name=team_edit_form]')->form();
|
||||
$this->assertEquals('Test Team 2', $editForm->get('team_edit_form[name]')->getValue());
|
||||
}
|
||||
|
||||
public function testEditCustomerAccessAction()
|
||||
{
|
||||
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace App\Tests\DataFixtures;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Project;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use Faker\Factory;
|
||||
|
||||
/**
|
||||
@@ -36,6 +36,10 @@ final class ActivityFixtures extends Fixture
|
||||
* @var callable
|
||||
*/
|
||||
private $callback;
|
||||
/**
|
||||
* @var Project[]
|
||||
*/
|
||||
private $projects = [];
|
||||
|
||||
/**
|
||||
* Will be called prior to persisting the object.
|
||||
@@ -79,15 +83,28 @@ final class ActivityFixtures extends Fixture
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Project[] $projects
|
||||
* @return ActivityFixtures
|
||||
*/
|
||||
public function setProjects(array $projects): ActivityFixtures
|
||||
{
|
||||
$this->projects = $projects;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(ObjectManager $manager)
|
||||
{
|
||||
$projects = $this->getAllProjects($manager);
|
||||
$projects = $this->projects;
|
||||
if (empty($projects)) {
|
||||
$projects = $this->getAllProjects($manager);
|
||||
}
|
||||
$faker = Factory::create();
|
||||
|
||||
// random amount of timesheet entries for every user
|
||||
for ($i = 0; $i < $this->amount; $i++) {
|
||||
$project = null;
|
||||
if (false === $this->isGlobal) {
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace App\Tests\DataFixtures;
|
||||
|
||||
use App\Entity\Customer;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use Faker\Factory;
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace App\Tests\DataFixtures;
|
||||
|
||||
use App\Entity\InvoiceTemplate;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use Faker\Factory;
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace App\Tests\DataFixtures;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Project;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use Faker\Factory;
|
||||
|
||||
/**
|
||||
@@ -32,6 +32,10 @@ final class ProjectFixtures extends Fixture
|
||||
* @var callable
|
||||
*/
|
||||
private $callback;
|
||||
/**
|
||||
* @var Customer[]
|
||||
*/
|
||||
private $customers = [];
|
||||
|
||||
public function getAmount(): int
|
||||
{
|
||||
@@ -52,6 +56,17 @@ final class ProjectFixtures extends Fixture
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Customer[] $customers
|
||||
* @return ProjectFixtures
|
||||
*/
|
||||
public function setCustomers(array $customers): ProjectFixtures
|
||||
{
|
||||
$this->customers = $customers;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will be called prior to persisting the object.
|
||||
*
|
||||
@@ -70,7 +85,10 @@ final class ProjectFixtures extends Fixture
|
||||
*/
|
||||
public function load(ObjectManager $manager)
|
||||
{
|
||||
$customers = $this->getAllCustomers($manager);
|
||||
$customers = $this->customers;
|
||||
if (empty($customers)) {
|
||||
$customers = $this->getAllCustomers($manager);
|
||||
}
|
||||
$faker = Factory::create();
|
||||
|
||||
for ($i = 0; $i < $this->amount; $i++) {
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace App\Tests\DataFixtures;
|
||||
|
||||
use App\Entity\Tag;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
|
||||
/**
|
||||
* Defines the sample data to load in during controller tests.
|
||||
|
||||
@@ -13,7 +13,7 @@ use App\Entity\Customer;
|
||||
use App\Entity\Team;
|
||||
use App\Entity\User;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use Faker\Factory;
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,7 @@ use App\Entity\User;
|
||||
use App\Entity\UserPreference;
|
||||
use App\Timesheet\Util;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
use Faker\Factory;
|
||||
|
||||
/**
|
||||
|
||||
50
tests/Entity/AbstractCommentEntityTest.php
Normal file
50
tests/Entity/AbstractCommentEntityTest.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\CommentInterface;
|
||||
use App\Entity\User;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
abstract class AbstractCommentEntityTest extends TestCase
|
||||
{
|
||||
abstract protected function getEntity(): CommentInterface;
|
||||
|
||||
public function testDefaultValues()
|
||||
{
|
||||
$sut = $this->getEntity();
|
||||
|
||||
self::assertNull($sut->getId());
|
||||
self::assertNull($sut->getMessage());
|
||||
self::assertNull($sut->getCreatedBy());
|
||||
self::assertNotNull($sut->getCreatedAt());
|
||||
self::assertInstanceOf(\DateTime::class, $sut->getCreatedAt());
|
||||
self::assertFalse($sut->isPinned());
|
||||
}
|
||||
|
||||
public function testSetterAndGetter()
|
||||
{
|
||||
$sut = $this->getEntity();
|
||||
|
||||
$sut->setPinned(true);
|
||||
self::assertTrue($sut->isPinned());
|
||||
|
||||
$user = new User();
|
||||
$sut->setCreatedBy($user);
|
||||
self::assertSame($user, $sut->getCreatedBy());
|
||||
|
||||
$date = new \DateTime();
|
||||
$sut->setCreatedAt($date);
|
||||
self::assertSame($date, $sut->getCreatedAt());
|
||||
|
||||
$sut->setMessage('slödkfjaölsdkjflaksjdfölaksjdfölakjsdöfl');
|
||||
self::assertEquals('slödkfjaölsdkjflaksjdfölaksjdfölakjsdöfl', $sut->getMessage());
|
||||
}
|
||||
}
|
||||
36
tests/Entity/CustomerCommentTest.php
Normal file
36
tests/Entity/CustomerCommentTest.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?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\CommentInterface;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\CustomerComment;
|
||||
|
||||
/**
|
||||
* @covers \App\Entity\CustomerComment
|
||||
* @covers \App\Entity\CommentTableTypeTrait
|
||||
*/
|
||||
class CustomerCommentTest extends AbstractCommentEntityTest
|
||||
{
|
||||
protected function getEntity(): CommentInterface
|
||||
{
|
||||
return new CustomerComment();
|
||||
}
|
||||
|
||||
public function testEntitySpecificMethods()
|
||||
{
|
||||
$sut = new CustomerComment();
|
||||
self::assertNull($sut->getCustomer());
|
||||
|
||||
$customer = new Customer();
|
||||
self::assertInstanceOf(CustomerComment::class, $sut->setCustomer($customer));
|
||||
self::assertSame($customer, $sut->getCustomer());
|
||||
}
|
||||
}
|
||||
36
tests/Entity/ProjectCommentTest.php
Normal file
36
tests/Entity/ProjectCommentTest.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?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\CommentInterface;
|
||||
use App\Entity\Project;
|
||||
use App\Entity\ProjectComment;
|
||||
|
||||
/**
|
||||
* @covers \App\Entity\ProjectComment
|
||||
* @covers \App\Entity\CommentTableTypeTrait
|
||||
*/
|
||||
class ProjectCommentTest extends AbstractCommentEntityTest
|
||||
{
|
||||
protected function getEntity(): CommentInterface
|
||||
{
|
||||
return new ProjectComment();
|
||||
}
|
||||
|
||||
public function testEntitySpecificMethods()
|
||||
{
|
||||
$sut = new ProjectComment();
|
||||
self::assertNull($sut->getProject());
|
||||
|
||||
$project = new Project();
|
||||
self::assertInstanceOf(ProjectComment::class, $sut->setProject($project));
|
||||
self::assertSame($project, $sut->getProject());
|
||||
}
|
||||
}
|
||||
46
tests/Form/Extension/DocumentationLinkExtensionTest.php
Normal file
46
tests/Form/Extension/DocumentationLinkExtensionTest.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?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\Form\Extension;
|
||||
|
||||
use App\Form\Extension\DocumentationLinkExtension;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* @covers \App\Form\Extension\DocumentationLinkExtension
|
||||
*/
|
||||
class DocumentationLinkExtensionTest extends TestCase
|
||||
{
|
||||
public function testExtendedTypes()
|
||||
{
|
||||
self::assertEquals([FormType::class], DocumentationLinkExtension::getExtendedTypes());
|
||||
}
|
||||
|
||||
public function testConfigureOptions()
|
||||
{
|
||||
$resolver = new OptionsResolver();
|
||||
$sut = new DocumentationLinkExtension();
|
||||
$sut->configureOptions($resolver);
|
||||
self::assertEquals(['docu_chapter'], $resolver->getDefinedOptions());
|
||||
self::assertTrue($resolver->hasDefault('docu_chapter'));
|
||||
self::assertFalse($resolver->isRequired('docu_chapter'));
|
||||
|
||||
$result = $resolver->resolve(['docu_chapter' => 'foo']);
|
||||
self::assertEquals(['docu_chapter' => 'foo'], $result);
|
||||
|
||||
$result = $resolver->resolve([]);
|
||||
self::assertEquals(['docu_chapter' => ''], $result);
|
||||
|
||||
$this->expectException(InvalidOptionsException::class);
|
||||
$resolver->resolve(['docu_chapter' => true]);
|
||||
}
|
||||
}
|
||||
42
tests/Form/Extension/EnhancedChoiceTypeExtensionTest.php
Normal file
42
tests/Form/Extension/EnhancedChoiceTypeExtensionTest.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?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\Form\Extension;
|
||||
|
||||
use App\Form\Extension\EnhancedChoiceTypeExtension;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* @covers \App\Form\Extension\EnhancedChoiceTypeExtension
|
||||
*/
|
||||
class EnhancedChoiceTypeExtensionTest extends TestCase
|
||||
{
|
||||
public function testExtendedTypes()
|
||||
{
|
||||
self::assertEquals([EntityType::class, ChoiceType::class], EnhancedChoiceTypeExtension::getExtendedTypes());
|
||||
}
|
||||
|
||||
public function testConfigureOptions()
|
||||
{
|
||||
$resolver = new OptionsResolver();
|
||||
$sut = new EnhancedChoiceTypeExtension();
|
||||
$sut->configureOptions($resolver);
|
||||
self::assertEquals(['selectpicker', 'search'], $resolver->getDefinedOptions());
|
||||
self::assertTrue($resolver->hasDefault('selectpicker'));
|
||||
self::assertTrue($resolver->hasDefault('search'));
|
||||
self::assertFalse($resolver->isRequired('selectpicker'));
|
||||
self::assertFalse($resolver->isRequired('search'));
|
||||
|
||||
$result = $resolver->resolve([]);
|
||||
self::assertEquals(['selectpicker' => true, 'search' => true], $result);
|
||||
}
|
||||
}
|
||||
46
tests/Form/Extension/IconExtensionTest.php
Normal file
46
tests/Form/Extension/IconExtensionTest.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?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\Form\Extension;
|
||||
|
||||
use App\Form\Extension\IconExtension;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* @covers \App\Form\Extension\IconExtension
|
||||
*/
|
||||
class IconExtensionTest extends TestCase
|
||||
{
|
||||
public function testExtendedTypes()
|
||||
{
|
||||
self::assertEquals([TextType::class], IconExtension::getExtendedTypes());
|
||||
}
|
||||
|
||||
public function testConfigureOptions()
|
||||
{
|
||||
$resolver = new OptionsResolver();
|
||||
$sut = new IconExtension();
|
||||
$sut->configureOptions($resolver);
|
||||
self::assertEquals(['icon'], $resolver->getDefinedOptions());
|
||||
self::assertTrue($resolver->hasDefault('icon'));
|
||||
self::assertFalse($resolver->isRequired('icon'));
|
||||
|
||||
$result = $resolver->resolve(['icon' => 'foo']);
|
||||
self::assertEquals(['icon' => 'foo'], $result);
|
||||
|
||||
$result = $resolver->resolve([]);
|
||||
self::assertEquals(['icon' => ''], $result);
|
||||
|
||||
$this->expectException(InvalidOptionsException::class);
|
||||
$resolver->resolve(['icon' => true]);
|
||||
}
|
||||
}
|
||||
@@ -60,4 +60,33 @@ class MarkdownExtensionTest extends TestCase
|
||||
$sut->timesheetContent("- test\n- foo\n\nfoo __bar__")
|
||||
);
|
||||
}
|
||||
|
||||
public function testCommentContent()
|
||||
{
|
||||
$loader = $this->createMock(ConfigLoaderInterface::class);
|
||||
$config = new TimesheetConfiguration($loader, ['markdown_content' => false]);
|
||||
$sut = new MarkdownExtension(new Markdown(), $config);
|
||||
$this->assertEquals(
|
||||
"<p>- test<br />\n- foo</p>",
|
||||
$sut->commentContent("- test\n- foo", true)
|
||||
);
|
||||
$this->assertEquals(
|
||||
"- test\n- foo",
|
||||
$sut->commentContent("- test\n- foo", false)
|
||||
);
|
||||
|
||||
$loremIpsum = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.';
|
||||
|
||||
$this->assertEquals('', $sut->commentContent(null));
|
||||
$this->assertEquals('', $sut->commentContent(''));
|
||||
$this->assertEquals('<p>' . $loremIpsum . '</p>', $sut->commentContent($loremIpsum, true));
|
||||
$this->assertEquals('Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut l …', $sut->commentContent($loremIpsum));
|
||||
|
||||
$config = new TimesheetConfiguration($loader, ['markdown_content' => true]);
|
||||
$sut = new MarkdownExtension(new Markdown(), $config);
|
||||
$this->assertEquals(
|
||||
"<ul>\n<li>test</li>\n<li>foo</li>\n</ul>\n<p>foo <strong>bar</strong></p>",
|
||||
$sut->commentContent("- test\n- foo\n\nfoo __bar__")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,9 @@ class MarkdownTest extends TestCase
|
||||
<pre><code>ssdfsdf</code></pre>
|
||||
<p>sdfsdf <a href="#test-1">asdfasdf</a> asdfasdf</p>
|
||||
<h1 id="test-1">test</h1>
|
||||
<p>aasdfasdf</p>
|
||||
<p>aasdfasdf<br />
|
||||
1111<br />
|
||||
222</p>
|
||||
EOT;
|
||||
|
||||
$markdown = <<<EOT
|
||||
@@ -52,6 +54,8 @@ sdfsdf [asdfasdf](#test-1) asdfasdf
|
||||
|
||||
# test
|
||||
aasdfasdf
|
||||
1111
|
||||
222
|
||||
EOT;
|
||||
$this->assertEquals($html, $sut->toHtml($markdown));
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ use App\Repository\RolePermissionRepository;
|
||||
use App\Security\AclDecisionManager;
|
||||
use App\Security\RolePermissionManager;
|
||||
use App\Voter\AbstractVoter;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
abstract class AbstractVoterTest extends TestCase
|
||||
@@ -41,20 +40,23 @@ abstract class AbstractVoterTest extends TestCase
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param string $role
|
||||
* @param string|null $role
|
||||
* @return User
|
||||
*/
|
||||
protected function getUser($id, $role)
|
||||
protected function getUser($id, ?string $role)
|
||||
{
|
||||
$roles = [];
|
||||
if (!empty($role)) {
|
||||
$roles[] = $role;
|
||||
}
|
||||
|
||||
$user = $this->getMockBuilder(User::class)->getMock();
|
||||
$user->method('getId')->willReturn($id);
|
||||
$user->method('getRoles')->willReturn($roles);
|
||||
$user->method('getTeams')->willReturn(new ArrayCollection());
|
||||
$user = new User();
|
||||
$user->setRoles($roles);
|
||||
|
||||
$reflection = new \ReflectionClass($user);
|
||||
$property = $reflection->getProperty('id');
|
||||
$property->setAccessible(true);
|
||||
$property->setValue($user, $id);
|
||||
|
||||
return $user;
|
||||
}
|
||||
@@ -69,16 +71,16 @@ abstract class AbstractVoterTest extends TestCase
|
||||
if (!$overwrite) {
|
||||
$activities = ['view_activity', 'edit_activity', 'budget_activity', 'delete_activity', 'create_activity'];
|
||||
$activitiesTeam = ['view_activity', 'create_activity', 'edit_teamlead_activity', 'budget_teamlead_activity'];
|
||||
$projects = ['view_project', 'edit_project', 'budget_project', 'delete_project', 'create_project'];
|
||||
$projectsTeam = ['view_project', 'edit_teamlead_project', 'budget_teamlead_project', 'permissions_teamlead_project'];
|
||||
$customers = ['view_customer', 'edit_customer', 'budget_customer', 'delete_customer', 'create_customer'];
|
||||
$customersTeam = ['view_customer', 'edit_teamlead_customer', 'budget_teamlead_customer'];
|
||||
$projects = ['view_project', 'create_project', 'edit_project', 'budget_project', 'delete_project', 'permissions_project', 'comments_project', 'details_project'];
|
||||
$projectsTeam = ['view_teamlead_project', 'edit_teamlead_project', 'budget_teamlead_project', 'permissions_teamlead_project', 'comments_teamlead_project', 'details_teamlead_project'];
|
||||
$customers = ['view_customer', 'create_customer', 'edit_customer', 'budget_customer', 'delete_customer', 'permissions_customer', 'comments_customer', 'details_customer'];
|
||||
$customersTeam = ['view_teamlead_customer', 'edit_teamlead_customer', 'budget_teamlead_customer', 'comments_teamlead_customer', 'details_teamlead_customer'];
|
||||
$invoice = ['view_invoice', 'create_invoice'];
|
||||
$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'];
|
||||
$profileOther = ['view_other_profile', 'edit_other_profile', 'delete_other_profile', 'password_other_profile', 'roles_other_profile', 'preferences_other_profile', 'api-token_other_profile'];
|
||||
$profileOther = ['view_other_profile', 'edit_other_profile', 'password_other_profile', 'roles_other_profile', 'preferences_other_profile', 'api-token_other_profile'];
|
||||
$user = ['view_user', 'create_user', 'delete_user'];
|
||||
$rate = ['view_rate_own_timesheet', 'edit_rate_own_timesheet'];
|
||||
$rateOther = ['view_rate_other_timesheet', 'edit_rate_other_timesheet'];
|
||||
@@ -87,7 +89,7 @@ abstract class AbstractVoterTest extends TestCase
|
||||
$roleUser = ['edit_team_activity', 'edit_team_project', 'edit_team_customer'];
|
||||
$roleTeamlead = ['view_rate_own_timesheet', 'view_rate_other_timesheet', 'hourly-rate_own_profile'];
|
||||
$roleAdmin = ['hourly-rate_own_profile', 'edit_exported_timesheet'];
|
||||
$roleSuperAdmin = ['hourly-rate_own_profile', 'hourly-rate_other_profile', 'delete_own_profile', 'roles_own_profile', 'system_information', 'system_configuration', 'plugins', 'edit_exported_timesheet'];
|
||||
$roleSuperAdmin = ['hourly-rate_own_profile', 'hourly-rate_other_profile', 'roles_own_profile', 'system_information', 'system_configuration', 'plugins', 'edit_exported_timesheet'];
|
||||
|
||||
$permissions = [
|
||||
'ROLE_USER' => array_merge($timesheet, $profile, $roleUser),
|
||||
|
||||
@@ -21,65 +21,65 @@ use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
*/
|
||||
class CustomerVoterTest extends AbstractVoterTest
|
||||
{
|
||||
/**
|
||||
* @dataProvider getTestData
|
||||
*/
|
||||
public function testVote(User $user, $subject, $attribute, $result)
|
||||
{
|
||||
$this->assertVote($user, $subject, $attribute, $result);
|
||||
}
|
||||
|
||||
protected function assertVote(User $user, $subject, $attribute, $result)
|
||||
{
|
||||
$token = new UsernamePasswordToken($user, 'foo', 'bar', $user->getRoles());
|
||||
$sut = $this->getVoter(CustomerVoter::class, $user);
|
||||
|
||||
$this->assertEquals($result, $sut->vote($token, $subject, [$attribute]));
|
||||
$actual = $sut->vote($token, $subject, [$attribute]);
|
||||
$this->assertEquals($result, $actual, sprintf('Failed voting "%s" for User with roles %s.', $attribute, implode(', ', $user->getRoles())));
|
||||
}
|
||||
|
||||
public function getTestData()
|
||||
public function testVote()
|
||||
{
|
||||
$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);
|
||||
$userNoRole = $this->getUser(0, 'foo');
|
||||
$userStandard = $this->getUser(1, User::ROLE_USER);
|
||||
$userTeamlead = $this->getUser(2, User::ROLE_TEAMLEAD);
|
||||
$userAdmin = $this->getUser(3, User::ROLE_ADMIN);
|
||||
$userSuperAdmin = $this->getUser(4, User::ROLE_SUPER_ADMIN);
|
||||
|
||||
$result = VoterInterface::ACCESS_GRANTED;
|
||||
foreach ([$user3, $user4] as $user) {
|
||||
yield [$user, new Customer(), 'view', $result];
|
||||
yield [$user, new Customer(), 'edit', $result];
|
||||
yield [$user, new Customer(), 'budget', $result];
|
||||
yield [$user, new Customer(), 'delete', $result];
|
||||
foreach ([$userAdmin, $userSuperAdmin] as $user) {
|
||||
$this->assertVote($user, new Customer(), 'view', $result);
|
||||
$this->assertVote($user, new Customer(), 'edit', $result);
|
||||
$this->assertVote($user, new Customer(), 'budget', $result);
|
||||
$this->assertVote($user, new Customer(), 'delete', $result);
|
||||
}
|
||||
|
||||
foreach ([$user2] as $user) {
|
||||
yield [$user, new Customer(), 'view', $result];
|
||||
$team = new Team();
|
||||
$team->setTeamLead($userTeamlead);
|
||||
foreach ([$userTeamlead] as $user) {
|
||||
$customer = new Customer();
|
||||
$team->addCustomer($customer);
|
||||
$this->assertVote($user, $customer, 'view', $result);
|
||||
$team->removeCustomer($customer);
|
||||
}
|
||||
|
||||
$userTeamlead = $this->getUser(2, User::ROLE_TEAMLEAD);
|
||||
|
||||
$result = VoterInterface::ACCESS_DENIED;
|
||||
foreach ([$user0, $user1] as $user) {
|
||||
yield [$user, new Customer(), 'view', $result];
|
||||
yield [$user, new Customer(), 'edit', $result];
|
||||
yield [$user, new Customer(), 'budget', $result];
|
||||
yield [$user, new Customer(), 'delete', $result];
|
||||
foreach ([$userNoRole, $userStandard] as $user) {
|
||||
$this->assertVote($user, new Customer(), 'view', $result);
|
||||
$this->assertVote($user, new Customer(), 'edit', $result);
|
||||
$this->assertVote($user, new Customer(), 'budget', $result);
|
||||
$this->assertVote($user, new Customer(), 'delete', $result);
|
||||
}
|
||||
|
||||
foreach ([$user2] as $user) {
|
||||
yield [$user, new Customer(), 'edit', $result];
|
||||
yield [$user, new Customer(), 'budget', $result];
|
||||
yield [$user, new Customer(), 'delete', $result];
|
||||
foreach ([$userTeamlead] as $user) {
|
||||
$this->assertVote($user, new Customer(), 'edit', $result);
|
||||
$this->assertVote($user, new Customer(), 'budget', $result);
|
||||
$this->assertVote($user, new Customer(), 'delete', $result);
|
||||
}
|
||||
|
||||
$result = VoterInterface::ACCESS_ABSTAIN;
|
||||
foreach ([$user0, $user1, $user2] as $user) {
|
||||
yield [$user, new Customer(), 'view_customer', $result];
|
||||
yield [$user, new Customer(), 'edit_customer', $result];
|
||||
yield [$user, new Customer(), 'budget_customer', $result];
|
||||
yield [$user, new Customer(), 'delete_customer', $result];
|
||||
yield [$user, new \stdClass(), 'view', $result];
|
||||
yield [$user, null, 'edit', $result];
|
||||
yield [$user, $user, 'delete', $result];
|
||||
foreach ([$userNoRole, $userStandard, $userTeamlead] as $user) {
|
||||
$this->assertVote($user, new Customer(), 'view_customer', $result);
|
||||
$this->assertVote($user, new Customer(), 'edit_customer', $result);
|
||||
$this->assertVote($user, new Customer(), 'budget_customer', $result);
|
||||
$this->assertVote($user, new Customer(), 'delete_customer', $result);
|
||||
$this->assertVote($user, new \stdClass(), 'view', $result);
|
||||
$this->assertVote($user, null, 'edit', $result);
|
||||
$this->assertVote($user, $user, 'delete', $result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,14 +22,6 @@ use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
*/
|
||||
class ProjectVoterTest extends AbstractVoterTest
|
||||
{
|
||||
/**
|
||||
* @dataProvider getTestData
|
||||
*/
|
||||
public function testVote(User $user, $subject, $attribute, $result)
|
||||
{
|
||||
$this->assertVote($user, $subject, $attribute, $result);
|
||||
}
|
||||
|
||||
protected function assertVote(User $user, $subject, $attribute, $result)
|
||||
{
|
||||
$token = new UsernamePasswordToken($user, 'foo', 'bar', $user->getRoles());
|
||||
@@ -39,53 +31,62 @@ class ProjectVoterTest extends AbstractVoterTest
|
||||
$subject->setCustomer(new Customer());
|
||||
}
|
||||
|
||||
$this->assertEquals($result, $sut->vote($token, $subject, [$attribute]));
|
||||
$actual = $sut->vote($token, $subject, [$attribute]);
|
||||
$this->assertEquals($result, $actual, sprintf('Failed voting "%s" for User with roles %s.', $attribute, implode(', ', $user->getRoles())));
|
||||
}
|
||||
|
||||
public function getTestData()
|
||||
public function testVote()
|
||||
{
|
||||
$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);
|
||||
$userNoRole = $this->getUser(0, 'foo');
|
||||
$userStandard = $this->getUser(1, User::ROLE_USER);
|
||||
$userTeamlead = $this->getUser(2, User::ROLE_TEAMLEAD);
|
||||
$userAdmin = $this->getUser(3, User::ROLE_ADMIN);
|
||||
$userSuperAdmin = $this->getUser(4, User::ROLE_SUPER_ADMIN);
|
||||
|
||||
$result = VoterInterface::ACCESS_GRANTED;
|
||||
foreach ([$user3, $user4] as $user) {
|
||||
yield [$user, new Project(), 'view', $result];
|
||||
yield [$user, new Project(), 'edit', $result];
|
||||
yield [$user, new Project(), 'budget', $result];
|
||||
yield [$user, new Project(), 'delete', $result];
|
||||
foreach ([$userAdmin, $userSuperAdmin] as $user) {
|
||||
$this->assertVote($user, new Project(), 'view', $result);
|
||||
$this->assertVote($user, new Project(), 'edit', $result);
|
||||
$this->assertVote($user, new Project(), 'budget', $result);
|
||||
$this->assertVote($user, new Project(), 'delete', $result);
|
||||
}
|
||||
|
||||
foreach ([$user2] as $user) {
|
||||
yield [$user, new Project(), 'view', $result];
|
||||
$team = new Team();
|
||||
$team->setTeamLead($userTeamlead);
|
||||
foreach ([$userTeamlead] as $user) {
|
||||
$project = new Project();
|
||||
$team->addProject($project);
|
||||
$this->assertVote($user, $project, 'view', $result);
|
||||
$team->removeProject($project);
|
||||
}
|
||||
|
||||
$userTeamlead = $this->getUser(2, User::ROLE_TEAMLEAD);
|
||||
|
||||
$result = VoterInterface::ACCESS_DENIED;
|
||||
foreach ([$user0, $user1] as $user) {
|
||||
yield [$user, new Project(), 'view', $result];
|
||||
yield [$user, new Project(), 'edit', $result];
|
||||
yield [$user, new Project(), 'budget', $result];
|
||||
yield [$user, new Project(), 'delete', $result];
|
||||
foreach ([$userNoRole, $userStandard] as $user) {
|
||||
$this->assertVote($user, new Project(), 'view', $result);
|
||||
$this->assertVote($user, new Project(), 'edit', $result);
|
||||
$this->assertVote($user, new Project(), 'budget', $result);
|
||||
$this->assertVote($user, new Project(), 'delete', $result);
|
||||
}
|
||||
|
||||
foreach ([$user2] as $user) {
|
||||
yield [$user, new Project(), 'edit', $result];
|
||||
yield [$user, new Project(), 'budget', $result];
|
||||
yield [$user, new Project(), 'delete', $result];
|
||||
foreach ([$userTeamlead] as $user) {
|
||||
$this->assertVote($user, new Project(), 'view', $result);
|
||||
$this->assertVote($user, new Project(), 'edit', $result);
|
||||
$this->assertVote($user, new Project(), 'budget', $result);
|
||||
$this->assertVote($user, new Project(), 'delete', $result);
|
||||
}
|
||||
|
||||
$result = VoterInterface::ACCESS_ABSTAIN;
|
||||
foreach ([$user0, $user1, $user2] as $user) {
|
||||
yield [$user, new Project(), 'create_project', $result];
|
||||
yield [$user, new Project(), 'view_project', $result];
|
||||
yield [$user, new Project(), 'edit_project', $result];
|
||||
yield [$user, new Project(), 'budget_project', $result];
|
||||
yield [$user, new Project(), 'delete_project', $result];
|
||||
yield [$user, new \stdClass(), 'view', $result];
|
||||
yield [$user, null, 'edit', $result];
|
||||
yield [$user, $user, 'delete', $result];
|
||||
foreach ([$userNoRole, $userStandard, $userTeamlead] as $user) {
|
||||
$this->assertVote($user, new Project(), 'create_project', $result);
|
||||
$this->assertVote($user, new Project(), 'view_project', $result);
|
||||
$this->assertVote($user, new Project(), 'edit_project', $result);
|
||||
$this->assertVote($user, new Project(), 'budget_project', $result);
|
||||
$this->assertVote($user, new Project(), 'delete_project', $result);
|
||||
$this->assertVote($user, new \stdClass(), 'view', $result);
|
||||
$this->assertVote($user, null, 'edit', $result);
|
||||
$this->assertVote($user, $user, 'delete', $result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,16 +28,17 @@ class RolePermissionVoterTest extends AbstractVoterTest
|
||||
$token = new UsernamePasswordToken($user, 'foo', 'bar', $user->getRoles());
|
||||
$sut = $this->getVoter(RolePermissionVoter::class, $user);
|
||||
|
||||
$this->assertEquals($result, $sut->vote($token, $subject, [$attribute]));
|
||||
$actual = $sut->vote($token, $subject, [$attribute]);
|
||||
$this->assertEquals($result, $actual, sprintf('Failed voting "%s" for User with roles %s.', $attribute, implode(', ', $user->getRoles())));
|
||||
}
|
||||
|
||||
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);
|
||||
$userNoRole = $this->getUser(0, 'foo');
|
||||
$userStandard = $this->getUser(1, User::ROLE_USER);
|
||||
$userTeamlead = $this->getUser(2, User::ROLE_TEAMLEAD);
|
||||
$userAdmin = $this->getUser(3, User::ROLE_ADMIN);
|
||||
$userSuperAdmin = $this->getUser(4, User::ROLE_SUPER_ADMIN);
|
||||
|
||||
$invoice = [
|
||||
'manage_invoice_template' => null,
|
||||
@@ -70,7 +71,7 @@ class RolePermissionVoterTest extends AbstractVoterTest
|
||||
$result = VoterInterface::ACCESS_GRANTED;
|
||||
|
||||
$entries = array_merge($timesheet);
|
||||
foreach ([$user1, $user2, $user3, $user4] as $user) {
|
||||
foreach ([$userNoRole, $userStandard, $userTeamlead, $userAdmin, $userSuperAdmin] as $user) {
|
||||
foreach ($entries as $permission => $entity) {
|
||||
yield [$user, $entity, $permission, $result];
|
||||
yield [$user, null, $permission, $result];
|
||||
@@ -78,7 +79,7 @@ class RolePermissionVoterTest extends AbstractVoterTest
|
||||
}
|
||||
|
||||
$entriesAdmin = array_merge($others, $timesheetOther, $invoice, $timesheet);
|
||||
foreach ([$user3, $user4] as $user) {
|
||||
foreach ([$userAdmin, $userSuperAdmin] as $user) {
|
||||
foreach ($entriesAdmin as $permission => $entity) {
|
||||
yield [$user, $entity, $permission, $result];
|
||||
yield [$user, null, $permission, $result];
|
||||
@@ -87,35 +88,30 @@ class RolePermissionVoterTest extends AbstractVoterTest
|
||||
|
||||
$entriesSuperAdmin = array_merge($users);
|
||||
foreach ($entriesSuperAdmin as $permission => $entity) {
|
||||
yield [$user4, $entity, $permission, $result];
|
||||
yield [$user4, null, $permission, $result];
|
||||
yield [$userSuperAdmin, $entity, $permission, $result];
|
||||
yield [$userSuperAdmin, null, $permission, $result];
|
||||
}
|
||||
|
||||
// ================== DENIED ==================
|
||||
// this test might fail in the future due to the role permissions
|
||||
$result = VoterInterface::ACCESS_DENIED;
|
||||
|
||||
foreach ([$user0, $user1, $user2] as $user) {
|
||||
foreach ([$userNoRole, $userStandard, $userTeamlead] as $user) {
|
||||
foreach ($others as $permission => $entity) {
|
||||
yield [$user, $entity, $permission, $result];
|
||||
}
|
||||
}
|
||||
foreach ([$user0, $user1] as $user) {
|
||||
foreach ([$userNoRole, $userStandard] as $user) {
|
||||
foreach (['view_activity' => null] as $permission => $entity) {
|
||||
yield [$user, $entity, $permission, $result];
|
||||
}
|
||||
}
|
||||
foreach ([$user0, $user1] as $user) {
|
||||
foreach ([$userNoRole, $userStandard] as $user) {
|
||||
foreach ($invoice as $permission => $entity) {
|
||||
yield [$user, $entity, $permission, $result];
|
||||
}
|
||||
}
|
||||
foreach ([$user0] as $user) {
|
||||
foreach ($timesheet as $permission => $entity) {
|
||||
yield [$user, $entity, $permission, $result];
|
||||
}
|
||||
}
|
||||
foreach ([$user0, $user1] as $user) {
|
||||
foreach ([$userNoRole, $userStandard] as $user) {
|
||||
foreach ($timesheetOther as $permission => $entity) {
|
||||
yield [$user, $entity, $permission, $result];
|
||||
}
|
||||
@@ -123,7 +119,7 @@ class RolePermissionVoterTest extends AbstractVoterTest
|
||||
|
||||
// ================== ABSTAIN ==================
|
||||
$result = VoterInterface::ACCESS_ABSTAIN;
|
||||
foreach ([$user3, $user4] as $user) {
|
||||
foreach ([$userAdmin, $userSuperAdmin] as $user) {
|
||||
yield [$user, new Activity(), 'view', $result];
|
||||
yield [$user, new Activity(), 'edit', $result];
|
||||
yield [$user, new Activity(), 'delete', $result];
|
||||
|
||||
@@ -10,7 +10,6 @@ parameters:
|
||||
- '#Access to an undefined property Faker\\Generator::\$catchPhrase.#'
|
||||
- '#Access to an undefined property Faker\\Generator::\$bs.#'
|
||||
- '#Call to static method PHPUnit\\Framework\\Assert::assertSame\(\) with App\\Entity\\[a-zA-Z0-9]+ and null will always evaluate to false.#'
|
||||
- '#Method *::getUserByName\(\) should return App\\Entity\\User\|null but returns object|null.#'
|
||||
excludes_analyse:
|
||||
- %rootDir%/../../../tests/Ldap/LdapDriverTest.php
|
||||
inferPrivatePropertyTypeFromConstructor: true
|
||||
Reference in New Issue
Block a user