added team permissions for activities (#1872)

This commit is contained in:
Kevin Papst
2020-08-08 18:50:04 +02:00
committed by GitHub
parent dc162bf385
commit 0914ebf737
84 changed files with 4300 additions and 3279 deletions

View File

@@ -337,6 +337,7 @@ abstract class APIControllerBaseTest extends ControllerBaseTest
'users' => ['result' => 'array', 'type' => 'User'],
'customers' => ['result' => 'array', 'type' => '@Customer'],
'projects' => ['result' => 'array', 'type' => '@Project'],
'activities' => ['result' => 'array', 'type' => '@Activity'],
];
// if a customer is embedded in other objects
@@ -462,6 +463,7 @@ abstract class APIControllerBaseTest extends ControllerBaseTest
'color' => '@string',
'metaFields' => ['result' => 'array', 'type' => 'ProjectMeta'],
'parentTitle' => '@string',
'teams' => ['result' => 'array', 'type' => 'Team'],
];
// if a activity is explicitly loaded
@@ -477,6 +479,7 @@ abstract class APIControllerBaseTest extends ControllerBaseTest
'comment' => '@string',
'budget' => 'float',
'timeBudget' => 'int',
'teams' => ['result' => 'array', 'type' => 'Team'],
];
case 'TimesheetEntity':

View File

