Skip to content

Commit

Permalink
Review fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
carlobeltrame committed Apr 7, 2024
1 parent 826e5ec commit 2fbe07b
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 51 deletions.
3 changes: 2 additions & 1 deletion api/src/State/CampCollaborationCreateProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ public function onBefore($data, Operation $operation, array $uriVariables = [],
$profileByInviteEmail = $this->profileRepository->findOneBy(['email' => $inviteEmail]);
if (null != $profileByInviteEmail) {
// Create a personal invitation, which the invited user will be able to see and
// accept / reject in the UI, even without receiving the invitation email
// accept / reject in the UI, even without receiving the invitation email.
// This is done by setting the user field instead of the inviteEmail field.
$data->user = $profileByInviteEmail->user;
$data->inviteEmail = null;
$this->validator->validate($data, ['groups' => ['Default', 'create']]);
Expand Down
11 changes: 9 additions & 2 deletions api/src/State/PersonalInvitationAcceptProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

/**
* @implements ProcessorInterface<PersonalInvitation,PersonalInvitation>
Expand All @@ -35,6 +36,10 @@ public function process(mixed $data, Operation $operation, array $uriVariables =
$user = $this->getUser();

$campCollaboration = $this->campCollaborationRepository->findByUserAndIdAndInvited($user, $data->id);
if (null === $campCollaboration) {
throw new NoResultException();
}

$campCollaboration->status = CampCollaboration::STATUS_ESTABLISHED;
$campCollaboration->inviteKey = null;
$campCollaboration->inviteKeyHash = null;
Expand All @@ -49,10 +54,12 @@ public function process(mixed $data, Operation $operation, array $uriVariables =
* @throws NonUniqueResultException
* @throws NoResultException
*/
protected function getUser(): ?User {
private function getUser(): ?User {
$user = $this->security->getUser();
if (null == $user) {
return null;
// This should never happen because it should be caught earlier by our security settings
// on all API operations using this processor.
throw new AccessDeniedHttpException();
}

return $this->userRepository->loadUserByIdentifier($user->getUserIdentifier());
Expand Down
12 changes: 6 additions & 6 deletions api/src/State/PersonalInvitationProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,37 +43,37 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
* @throws NoResultException
* @throws NonUniqueResultException
*/
protected function provideCollection(): ?array {
private function provideCollection(): array {
$user = $this->getUser();
if (null == $user) {
return [];
}
$campCollaborations = $this->campCollaborationRepository->findAllByPersonallyInvitedUser($user);

return array_map(function (CampCollaboration $campCollaboration) {
return $this->getInvitation($campCollaboration);
return $this->toInvitation($campCollaboration);
}, $campCollaborations);
}

/**
* @throws NoResultException
* @throws NonUniqueResultException
*/
protected function provideItem(string $id): ?PersonalInvitation {
private function provideItem(string $id): ?PersonalInvitation {
$user = $this->getUser();
if (null == $id || null == $user) {
return null;
}
$campCollaboration = $this->campCollaborationRepository->findByUserAndIdAndInvited($user, $id);

return $this->getInvitation($campCollaboration);
return $this->toInvitation($campCollaboration);
}

/**
* @throws NonUniqueResultException
* @throws NoResultException
*/
protected function getUser(): ?User {
private function getUser(): ?User {
$user = $this->security->getUser();
if (null == $user) {
return null;
Expand All @@ -82,7 +82,7 @@ protected function getUser(): ?User {
return $this->userRepository->loadUserByIdentifier($user->getUserIdentifier());
}

protected function getInvitation(?CampCollaboration $campCollaboration): ?PersonalInvitation {
private function toInvitation(?CampCollaboration $campCollaboration): ?PersonalInvitation {
if (null == $campCollaboration) {
return null;
}
Expand Down
11 changes: 9 additions & 2 deletions api/src/State/PersonalInvitationRejectProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

/**
* @implements ProcessorInterface<PersonalInvitation,PersonalInvitation>
Expand All @@ -35,6 +36,10 @@ public function process(mixed $data, Operation $operation, array $uriVariables =
$user = $this->getUser();

$campCollaboration = $this->campCollaborationRepository->findByUserAndIdAndInvited($user, $data->id);
if (null === $campCollaboration) {
throw new NoResultException();
}

$campCollaboration->status = CampCollaboration::STATUS_INACTIVE;
$campCollaboration->inviteKey = null;
$campCollaboration->inviteKeyHash = null;
Expand All @@ -48,10 +53,12 @@ public function process(mixed $data, Operation $operation, array $uriVariables =
* @throws NonUniqueResultException
* @throws NoResultException
*/
protected function getUser(): ?User {
private function getUser(): ?User {
$user = $this->security->getUser();
if (null == $user) {
return null;
// This should never happen because it should be caught earlier by our security settings
// on all API operations using this processor.
throw new AccessDeniedHttpException();
}

return $this->userRepository->loadUserByIdentifier($user->getUserIdentifier());
Expand Down
23 changes: 16 additions & 7 deletions api/tests/Api/Invitations/AcceptInvitationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,6 @@ public function testCannotFindInvitationAfterSuccessfulAccept() {
);
$this->assertResponseStatusCodeSame(200);
$this->assertJsonContains([
/*
'campId' => $campCollaboration->camp->getId(),
'campTitle' => $campCollaboration->camp->title,
'userDisplayName' => 'Bi-Pi',
'userAlreadyInCamp' => false, */
'_links' => [
'self' => ['href' => "/invitations/{$campCollaboration->inviteKey}/find"],
],
Expand Down Expand Up @@ -212,7 +207,14 @@ public static function invalidMethods(): array {
* @throws TransportExceptionInterface
*/
public function testNotFoundWhenInviteKeyDoesNotMatch() {
static::createClientWithCredentials()->request('PATCH', '/invitations/notExisting/'.Invitation::ACCEPT);
static::createClientWithCredentials()->request(
'PATCH',
'/invitations/notExisting/'.Invitation::ACCEPT,
[
'json' => [],
'headers' => ['Content-Type' => 'application/merge-patch+json'],
]
);
$this->assertResponseStatusCodeSame(404);
}

Expand All @@ -223,7 +225,14 @@ public function testNotFoundWhenInviteKeyDoesNotMatch() {
* @throws ClientExceptionInterface
*/
public function testNotFoundWhenNoInviteKey() {
static::createClientWithCredentials()->request('PATCH', '/invitations/'.Invitation::ACCEPT);
static::createClientWithCredentials()->request(
'PATCH',
'/invitations/'.Invitation::ACCEPT,
[
'json' => [],
'headers' => ['Content-Type' => 'application/merge-patch+json'],
]
);
$this->assertResponseStatusCodeSame(404);
}
}
33 changes: 16 additions & 17 deletions api/tests/Api/Invitations/RejectInvitationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,6 @@ public function testCannotFindInvitationAfterSuccessfulReject() {
);
$this->assertResponseStatusCodeSame(200);
$this->assertJsonContains([
/*
'campId' => $campCollaboration->camp->getId(),
'campTitle' => $campCollaboration->camp->title,
'userDisplayName' => null,
'userAlreadyInCamp' => null,*/
'_links' => [
'self' => ['href' => "/invitations/{$campCollaboration->inviteKey}/find"],
],
Expand Down Expand Up @@ -98,11 +93,6 @@ public function testRejectInvitationSucceedsWhenLoggedIn() {
);
$this->assertResponseStatusCodeSame(200);
$this->assertJsonContains([
/*
'campId' => $campCollaboration->camp->getId(),
'campTitle' => $campCollaboration->camp->title,
'userDisplayName' => 'Bi-Pi',
'userAlreadyInCamp' => false,*/
'_links' => [
'self' => ['href' => "/invitations/{$campCollaboration->inviteKey}/find"],
],
Expand Down Expand Up @@ -151,11 +141,6 @@ public function testRejectInvitationSucceedsWhenUserAlreadyInCamp() {
);
$this->assertResponseStatusCodeSame(200);
$this->assertJsonContains([
/*
'campId' => $campCollaboration->camp->getId(),
'campTitle' => $campCollaboration->camp->title,
'userDisplayName' => 'Bi-Pi',
'userAlreadyInCamp' => true,*/
'_links' => [
'self' => ['href' => "/invitations/{$campCollaboration->inviteKey}/find"],
],
Expand Down Expand Up @@ -187,7 +172,14 @@ public static function invalidMethods(): array {
* @throws TransportExceptionInterface
*/
public function testNotFoundWhenInviteKeyDoesNotMatch() {
static::createClientWithCredentials()->request('PATCH', '/invitations/notExisting/'.Invitation::REJECT);
static::createClientWithCredentials()->request(
'PATCH',
'/invitations/notExisting/'.Invitation::REJECT,
[
'json' => [],
'headers' => ['Content-Type' => 'application/merge-patch+json'],
]
);
$this->assertResponseStatusCodeSame(404);
}

Expand All @@ -198,7 +190,14 @@ public function testNotFoundWhenInviteKeyDoesNotMatch() {
* @throws ClientExceptionInterface
*/
public function testNotFoundWhenNoInviteKey() {
static::createClientWithCredentials()->request('PATCH', '/invitations/'.Invitation::REJECT);
static::createClientWithCredentials()->request(
'PATCH',
'/invitations/'.Invitation::REJECT,
[
'json' => [],
'headers' => ['Content-Type' => 'application/merge-patch+json'],
]
);
$this->assertResponseStatusCodeSame(404);
}
}
45 changes: 39 additions & 6 deletions api/tests/Api/PersonalInvitations/AcceptPersonalInvitationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,6 @@ public function testCannotFindPersonalInvitationAfterSuccessfulAccept() {
);
$this->assertResponseStatusCodeSame(200);
$this->assertJsonContains([
/*
'id' => $campCollaboration->getId(),
'campId' => $campCollaboration->camp->getId(),
'campTitle' => $campCollaboration->camp->title, */
'_links' => [
'self' => ['href' => "/personal_invitations/{$campCollaboration->getId()}"],
],
Expand Down Expand Up @@ -183,7 +179,37 @@ public static function invalidMethods(): array {
public function testNotFoundWhenIdDoesNotMatch() {
/** @var Profile $profile */
$profile = static::getFixture('profile6invited');
static::createClientWithCredentials(['email' => $profile->email])->request('PATCH', '/personal_invitations/notExisting/'.PersonalInvitation::ACCEPT);
static::createClientWithCredentials(['email' => $profile->email])->request(
'PATCH',
'/personal_invitations/notExisting/'.PersonalInvitation::ACCEPT,
[
'json' => [],
'headers' => ['Content-Type' => 'application/merge-patch+json'],
]
);
$this->assertResponseStatusCodeSame(404);
}

/**
* @throws ClientExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
public function testNotFoundWhenUserHasNoAccessToPersonalInvitation() {
/** @var CampCollaboration $campCollaboration */
$campCollaboration = static::getFixture('campCollaboration6invitedWithUser');

/** @var Profile $profile */
$profile = static::getFixture('profile8memberOnlyInCamp2');
static::createClientWithCredentials(['email' => $profile->email])->request(
'PATCH',
"/personal_invitations/{$campCollaboration->getId()}/".PersonalInvitation::ACCEPT,
[
'json' => [],
'headers' => ['Content-Type' => 'application/merge-patch+json'],
]
);
$this->assertResponseStatusCodeSame(404);
}

Expand All @@ -196,7 +222,14 @@ public function testNotFoundWhenIdDoesNotMatch() {
public function testMethodNotAllowedWhenNoId() {
/** @var Profile $profile */
$profile = static::getFixture('profile6invited');
static::createClientWithCredentials(['email' => $profile->email])->request('PATCH', '/personal_invitations/'.PersonalInvitation::ACCEPT);
static::createClientWithCredentials(['email' => $profile->email])->request(
'PATCH',
'/personal_invitations/'.PersonalInvitation::ACCEPT,
[
'json' => [],
'headers' => ['Content-Type' => 'application/merge-patch+json'],
]
);
$this->assertResponseStatusCodeSame(405);
}
}
49 changes: 39 additions & 10 deletions api/tests/Api/PersonalInvitations/RejectPersonalInvitationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ public function testRejectPersonalInvitationSucceedsWhenLoggedIn() {
);
$this->assertResponseStatusCodeSame(200);
$this->assertJsonContains([
/*
'id' => $campCollaboration->getId(),
'campId' => $campCollaboration->camp->getId(),
'campTitle' => $campCollaboration->camp->title,*/
'_links' => [
'self' => ['href' => "/personal_invitations/{$campCollaboration->getId()}"],
],
Expand Down Expand Up @@ -96,10 +92,6 @@ public function testCannotFindPersonalInvitationAfterSuccessfulReject() {
);
$this->assertResponseStatusCodeSame(200);
$this->assertJsonContains([
/*
'id' => $campCollaboration->getId(),
'campId' => $campCollaboration->camp->getId(),
'campTitle' => $campCollaboration->camp->title,*/
'_links' => [
'self' => ['href' => "/personal_invitations/{$campCollaboration->getId()}"],
],
Expand Down Expand Up @@ -164,7 +156,37 @@ public static function invalidMethods(): array {
public function testNotFoundWhenIdDoesNotMatch() {
/** @var Profile $profile */
$profile = static::getFixture('profile6invited');
static::createClientWithCredentials(['email' => $profile->email])->request('PATCH', '/personal_invitations/notExisting/'.PersonalInvitation::REJECT);
static::createClientWithCredentials(['email' => $profile->email])->request(
'PATCH',
'/personal_invitations/notExisting/'.PersonalInvitation::REJECT,
[
'json' => [],
'headers' => ['Content-Type' => 'application/merge-patch+json'],
]
);
$this->assertResponseStatusCodeSame(404);
}

/**
* @throws ClientExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
public function testNotFoundWhenUserHasNoAccessToPersonalInvitation() {
/** @var CampCollaboration $campCollaboration */
$campCollaboration = static::getFixture('campCollaboration6invitedWithUser');

/** @var Profile $profile */
$profile = static::getFixture('profile8memberOnlyInCamp2');
static::createClientWithCredentials(['email' => $profile->email])->request(
'PATCH',
"/personal_invitations/{$campCollaboration->getId()}/".PersonalInvitation::REJECT,
[
'json' => [],
'headers' => ['Content-Type' => 'application/merge-patch+json'],
]
);
$this->assertResponseStatusCodeSame(404);
}

Expand All @@ -177,7 +199,14 @@ public function testNotFoundWhenIdDoesNotMatch() {
public function testMethodNotAllowedWhenNoId() {
/** @var Profile $profile */
$profile = static::getFixture('profile6invited');
static::createClientWithCredentials(['email' => $profile->email])->request('PATCH', '/personal_invitations/'.PersonalInvitation::REJECT);
static::createClientWithCredentials(['email' => $profile->email])->request(
'PATCH',
'/personal_invitations/'.PersonalInvitation::REJECT,
[
'json' => [],
'headers' => ['Content-Type' => 'application/merge-patch+json'],
]
);
$this->assertResponseStatusCodeSame(405);
}
}

0 comments on commit 2fbe07b

Please sign in to comment.