diff --git a/config/api_platform/resources.xml b/config/api_platform/resources.xml
index 023144a..9f3de08 100644
--- a/config/api_platform/resources.xml
+++ b/config/api_platform/resources.xml
@@ -143,14 +143,22 @@
-
+
-
+
+
+
+
+
+
+
+
+
diff --git a/src/Controller/GetTournamentFights.php b/src/Controller/GetTournamentFights.php
index 9d3d0a5..af55de5 100644
--- a/src/Controller/GetTournamentFights.php
+++ b/src/Controller/GetTournamentFights.php
@@ -13,8 +13,6 @@ class GetTournamentFights
{
return $em->getRepository(Fight::class)->findBy([
'tournament' => $tournamentId
- ], [
- 'startDate' => 'ASC'
]);
}
}
diff --git a/src/Entity/Character.php b/src/Entity/Character.php
index 38443b4..b1bae6e 100644
--- a/src/Entity/Character.php
+++ b/src/Entity/Character.php
@@ -167,17 +167,19 @@ class Character extends Thing
}
/**
- *
- * @return Technique[]
+ * @return Collection
*/
- public function getTechniques(): mixed
+ public function getTechniques(): Collection
{
- return $this->techniques->getValues();
+ return $this->techniques;
}
public function addTechnique(Technique $technique): static
{
- $this->techniques[] = $technique;
+ if (!$this->techniques->contains($technique)) {
+ $this->techniques->add($technique);
+ }
+
return $this;
}
diff --git a/src/Entity/Dojo.php b/src/Entity/Dojo.php
index 1323ff4..c0c4512 100644
--- a/src/Entity/Dojo.php
+++ b/src/Entity/Dojo.php
@@ -62,7 +62,6 @@ class Dojo extends Thing
}
/**
- *
* @return Collection
*/
public function getMembers(): Collection
@@ -72,7 +71,7 @@ class Dojo extends Thing
public function addMember(Character $member): static
{
- if (! $this->members->contains($member)) {
+ if (!$this->members->contains($member)) {
$this->members->add($member);
$member->setDojo($this);
}
diff --git a/src/Entity/Fight.php b/src/Entity/Fight.php
index bf6d0c8..0c0e11b 100644
--- a/src/Entity/Fight.php
+++ b/src/Entity/Fight.php
@@ -21,7 +21,6 @@ class Fight extends Thing
private array $events = [];
#[ORM\ManyToOne]
- #[ORM\JoinColumn(nullable: false)]
private ?Character $winner = null;
#[ORM\ManyToOne(inversedBy: 'fights')]
diff --git a/src/Entity/Tournament.php b/src/Entity/Tournament.php
index c616d89..170c88d 100644
--- a/src/Entity/Tournament.php
+++ b/src/Entity/Tournament.php
@@ -23,6 +23,9 @@ class Tournament extends Thing
#[ORM\OneToMany(mappedBy: 'tournament', targetEntity: Fight::class)]
private Collection $fights;
+ #[ORM\ManyToOne]
+ private ?Character $winner = null;
+
public function __construct()
{
$this->characters = new ArrayCollection();
@@ -108,4 +111,16 @@ class Tournament extends Thing
return $this;
}
+
+ public function getWinner(): ?Character
+ {
+ return $this->winner;
+ }
+
+ public function setWinner(?Character $winner): static
+ {
+ $this->winner = $winner;
+
+ return $this;
+ }
}
diff --git a/src/Entity/TournamentRegistration.php b/src/Entity/TournamentRegistration.php
index 4a7e731..193fee3 100644
--- a/src/Entity/TournamentRegistration.php
+++ b/src/Entity/TournamentRegistration.php
@@ -1,11 +1,15 @@
updateData($data);
+ $result = $this->persistProcessor->process($data, $operation, $uriVariables, $context);
+
+ return $result;
+ }
+
+ private function updateData(TournamentRegistration $registration): void
+ {
+ $tournament = $registration->tournament;
+ $character = $registration->character;
+
+ if ($tournament->getCharacters()->contains($character)) {
+ throw new BadRequestException("Character is already registered!");
+ }
+
+ $registration->tournament->addCharacter($registration->character);
+ $this->em->persist($registration->tournament);
+ $this->em->persist($registration->character);
+ $this->em->flush();
+ }
+}
diff --git a/src/Validator/CharacterOwned.php b/src/Validator/CharacterOwned.php
new file mode 100644
index 0000000..2d5c11b
--- /dev/null
+++ b/src/Validator/CharacterOwned.php
@@ -0,0 +1,12 @@
+getDojo()
+ ->getOwner()
+ ->getId() != $this->security->getUser()->getUserIdentifier()) {
+ $this->context->buildViolation($constraint->invalidOwnerMessage)->addViolation();
+ }
+ }
+}
+
diff --git a/src/Validator/StartDateInFuture.php b/src/Validator/StartDateInFuture.php
new file mode 100644
index 0000000..7e8728f
--- /dev/null
+++ b/src/Validator/StartDateInFuture.php
@@ -0,0 +1,12 @@
+getStartDate() < new DateTimeImmutable("now", new DateTimeZone("UTC"))) {
+ $this->context->buildViolation($constraint->invalidStartDateMessage)->addViolation();
+ }
+ }
+}
+
diff --git a/tests/AbstractTest.php b/tests/AbstractTest.php
index bb5f96b..7ce59bd 100644
--- a/tests/AbstractTest.php
+++ b/tests/AbstractTest.php
@@ -4,6 +4,7 @@ namespace App\Tests;
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
use ApiPlatform\Symfony\Bundle\Test\Client;
use App\Entity\Thing;
+use Doctrine\ORM\EntityManagerInterface;
use Zenstruck\Foundry\Proxy;
use Zenstruck\Foundry\Test\Factories;
use Zenstruck\Foundry\Test\ResetDatabase;
@@ -48,5 +49,10 @@ abstract class AbstractTest extends ApiTestCase
}
return $this->getIriFromResource($thing);
}
+
+ protected function getEntityManager(): EntityManagerInterface
+ {
+ return static::$kernel->getContainer()->get('doctrine.orm.entity_manager');
+ }
}
diff --git a/tests/TournamentTest.php b/tests/TournamentTest.php
index 54d0b72..37b2ec8 100644
--- a/tests/TournamentTest.php
+++ b/tests/TournamentTest.php
@@ -1,29 +1,53 @@
sub(\DateInterval::createFromDateString($offset));
+ return TournamentFactory::createOne([
+ 'startDate' => $tournamentStartDate,
+ 'characters' => $characters
+ ]);
+ }
+
+ private function createCharacter(User|Proxy $user): Character|Proxy
+ {
$dojo = DojoFactory::createOne([
- 'owner' => UserFactory::createOne()
+ 'owner' => $user
]);
$character = CharacterFactory::createOne([
'dojo' => $dojo
]);
- $response = static::createClientWithToken($dojo->getOwner()->authName)->request('POST',
- '/api/tournament_registrations',
+ return $character;
+ }
+
+ public function testRegisterCharacter(): void
+ {
+ $tournament = $this->createTournament("-5 min");
+ $user = UserFactory::createOne();
+ $character = $this->createCharacter($user);
+
+ static::createClientWithToken($user->authName)->request('POST', '/api/tournament_registrations',
[
'json' => [
'tournament' => $this->getIri($tournament),
@@ -32,40 +56,142 @@ class TournamentTest extends AbstractTest
]);
$this->assertResponseStatusCodeSame(201);
+ }
+
+ public function testRegisterCharacterDifferentUser(): void
+ {
+ $tournament = $this->createTournament("-5 min");
+ $characterOwner = UserFactory::createOne();
+ $character = $this->createCharacter($characterOwner);
+ $user = UserFactory::createOne();
- $this->assertArrayHasKey('id', $response->toArray());
+ static::createClientWithToken($user->authName)->request('POST', '/api/tournament_registrations',
+ [
+ 'json' => [
+ 'tournament' => $this->getIri($tournament),
+ 'character' => $this->getIri($character)
+ ]
+ ]);
+
+ $this->assertResponseStatusCodeSame(422);
+ }
+
+ public function testRegisterCharacterOnPastTournament(): void
+ {
+ $tournament = $this->createTournament("5 min");
+ $user = UserFactory::createOne();
+ $character = $this->createCharacter($user);
+
+ static::createClientWithToken($user->authName)->request('POST', '/api/tournament_registrations',
+ [
+ 'json' => [
+ 'tournament' => $this->getIri($tournament),
+ 'character' => $this->getIri($character)
+ ]
+ ]);
+
+ $this->assertResponseStatusCodeSame(422);
}
public function testRegisterCharacterNotPossibleTwice(): void
- {}
+ {
+ $tournament = $this->createTournament("-5 min");
+ $user = UserFactory::createOne();
+ $character = $this->createCharacter($user);
- public function testRegisterCharacterOnPastTournament(): void
- {}
+ static::createClientWithToken($user->authName)->request('POST', '/api/tournament_registrations',
+ [
+ 'json' => [
+ 'tournament' => $this->getIri($tournament),
+ 'character' => $this->getIri($character)
+ ]
+ ]);
+
+ static::createClientWithToken($user->authName)->request('POST', '/api/tournament_registrations',
+ [
+ 'json' => [
+ 'tournament' => $this->getIri($tournament),
+ 'character' => $this->getIri($character)
+ ]
+ ]);
+
+ $this->assertEquals(1,
+ $this->getEntityManager()
+ ->find(Tournament::class, $tournament->getId())
+ ->getCharacters()
+ ->count());
+ $this->assertResponseStatusCodeSame(400);
+ }
public function testShowRegisteredCharacters(): void
- {}
+ {
+ $tournament = $this->createTournament("-5 min", CharacterFactory::createMany(4));
+
+ $response = static::createClientWithToken()->request('GET', $this->getIri($tournament));
+ $this->assertResponseStatusCodeSame(200);
+ $this->assertCount(4, $response->toArray()['characters']);
+ }
public function testListTournaments(): void
- {}
+ {
+ TournamentFactory::createMany(5);
+ $response = static::createClientWithToken()->request('GET', '/api/tournaments');
+ $this->assertResponseStatusCodeSame(200);
+ $this->assertCount(5, $response->toArray());
+ }
/**
* Status is ...
* meta data like when it is starting, name, "location", Winner (nullable), etc.
*/
public function testTournamentStatus(): void
- {}
+ {
+ $tournament = TournamentFactory::createOne([
+ 'winner' => CharacterFactory::createOne()
+ ]);
+ $response = static::createClientWithToken()->request('GET', $this->getIri($tournament));
+ $this->assertResponseStatusCodeSame(200);
+
+ $arrayResponse = $response->toArray();
+ $this->assertArrayHasKey('winner', $arrayResponse);
+ }
- // /api/tournament/{id}/fights
- // readableLink: true -> participant ids and winner
public function testTournamentFights(): void
- {}
+ {
+ $tournament = TournamentFactory::createOne([
+ 'fights' => FightFactory::createMany(16)
+ ]);
+
+ $response = static::createClientWithToken()->request('GET', $this->getIri($tournament) . '/fights');
+ $this->assertResponseStatusCodeSame(200);
+ $this->assertCount(16, $response->toArray());
+ }
- // /api/tournament/{id}/character/{id}/fights
public function testTournamentFightsForCharacter(): void
- {}
+ {
+ $characters = CharacterFactory::createMany(16);
+ $tournament = TournamentFactory::createOne([
+ 'characters' => $characters
+ ]);
- // /api/tournament/{id}/ranking
- public function testTournamentRanking(): void
- {}
+ $winner = $characters[0];
+ for ($i = 1; $i < count($characters); ++ $i) {
+ $tournament->addFight(
+ FightFactory::createOne([
+ 'winner' => $winner,
+ 'characters' => array(
+ $winner,
+ $characters[$i]
+ )
+ ])->object());
+ }
+ $tournament->save();
+
+ $response = static::createClientWithToken()->request('GET',
+ $this->getIri($tournament) . '/characters/' . $winner->getId()
+ ->toBase32() . '/fights');
+
+ $this->assertCount(15, $response->toArray());
+ }
}