@@ -9,8 +9,6 @@
namespace App\Tests\API;
use App\Entity\Customer;
use App\Entity\Project;
use App\Entity\User;
use App\Tests\DataFixtures\TeamFixtures;
use Symfony\Component\HttpFoundation\Response;
@@ -371,21 +369,6 @@ class TeamControllerTest extends APIControllerBaseTest
self::assertEquals(Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode());
$json = json_decode($client->getResponse()->getContent(), true);
self::assertEquals('Team has already access to customer', $json['message']);
$customer = new Customer();
$customer->setName('foooo');
$customer->setVisible(false);
$customer->setCountry('DE');
$customer->setTimezone('Europe/Berlin');
$em = $this->getEntityManager();
$em->persist($customer);
$em->flush();
// cannot add invisible customer
$this->request($client, '/api/teams/' . $result['id'] . '/customers/' . $customer->getId(), 'POST');
self::assertEquals(Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode());
$json = json_decode($client->getResponse()->getContent(), true);
self::assertEquals('Cannot grant access to an invisible customer', $json['message']);
}
public function testDeleteCustomerAction()
@@ -503,27 +486,6 @@ class TeamControllerTest extends APIControllerBaseTest
self::assertEquals(Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode());
$json = json_decode($client->getResponse()->getContent(), true);
self::assertEquals('Team has already access to project', $json['message']);
$customer = new Customer();
$customer->setName('foooo');
$customer->setVisible(false);
$customer->setCountry('DE');
$customer->setTimezone('Europe/Berlin');
$project = new Project();
$project->setName('foooo');
$project->setVisible(false);
$project->setCustomer($customer);
$em = $this->getEntityManager();
$em->persist($customer);
$em->persist($project);
$em->flush();
// cannot add invisible project
$this->request($client, '/api/teams/' . $result['id'] . '/projects/' . $project->getId(), 'POST');
self::assertEquals(Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode());
$json = json_decode($client->getResponse()->getContent(), true);
self::assertEquals('Cannot grant access to an invisible project', $json['message']);
}
public function testDeleteProjectAction()
@@ -584,4 +546,121 @@ class TeamControllerTest extends APIControllerBaseTest
$json = json_decode($client->getResponse()->getContent(), true);
self::assertEquals('Project is not assigned to the team', $json['message']);
}
public function testPostActivityAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
$data = [
'name' => 'foo',
'teamlead' => 1,
];
$this->request($client, '/api/teams', 'POST', [], json_encode($data));
$this->assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
self::assertCount(0, $result['activities']);
$this->request($client, '/api/teams/' . $result['id'] . '/activities/1', 'POST');
$this->assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
$this->assertIsArray($result);
self::assertApiResponseTypeStructure('TeamEntity', $result);
self::assertCount(1, $result['activities']);
self::assertEquals(1, $result['activities'][0]['id']);
}
public function testPostActivityActionErrors()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
$data = [
'name' => 'foo',
'teamlead' => 1,
'users' => [2]
];
$this->request($client, '/api/teams', 'POST', [], json_encode($data));
$this->assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
// team not found
$this->request($client, '/api/teams/999/activities/999', 'POST');
self::assertEquals(Response::HTTP_NOT_FOUND, $client->getResponse()->getStatusCode());
$json = json_decode($client->getResponse()->getContent(), true);
self::assertEquals('Team not found', $json['message']);
// activity not found
$this->request($client, '/api/teams/' . $result['id'] . '/activities/999', 'POST');
self::assertEquals(Response::HTTP_NOT_FOUND, $client->getResponse()->getStatusCode());
$json = json_decode($client->getResponse()->getContent(), true);
self::assertEquals('Activity not found', $json['message']);
// add activity
$this->request($client, '/api/teams/' . $result['id'] . '/activities/1', 'POST');
$this->assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
self::assertCount(1, $result['activities']);
// cannot add existing activity
$this->request($client, '/api/teams/' . $result['id'] . '/activities/1', 'POST');
self::assertEquals(Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode());
$json = json_decode($client->getResponse()->getContent(), true);
self::assertEquals('Team has already access to activity', $json['message']);
}
public function testDeleteActivityAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
$data = [
'name' => 'foo',
'teamlead' => 1,
'users' => [2, 4, 5]
];
$this->request($client, '/api/teams', 'POST', [], json_encode($data));
$this->assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
self::assertCount(0, $result['activities']);
// add activity
$this->request($client, '/api/teams/' . $result['id'] . '/activities/1', 'POST');
$this->assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
self::assertCount(1, $result['activities']);
$this->request($client, '/api/teams/' . $result['id'] . '/activities/1', 'DELETE');
$this->assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
$this->assertIsArray($result);
self::assertApiResponseTypeStructure('TeamEntity', $result);
self::assertCount(0, $result['activities']);
}
public function testDeleteActivityActionErrors()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
$data = [
'name' => 'foo',
'teamlead' => 1,
'users' => [2, 4, 5]
];
$this->request($client, '/api/teams', 'POST', [], json_encode($data));
$this->assertTrue($client->getResponse()->isSuccessful());
$result = json_decode($client->getResponse()->getContent(), true);
// team not found
$this->request($client, '/api/teams/999/activities/999', 'DELETE');
self::assertEquals(Response::HTTP_NOT_FOUND, $client->getResponse()->getStatusCode());
$json = json_decode($client->getResponse()->getContent(), true);
self::assertEquals('Team not found', $json['message']);
// activity not found
$this->request($client, '/api/teams/' . $result['id'] . '/activities/999', 'DELETE');
self::assertEquals(Response::HTTP_NOT_FOUND, $client->getResponse()->getStatusCode());
$json = json_decode($client->getResponse()->getContent(), true);
self::assertEquals('Activity not found', $json['message']);
// cannot remove activity
$this->request($client, '/api/teams/' . $result['id'] . '/activities/1', 'DELETE');
self::assertEquals(Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode());
$json = json_decode($client->getResponse()->getContent(), true);
self::assertEquals('Activity is not assigned to the team', $json['message']);
}
}

View File

