added team permissions for activities (#1872)
This commit is contained in:
@@ -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':
|
||||
|
||||
@@ -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']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user