Skip to content

Commit

Permalink
fix: Force requester and assignee to be part of the lists
Browse files Browse the repository at this point in the history
  • Loading branch information
marien-probesys committed Mar 14, 2024
1 parent d02a74b commit 15faa7e
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 92 deletions.
32 changes: 9 additions & 23 deletions src/Controller/Organizations/TicketsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use App\Service\ActorsLister;
use App\TicketActivity\MessageEvent;
use App\TicketActivity\TicketEvent;
use App\Utils\ArrayHelper;
use App\Utils\ConstraintErrorsFormatter;
use App\Utils\Pagination;
use App\Utils\Time;
Expand Down Expand Up @@ -228,7 +229,10 @@ public function create(
]);
}

$requester = $userRepository->findOneBy(['uid' => $requesterUid]);
$requester = ArrayHelper::find($allUsers, function ($user) use ($requesterUid): bool {
return $user->getUid() === $requesterUid;
});

if (!$requester) {
return $this->renderBadRequest('organizations/tickets/new.html.twig', [
'organization' => $organization,
Expand All @@ -249,29 +253,11 @@ public function create(
]);
}

$assignee = null;
if ($assigneeUid) {
$assignee = $userRepository->findOneBy(['uid' => $assigneeUid]);
if (!$assignee) {
return $this->renderBadRequest('organizations/tickets/new.html.twig', [
'organization' => $organization,
'title' => $title,
'message' => $messageContent,
'type' => $type,
'requesterUid' => $requesterUid,
'assigneeUid' => $assigneeUid,
'isResolved' => $isResolved,
'urgency' => $urgency,
'impact' => $impact,
'priority' => $priority,
'allUsers' => $allUsers,
'agents' => $agents,
'errors' => [
'assignee' => $translator->trans('ticket.assignee.invalid', [], 'errors'),
],
]);
}
} else {
$assignee = null;
$assignee = ArrayHelper::find($agents, function ($agent) use ($assigneeUid): bool {
return $agent->getUid() === $assigneeUid;
});
}

$ticket = new Ticket();
Expand Down
25 changes: 9 additions & 16 deletions src/Controller/Tickets/ActorsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use App\Repository\UserRepository;
use App\Service\ActorsLister;
use App\TicketActivity\TicketEvent;
use App\Utils\ArrayHelper;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
Expand Down Expand Up @@ -95,7 +96,10 @@ public function update(
]);
}

$requester = $userRepository->findOneBy(['uid' => $requesterUid]);
$requester = ArrayHelper::find($allUsers, function ($user) use ($requesterUid): bool {
return $user->getUid() === $requesterUid;
});