@@ -16,9 +16,11 @@ use App\Entity\Timesheet;
use App\Entity\User;
use App\Tests\DataFixtures\ActivityFixtures;
use App\Tests\DataFixtures\ProjectFixtures;
use App\Tests\DataFixtures\TeamFixtures;
use App\Tests\DataFixtures\TimesheetFixtures;
use App\Tests\Mocks\ActivityTestMetaFieldSubscriberMock;
use Doctrine\ORM\EntityManager;
use Symfony\Component\DomCrawler\Field\ChoiceFormField;
/**
* @group integration
@@ -275,6 +277,61 @@ class ActivityControllerTest extends ControllerBaseTest
$this->assertEquals('', $editForm->get('activity_edit_form[project]')->getValue());
}
public function testTeamPermissionAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
$em = $this->getEntityManager();
/** @var Activity $activity */
$activity = $em->getRepository(Activity::class)->find(1);
self::assertEquals(0, $activity->getTeams()->count());
$fixture = new TeamFixtures();
$fixture->setAmount(2);
$fixture->setAddCustomer(false);
$this->importFixture($fixture);
$this->assertAccessIsGranted($client, '/admin/activity/1/permissions');
$form = $client->getCrawler()->filter('form[name=activity_team_permission_form]')->form();
/** @var ChoiceFormField $team1 */
$team1 = $form->get('activity_team_permission_form[teams][0]');
$team1->tick();
/** @var ChoiceFormField $team2 */
$team2 = $form->get('activity_team_permission_form[teams][1]');
$team2->tick();
$client->submit($form);
$this->assertIsRedirect($client, $this->createUrl('/admin/activity/'));
$client->followRedirect();
$this->assertHasDataTable($client);
/** @var Activity $activity */
$activity = $em->getRepository(Activity::class)->find(1);
self::assertEquals(2, $activity->getTeams()->count());
}
public function testCreateDefaultTeamAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
$this->assertAccessIsGranted($client, '/admin/activity/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(null, true));
$this->request($client, '/admin/activity/1/create_team');
$this->assertIsRedirect($client, $this->createUrl('/admin/activity/1/details'));
$client->followRedirect();
$node = $client->getCrawler()->filter('div.box#team_listing_box .box-title');
self::assertStringContainsString('Only visible to the following teams and all admins.', $node->text(null, true));
$node = $client->getCrawler()->filter('div.box#team_listing_box .box-body table tbody tr');
self::assertEquals(1, $node->count());
// creating the default team a second time fails, as the name already exists
$this->request($client, '/admin/activity/1/create_team');
$this->assertIsRedirect($client, $this->createUrl('/admin/activity/1/details'));
$client->followRedirect();
$this->assertHasFlashError($client, 'Changes could not be saved: Team already existing');
}
public function testDeleteAction()
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);

View File

@@ -224,6 +224,12 @@ class CustomerControllerTest extends ControllerBaseTest
self::assertStringContainsString('Only visible to the following teams and all admins.', $node->text(null, true));
$node = $client->getCrawler()->filter('div.box#team_listing_box .box-body table tbody tr');
self::assertEquals(1, $node->count());
// creating the default team a second time fails, as the name already exists
$this->request($client, '/admin/customer/1/create_team');
$this->assertIsRedirect($client, $this->createUrl('/admin/customer/1/details'));
$client->followRedirect();
$this->assertHasFlashError($client, 'Changes could not be saved: Team already existing');
}
public function testProjectsAction()

View File

