detail pages for customers and projects (#1371)

This commit is contained in:
Kevin Papst
2020-01-16 16:25:28 +01:00
committed by GitHub
parent 28c5357f11
commit 6a44dbfe83
131 changed files with 3055 additions and 1742 deletions

View File

@@ -54,7 +54,6 @@ abstract class APIControllerBaseTest extends ControllerBaseTest
default:
throw new \Exception(sprintf('Unknown role "%s"', $role));
break;
}
return $client;

View File

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

View File

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

View File

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

View File

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

View File

@@ -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'),

View File

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

View File

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

View File

@@ -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],
]
]

View File

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

View File

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

View File

@@ -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;
/**

View File

@@ -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;
/**

View File

@@ -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++) {

View File

@@ -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.

View File

@@ -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;
/**

View File

@@ -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;
/**

View File

@@ -0,0 +1,50 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Tests\Entity;
use App\Entity\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());
}
}

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

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

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

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

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

View File

@@ -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 &hellip;', $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__")
);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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