if (!$requester) {
return $this->renderBadRequest('tickets/actors/edit.html.twig', [
'ticket' => $ticket,
Expand All @@ -109,22 +113,11 @@ public function update(
]);
}

$assignee = null;
if ($assigneeUid) {
$assignee = $userRepository->findOneBy(['uid' => $assigneeUid]);
if (!$assignee) {
return $this->renderBadRequest('tickets/actors/edit.html.twig', [
'ticket' => $ticket,
'requesterUid' => $requesterUid,
'assigneeUid' => $assigneeUid,
'allUsers' => $allUsers,
'agents' => $agents,
'errors' => [
'assignee' => $translator->trans('ticket.assignee.invalid', [], 'errors'),
],
]);
}
} else {
$assignee = null;
$assignee = ArrayHelper::find($agents, function ($agent) use ($assigneeUid): bool {
return $agent->getUid() === $assigneeUid;
});
}

$previousAssignee = $ticket->getAssignee();
Expand Down
13 changes: 9 additions & 4 deletions tests/AuthorizationHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,14 @@ public function grantAdmin(User $user, array $permissions): void

/**
* @param string[] $permissions
* @param 'user'|'agent' $type
*/
public function grantOrga(User $user, array $permissions, ?Organization $organization = null): void
{
public function grantOrga(
User $user,
array $permissions,
?Organization $organization = null,
string $type = 'agent',
): void {
if (empty($permissions)) {
return;
}
Expand All @@ -72,12 +77,12 @@ public function grantOrga(User $user, array $permissions, ?Organization $organiz
/** @var \App\Repository\AuthorizationRepository $authorizationRepo */
$authorizationRepo = $entityManager->getRepository(Authorization::class);

$permissions = Role::sanitizePermissions('agent', $permissions);
$permissions = Role::sanitizePermissions($type, $permissions);

$role = new Role();
$role->setName(Random::hex(10));
$role->setDescription('The role description');
$role->setType('agent');
$role->setType($type);
$role->setPermissions($permissions);

$roleRepo->save($role);
Expand Down
110 changes: 77 additions & 33 deletions tests/Controller/Organizations/TicketsControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ public function testPostCreateCreatesATicketAndRedirects(): void
list(
$user,
$requester,
) = UserFactory::createMany(3);
) = UserFactory::createMany(2);
$client->loginUser($user->object());
$organization = OrganizationFactory::createOne();
$this->grantOrga($user->object(), [
Expand All @@ -205,6 +205,9 @@ public function testPostCreateCreatesATicketAndRedirects(): void
'orga:update:tickets:actors',
'orga:update:tickets:priority',
], $organization->object());
$this->grantOrga($requester->object(), [
'orga:create:tickets',
], $organization->object());
$title = 'My ticket';
$messageContent = 'My message';

Expand Down Expand Up @@ -351,15 +354,14 @@ public function testPostCreateAttachesDocumentsToMessage(): void
$this->assertSame($message->getUid(), $messageDocument2->getMessage()->getUid());
}

public function testPostCreateCanAssignsAUser(): void
public function testPostCreateCanAssignAUser(): void
{
$now = new \DateTimeImmutable('2022-11-02');
$client = static::createClient();
list(
$user,
$requester,
$assignee
) = UserFactory::createMany(3);
) = UserFactory::createMany(2);
$client->loginUser($user->object());
$organization = OrganizationFactory::createOne();
$this->grantOrga($user->object(), [
Expand All @@ -369,6 +371,9 @@ public function testPostCreateCanAssignsAUser(): void
'orga:update:tickets:actors',
'orga:update:tickets:priority',
], $organization->object());
$this->grantOrga($assignee->object(), [
'orga:create:tickets',
], $organization->object());
$title = 'My ticket';
$messageContent = 'My message';

Expand All @@ -378,7 +383,7 @@ public function testPostCreateCanAssignsAUser(): void
$client->request('POST', "/organizations/{$organization->getUid()}/tickets/new", [
'_csrf_token' => $this->generateCsrfToken($client, 'create organization ticket'),
'title' => $title,
'requesterUid' => $requester->getUid(),
'requesterUid' => $user->getUid(),
'assigneeUid' => $assignee->getUid(),
'type' => 'incident',
'urgency' => 'high',
Expand All @@ -399,10 +404,7 @@ public function testPostCreateCanAssignsAUser(): void
public function testPostCreateCanMarkATicketAsResolved(): void
{
$client = static::createClient();
list(
$user,
$requester
) = UserFactory::createMany(2);
$user = UserFactory::createOne();
$client->loginUser($user->object());
$organization = OrganizationFactory::createOne();
$this->grantOrga($user->object(), [
Expand All @@ -418,7 +420,7 @@ public function testPostCreateCanMarkATicketAsResolved(): void
$client->request('POST', "/organizations/{$organization->getUid()}/tickets/new", [
'_csrf_token' => $this->generateCsrfToken($client, 'create organization ticket'),
'title' => $title,
'requesterUid' => $requester->getUid(),
'requesterUid' => $user->getUid(),
'message' => $messageContent,
'isResolved' => true,
]);
Expand Down Expand Up @@ -472,12 +474,14 @@ public function testPostCreateCanCreateATicketWithMinimalPermissions(): void
$this->assertSame('webapp', $message->getVia());
}

public function testPostCreateFailsIfTitleIsEmpty(): void
public function testPostCreateDoesNotAssignIfUserIsNotAgent(): void
{
$now = new \DateTimeImmutable('2022-11-02');
Time::freeze($now);
$client = static::createClient();
$user = UserFactory::createOne();
list(
$user,
$assignee
) = UserFactory::createMany(2);
$client->loginUser($user->object());
$organization = OrganizationFactory::createOne();
$this->grantOrga($user->object(), [
Expand All @@ -487,25 +491,66 @@ public function testPostCreateFailsIfTitleIsEmpty(): void
'orga:update:tickets:actors',
'orga:update:tickets:priority',
], $organization->object());
$title = '';
$this->grantOrga($assignee->object(), [
'orga:create:tickets',
], $organization->object(), 'user');
$title = 'My ticket';
$messageContent = 'My message';

$this->assertSame(0, TicketFactory::count());

$client->request('POST', "/organizations/{$organization->getUid()}/tickets/new", [
'_csrf_token' => $this->generateCsrfToken($client, 'create organization ticket'),
'title' => $title,
'requesterUid' => $user->getUid(),
'assigneeUid' => $assignee->getUid(),
'type' => 'incident',
'urgency' => 'high',
'impact' => 'high',
'priority' => 'high',
'message' => $messageContent,
]);

$this->assertSame(1, TicketFactory::count());
$this->assertSame(1, MessageFactory::count());

$ticket = TicketFactory::first();
$this->assertResponseRedirects("/tickets/{$ticket->getUid()}", 302);
$this->assertSame('new', $ticket->getStatus());
$this->assertNull($ticket->getAssignee());
}

public function testPostCreateFailsIfRequesterIsNotInOrganization(): void
{
$now = new \DateTimeImmutable('2022-11-02');
$client = static::createClient();
list(
$user,
$requester,
) = UserFactory::createMany(2);
$client->loginUser($user->object());
$organization = OrganizationFactory::createOne();
$this->grantOrga($user->object(), [
'orga:create:tickets',
'orga:update:tickets:status',
'orga:update:tickets:type',
'orga:update:tickets:actors',
'orga:update:tickets:priority',
], $organization->object());
$title = 'My ticket';
$messageContent = 'My message';

$client->request('POST', "/organizations/{$organization->getUid()}/tickets/new", [
'_csrf_token' => $this->generateCsrfToken($client, 'create organization ticket'),
'title' => $title,
'requesterUid' => $requester->getUid(),
'message' => $messageContent,
]);

Time::unfreeze();
$this->assertSame(0, TicketFactory::count());
$this->assertSame(0, MessageFactory::count());
$this->assertSelectorTextContains('#title-error', 'Enter a title');
$this->assertSelectorTextContains('#requester-error', 'Select a user from the list');
}

public function testPostCreateFailsIfTitleIsTooLong(): void
public function testPostCreateFailsIfTitleIsEmpty(): void
{
$now = new \DateTimeImmutable('2022-11-02');
Time::freeze($now);
Expand All @@ -520,7 +565,7 @@ public function testPostCreateFailsIfTitleIsTooLong(): void
'orga:update:tickets:actors',
'orga:update:tickets:priority',
], $organization->object());
$title = str_repeat('a', 256);
$title = '';
$messageContent = 'My message';

$this->assertSame(0, TicketFactory::count());
Expand All @@ -535,10 +580,10 @@ public function testPostCreateFailsIfTitleIsTooLong(): void
Time::unfreeze();
$this->assertSame(0, TicketFactory::count());
$this->assertSame(0, MessageFactory::count());
$this->assertSelectorTextContains('#title-error', 'Enter a title of less than 255 characters');
$this->assertSelectorTextContains('#title-error', 'Enter a title');
}

public function testPostCreateFailsIfMessageIsEmpty(): void
public function testPostCreateFailsIfTitleIsTooLong(): void
{
$now = new \DateTimeImmutable('2022-11-02');
Time::freeze($now);
Expand All @@ -553,8 +598,8 @@ public function testPostCreateFailsIfMessageIsEmpty(): void
'orga:update:tickets:actors',
'orga:update:tickets:priority',
], $organization->object());
$title = 'My ticket';
$messageContent = '';
$title = str_repeat('a', 256);
$messageContent = 'My message';

$this->assertSame(0, TicketFactory::count());

Expand All @@ -568,10 +613,10 @@ public function testPostCreateFailsIfMessageIsEmpty(): void
Time::unfreeze();
$this->assertSame(0, TicketFactory::count());
$this->assertSame(0, MessageFactory::count());
$this->assertSelectorTextContains('#message-error', 'Enter a message');
$this->assertSelectorTextContains('#title-error', 'Enter a title of less than 255 characters');
}

public function testPostCreateFailsIfRequesterIsInvalid(): void
public function testPostCreateFailsIfMessageIsEmpty(): void
{
$now = new \DateTimeImmutable('2022-11-02');
Time::freeze($now);
Expand All @@ -587,24 +632,24 @@ public function testPostCreateFailsIfRequesterIsInvalid(): void
'orga:update:tickets:priority',
], $organization->object());
$title = 'My ticket';
$messageContent = 'My message';
$messageContent = '';

$this->assertSame(0, TicketFactory::count());

$client->request('POST', "/organizations/{$organization->getUid()}/tickets/new", [
'_csrf_token' => $this->generateCsrfToken($client, 'create organization ticket'),
'title' => $title,
'requesterUid' => 'not an uid',
'requesterUid' => $user->getUid(),
'message' => $messageContent,
]);

Time::unfreeze();
$this->assertSame(0, TicketFactory::count());
$this->assertSame(0, MessageFactory::count());
$this->assertSelectorTextContains('#requester-error', 'Select a user from the list');
$this->assertSelectorTextContains('#message-error', 'Enter a message');
}

public function testPostCreateFailsIfAssigneeIsInvalid(): void
public function testPostCreateFailsIfRequesterIsInvalid(): void
{
$now = new \DateTimeImmutable('2022-11-02');
Time::freeze($now);
Expand All @@ -627,15 +672,14 @@ public function testPostCreateFailsIfAssigneeIsInvalid(): void
$client->request('POST', "/organizations/{$organization->getUid()}/tickets/new", [
'_csrf_token' => $this->generateCsrfToken($client, 'create organization ticket'),
'title' => $title,
'requesterUid' => $user->getUid(),
'assigneeUid' => 'not an uid',
'requesterUid' => 'not an uid',
'message' => $messageContent,
]);

Time::unfreeze();
$this->assertSame(0, TicketFactory::count());
$this->assertSame(0, MessageFactory::count());
$this->assertSelectorTextContains('#assignee-error', 'Select a user from the list');
$this->assertSelectorTextContains('#requester-error', 'Select a user from the list');
}

public function testPostCreateFailsIfCsrfTokenIsInvalid(): void
Expand Down
Loading

0 comments on commit 15faa7e

Please sign in to comment.