@@ -33,7 +33,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', 113);
$this->assertDataTableRowCount($client, 'datatable_user_admin_permissions', 119);
$this->assertPageActions($client, [
'back' => $this->createUrl('/admin/user/'),
'roles modal-ajax-form' => $this->createUrl('/admin/permissions/roles/create'),

View File

@@ -302,6 +302,12 @@ class ProjectControllerTest extends ControllerBaseTest
self::assertStringContainsString('Only visible to the following teams and all admins.', $node->text(null, true));
$node = $client->getCrawler()->filter('div.box#team_listing_box .box-body table tbody tr');
self::assertEquals(1, $node->count());
// creating the default team a second time fails, as the name already exists
$this->request($client, '/admin/project/1/create_team');
$this->assertIsRedirect($client, $this->createUrl('/admin/project/1/details'));
$client->followRedirect();
$this->assertHasFlashError($client, 'Changes could not be saved: Team already existing');
}
public function testActivitiesAction()

View File

@@ -12,6 +12,7 @@ namespace App\Tests\Entity;
use App\Entity\Activity;
use App\Entity\ActivityMeta;
use App\Entity\Project;
use App\Entity\Team;
use App\Export\Spreadsheet\ColumnDefinition;
use App\Export\Spreadsheet\Extractor\AnnotationExtractor;
use Doctrine\Common\Annotations\AnnotationReader;
@@ -38,6 +39,7 @@ class ActivityTest extends TestCase
$this->assertInstanceOf(Collection::class, $sut->getMetaFields());
$this->assertEquals(0, $sut->getMetaFields()->count());
$this->assertNull($sut->getMetaField('foo'));
$this->assertInstanceOf(Collection::class, $sut->getTeams());
}
public function testSetterAndGetter()
@@ -94,6 +96,29 @@ class ActivityTest extends TestCase
self::assertCount(2, $sut->getVisibleMetaFields());
}
public function testTeams()
{
$sut = new Activity();
$team = new Team();
self::assertEmpty($sut->getTeams());
self::assertEmpty($team->getActivities());
$sut->addTeam($team);
self::assertCount(1, $sut->getTeams());
self::assertCount(1, $team->getActivities());
self::assertSame($team, $sut->getTeams()[0]);
self::assertSame($sut, $team->getActivities()[0]);
// test remove unknown team doesn't do anything
$sut->removeTeam(new Team());
self::assertCount(1, $sut->getTeams());
self::assertCount(1, $team->getActivities());
$sut->removeTeam($team);
self::assertCount(0, $sut->getTeams());
self::assertCount(0, $team->getActivities());
}
public function testExportAnnotations()
{
$sut = new AnnotationExtractor(new AnnotationReader());

View File

@@ -143,6 +143,11 @@ class CustomerTest extends TestCase
self::assertSame($team, $sut->getTeams()[0]);
self::assertSame($sut, $team->getCustomers()[0]);
// test remove unknown team doesn't do anything
$sut->removeTeam(new Team());
self::assertCount(1, $sut->getTeams());
self::assertCount(1, $team->getCustomers());
$sut->removeTeam(new Team());
$sut->removeTeam($team);
self::assertCount(0, $sut->getTeams());

View File

@@ -132,6 +132,11 @@ class ProjectTest extends TestCase
self::assertSame($team, $sut->getTeams()[0]);
self::assertSame($sut, $team->getProjects()[0]);
// test remove unknown team doesn't do anything
$sut->removeTeam(new Team());
self::assertCount(1, $sut->getTeams());
self::assertCount(1, $team->getProjects());
$sut->removeTeam($team);
self::assertCount(0, $sut->getTeams());
self::assertCount(0, $team->getProjects());

View File

@@ -9,6 +9,7 @@
namespace App\Tests\Entity;
use App\Entity\Activity;
use App\Entity\Customer;
use App\Entity\Project;
use App\Entity\Team;
@@ -33,6 +34,8 @@ class TeamTest extends TestCase
self::assertEquals(0, $sut->getCustomers()->count());
self::assertInstanceOf(Collection::class, $sut->getProjects());
self::assertEquals(0, $sut->getProjects()->count());
self::assertInstanceOf(Collection::class, $sut->getActivities());
self::assertEquals(0, $sut->getActivities()->count());
}
public function testSetterAndGetter()
@@ -90,6 +93,26 @@ class TeamTest extends TestCase
self::assertEquals(0, $sut->getProjects()->count());
}
public function testActivities()
{
$activity = new Activity();
$activity->setName('foo');
self::assertEmpty($activity->getTeams());
$sut = new Team();
self::assertFalse($sut->hasActivity($activity));
$sut->addActivity($activity);
self::assertEquals(1, $sut->getActivities()->count());
self::assertTrue($sut->hasActivity($activity));
$actual = $sut->getActivities()[0];
self::assertSame($actual, $activity);
self::assertSame($sut, $activity->getTeams()[0]);
$sut->removeActivity(new Activity());
self::assertEquals(1, $sut->getActivities()->count());
$sut->removeActivity($activity);
self::assertEquals(0, $sut->getActivities()->count());
}
public function testUsers()
{
$user = new User();

View File

@@ -110,6 +110,15 @@ class ActivityVoterTest extends AbstractVoterTest
$this->assertVote($user, $activity, 'edit', VoterInterface::ACCESS_GRANTED);
$activity = new Activity();
$project = new Project();
$customer = new Customer();
$project->setCustomer($customer);
$activity->setProject($project);
$activity->addTeam($team);
$this->assertVote($user, $activity, 'edit', VoterInterface::ACCESS_GRANTED);
$activity = new Activity();
$this->assertVote($user, $activity, 'edit', VoterInterface::ACCESS_DENIED);
@@ -144,5 +153,19 @@ class ActivityVoterTest extends AbstractVoterTest
$activity->setProject($project);
$this->assertVote($user, $activity, 'edit', VoterInterface::ACCESS_GRANTED);
$activity = new Activity();
$team = new Team();
$user = new User();
$user->addRole(User::ROLE_USER);
$team->addUser($user);
$project = new Project();
$customer = new Customer();
$activity->addTeam($team);
$project->setCustomer($customer);
$activity->setProject($project);
$this->assertVote($user, $activity, 'edit', VoterInterface::ACCESS_GRANTED);
}
}