Fixed some issues with retrieving dojo and character

develop
Hecht 5 months ago
parent ba862e44fc
commit 57e53526e6

@ -79,7 +79,6 @@
<resource class="App\Entity\Dojo"> <resource class="App\Entity\Dojo">
<operations> <operations>
<operation class="ApiPlatform\Metadata\Get" /> <operation class="ApiPlatform\Metadata\Get" />
<operation class="ApiPlatform\Metadata\Get" uriTemplate="dojo" controller="App\Controller\GetUserDojo" />
<operation class="ApiPlatform\Metadata\Post" processor="App\State\DojoPostProcessor"/> <operation class="ApiPlatform\Metadata\Post" processor="App\State\DojoPostProcessor"/>
<operation class="ApiPlatform\Metadata\Patch" /> <operation class="ApiPlatform\Metadata\Patch" />
</operations> </operations>

@ -1,21 +0,0 @@
<?php
namespace App\Controller;
use App\Entity\Dojo;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpKernel\Attribute\AsController;
#[AsController]
final class GetUserDojo
{
public function __construct(private Security $security)
{}
public function __invoke(EntityManagerInterface $em): ?Dojo
{
return $em->getRepository(Dojo::class)->findOneByOwner($this->security->getUser());
}
}

@ -2,7 +2,7 @@
namespace App\Factory; namespace App\Factory;
use App\Entity\Character; use App\Entity\Character;
use Zenstruck\Foundry\ModelFactory; use Zenstruck\Foundry\Persistence\PersistentProxyObjectFactory;
/** /**
* *
@ -24,7 +24,7 @@ use Zenstruck\Foundry\ModelFactory;
* @method static Character[]|Proxy[] randomRange(int $min, int $max, array $attributes = []) * @method static Character[]|Proxy[] randomRange(int $min, int $max, array $attributes = [])
* @method static Character[]|Proxy[] randomSet(int $number, array $attributes = []) * @method static Character[]|Proxy[] randomSet(int $number, array $attributes = [])
*/ */
final class CharacterFactory extends ModelFactory final class CharacterFactory extends PersistentProxyObjectFactory
{ {
/** /**
@ -44,7 +44,7 @@ final class CharacterFactory extends ModelFactory
* *
* @todo add your default values here * @todo add your default values here
*/ */
protected function getDefaults(): array protected function defaults(): array
{ {
return [ return [
'name' => self::faker()->firstName(), 'name' => self::faker()->firstName(),
@ -66,7 +66,7 @@ final class CharacterFactory extends ModelFactory
// ->afterInstantiate(function(Character $character): void {}) // ->afterInstantiate(function(Character $character): void {})
} }
protected static function getClass(): string public static function class(): string
{ {
return Character::class; return Character::class;
} }

@ -1,35 +1,34 @@
<?php <?php
namespace App\Factory; namespace App\Factory;
use App\Entity\Dojo; use App\Entity\Dojo;
use Doctrine\ORM\EntityRepository; use Zenstruck\Foundry\Persistence\PersistentProxyObjectFactory;
use Zenstruck\Foundry\ModelFactory;
use Zenstruck\Foundry\Proxy;
use Zenstruck\Foundry\RepositoryProxy;
/** /**
*
* @extends ModelFactory<Dojo> * @extends ModelFactory<Dojo>
* *
* @method Dojo|Proxy create(array|callable $attributes = []) * @method Dojo|Proxy create(array|callable $attributes = [])
* @method static Dojo|Proxy createOne(array $attributes = []) * @method static Dojo|Proxy createOne(array $attributes = [])
* @method static Dojo|Proxy find(object|array|mixed $criteria) * @method static Dojo|Proxy find(object|array|mixed $criteria)
* @method static Dojo|Proxy findOrCreate(array $attributes) * @method static Dojo|Proxy findOrCreate(array $attributes)
* @method static Dojo|Proxy first(string $sortedField = 'id') * @method static Dojo|Proxy first(string $sortedField = 'id')
* @method static Dojo|Proxy last(string $sortedField = 'id') * @method static Dojo|Proxy last(string $sortedField = 'id')
* @method static Dojo|Proxy random(array $attributes = []) * @method static Dojo|Proxy random(array $attributes = [])
* @method static Dojo|Proxy randomOrCreate(array $attributes = []) * @method static Dojo|Proxy randomOrCreate(array $attributes = [])
* @method static EntityRepository|RepositoryProxy repository() * @method static EntityRepository|RepositoryProxy repository()
* @method static Dojo[]|Proxy[] all() * @method static Dojo[]|Proxy[] all()
* @method static Dojo[]|Proxy[] createMany(int $number, array|callable $attributes = []) * @method static Dojo[]|Proxy[] createMany(int $number, array|callable $attributes = [])
* @method static Dojo[]|Proxy[] createSequence(iterable|callable $sequence) * @method static Dojo[]|Proxy[] createSequence(iterable|callable $sequence)
* @method static Dojo[]|Proxy[] findBy(array $attributes) * @method static Dojo[]|Proxy[] findBy(array $attributes)
* @method static Dojo[]|Proxy[] randomRange(int $min, int $max, array $attributes = []) * @method static Dojo[]|Proxy[] randomRange(int $min, int $max, array $attributes = [])
* @method static Dojo[]|Proxy[] randomSet(int $number, array $attributes = []) * @method static Dojo[]|Proxy[] randomSet(int $number, array $attributes = [])
*/ */
final class DojoFactory extends ModelFactory final class DojoFactory extends PersistentProxyObjectFactory
{ {
/** /**
*
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services * @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services
* *
* @todo inject services if required * @todo inject services if required
@ -40,29 +39,30 @@ final class DojoFactory extends ModelFactory
} }
/** /**
*
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#model-factories * @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#model-factories
* *
* @todo add your default values here * @todo add your default values here
*/ */
protected function getDefaults(): array protected function defaults(): array
{ {
return [ return [
'name' => self::faker()->text(), 'name' => self::faker()->text(),
'owner' => UserFactory::new(), 'owner' => UserFactory::new()
]; ];
} }
/** /**
*
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#initialization * @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#initialization
*/ */
protected function initialize(): self protected function initialize(): self
{ {
return $this return $this;
// ->afterInstantiate(function(Dojo $dojo): void {}) // ->afterInstantiate(function(Dojo $dojo): void {})
;
} }
protected static function getClass(): string public static function class(): string
{ {
return Dojo::class; return Dojo::class;
} }

@ -1,35 +1,34 @@
<?php <?php
namespace App\Factory; namespace App\Factory;
use App\Entity\Fight; use App\Entity\Fight;
use App\Repository\FightRepository; use Zenstruck\Foundry\Persistence\PersistentProxyObjectFactory;
use Zenstruck\Foundry\ModelFactory;
use Zenstruck\Foundry\Proxy;
use Zenstruck\Foundry\RepositoryProxy;
/** /**
*
* @extends ModelFactory<Fight> * @extends ModelFactory<Fight>
* *
* @method Fight|Proxy create(array|callable $attributes = []) * @method Fight|Proxy create(array|callable $attributes = [])
* @method static Fight|Proxy createOne(array $attributes = []) * @method static Fight|Proxy createOne(array $attributes = [])
* @method static Fight|Proxy find(object|array|mixed $criteria) * @method static Fight|Proxy find(object|array|mixed $criteria)
* @method static Fight|Proxy findOrCreate(array $attributes) * @method static Fight|Proxy findOrCreate(array $attributes)
* @method static Fight|Proxy first(string $sortedField = 'id') * @method static Fight|Proxy first(string $sortedField = 'id')
* @method static Fight|Proxy last(string $sortedField = 'id') * @method static Fight|Proxy last(string $sortedField = 'id')
* @method static Fight|Proxy random(array $attributes = []) * @method static Fight|Proxy random(array $attributes = [])
* @method static Fight|Proxy randomOrCreate(array $attributes = []) * @method static Fight|Proxy randomOrCreate(array $attributes = [])
* @method static FightRepository|RepositoryProxy repository() * @method static FightRepository|RepositoryProxy repository()
* @method static Fight[]|Proxy[] all() * @method static Fight[]|Proxy[] all()
* @method static Fight[]|Proxy[] createMany(int $number, array|callable $attributes = []) * @method static Fight[]|Proxy[] createMany(int $number, array|callable $attributes = [])
* @method static Fight[]|Proxy[] createSequence(iterable|callable $sequence) * @method static Fight[]|Proxy[] createSequence(iterable|callable $sequence)
* @method static Fight[]|Proxy[] findBy(array $attributes) * @method static Fight[]|Proxy[] findBy(array $attributes)
* @method static Fight[]|Proxy[] randomRange(int $min, int $max, array $attributes = []) * @method static Fight[]|Proxy[] randomRange(int $min, int $max, array $attributes = [])
* @method static Fight[]|Proxy[] randomSet(int $number, array $attributes = []) * @method static Fight[]|Proxy[] randomSet(int $number, array $attributes = [])
*/ */
final class FightFactory extends ModelFactory final class FightFactory extends PersistentProxyObjectFactory
{ {
/** /**
*
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services * @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services
* *
* @todo inject services if required * @todo inject services if required
@ -40,31 +39,32 @@ final class FightFactory extends ModelFactory
} }
/** /**
*
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#model-factories * @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#model-factories
* *
* @todo add your default values here * @todo add your default values here
*/ */
protected function getDefaults(): array protected function defaults(): array
{ {
return [ return [
'events' => [], 'events' => [],
'startDate' => self::faker()->dateTime(), 'startDate' => self::faker()->dateTime(),
'tournament' => TournamentFactory::new(), 'tournament' => TournamentFactory::new(),
'winner' => CharacterFactory::new(), 'winner' => CharacterFactory::new()
]; ];
} }
/** /**
*
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#initialization * @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#initialization
*/ */
protected function initialize(): self protected function initialize(): self
{ {
return $this return $this;
// ->afterInstantiate(function(Fight $fight): void {}) // ->afterInstantiate(function(Fight $fight): void {})
;
} }
protected static function getClass(): string public static function class(): string
{ {
return Fight::class; return Fight::class;
} }

@ -2,7 +2,7 @@
namespace App\Factory; namespace App\Factory;
use App\Entity\Technique; use App\Entity\Technique;
use Zenstruck\Foundry\ModelFactory; use Zenstruck\Foundry\Persistence\PersistentProxyObjectFactory;
/** /**
* *
@ -24,7 +24,7 @@ use Zenstruck\Foundry\ModelFactory;
* @method static Technique[]|Proxy[] randomRange(int $min, int $max, array $attributes = []) * @method static Technique[]|Proxy[] randomRange(int $min, int $max, array $attributes = [])
* @method static Technique[]|Proxy[] randomSet(int $number, array $attributes = []) * @method static Technique[]|Proxy[] randomSet(int $number, array $attributes = [])
*/ */
final class TechniqueFactory extends ModelFactory final class TechniqueFactory extends PersistentProxyObjectFactory
{ {
/** /**
@ -44,7 +44,7 @@ final class TechniqueFactory extends ModelFactory
* *
* @todo add your default values here * @todo add your default values here
*/ */
protected function getDefaults(): array protected function defaults(): array
{ {
return [ return [
'name' => self::faker()->ean13(), 'name' => self::faker()->ean13(),
@ -66,7 +66,7 @@ final class TechniqueFactory extends ModelFactory
// ->afterInstantiate(function(Technique $technique): void {}) // ->afterInstantiate(function(Technique $technique): void {})
} }
protected static function getClass(): string public static function class(): string
{ {
return Technique::class; return Technique::class;
} }

@ -1,35 +1,34 @@
<?php <?php
namespace App\Factory; namespace App\Factory;
use App\Entity\Tournament; use App\Entity\Tournament;
use App\Repository\TournamentRepository; use Zenstruck\Foundry\Persistence\PersistentProxyObjectFactory;
use Zenstruck\Foundry\ModelFactory;
use Zenstruck\Foundry\Proxy;
use Zenstruck\Foundry\RepositoryProxy;
/** /**
*
* @extends ModelFactory<Tournament> * @extends ModelFactory<Tournament>
* *
* @method Tournament|Proxy create(array|callable $attributes = []) * @method Tournament|Proxy create(array|callable $attributes = [])
* @method static Tournament|Proxy createOne(array $attributes = []) * @method static Tournament|Proxy createOne(array $attributes = [])
* @method static Tournament|Proxy find(object|array|mixed $criteria) * @method static Tournament|Proxy find(object|array|mixed $criteria)
* @method static Tournament|Proxy findOrCreate(array $attributes) * @method static Tournament|Proxy findOrCreate(array $attributes)
* @method static Tournament|Proxy first(string $sortedField = 'id') * @method static Tournament|Proxy first(string $sortedField = 'id')
* @method static Tournament|Proxy last(string $sortedField = 'id') * @method static Tournament|Proxy last(string $sortedField = 'id')
* @method static Tournament|Proxy random(array $attributes = []) * @method static Tournament|Proxy random(array $attributes = [])
* @method static Tournament|Proxy randomOrCreate(array $attributes = []) * @method static Tournament|Proxy randomOrCreate(array $attributes = [])
* @method static TournamentRepository|RepositoryProxy repository() * @method static TournamentRepository|RepositoryProxy repository()
* @method static Tournament[]|Proxy[] all() * @method static Tournament[]|Proxy[] all()
* @method static Tournament[]|Proxy[] createMany(int $number, array|callable $attributes = []) * @method static Tournament[]|Proxy[] createMany(int $number, array|callable $attributes = [])
* @method static Tournament[]|Proxy[] createSequence(iterable|callable $sequence) * @method static Tournament[]|Proxy[] createSequence(iterable|callable $sequence)
* @method static Tournament[]|Proxy[] findBy(array $attributes) * @method static Tournament[]|Proxy[] findBy(array $attributes)
* @method static Tournament[]|Proxy[] randomRange(int $min, int $max, array $attributes = []) * @method static Tournament[]|Proxy[] randomRange(int $min, int $max, array $attributes = [])
* @method static Tournament[]|Proxy[] randomSet(int $number, array $attributes = []) * @method static Tournament[]|Proxy[] randomSet(int $number, array $attributes = [])
*/ */
final class TournamentFactory extends ModelFactory final class TournamentFactory extends PersistentProxyObjectFactory
{ {
/** /**
*
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services * @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services
* *
* @todo inject services if required * @todo inject services if required
@ -40,29 +39,30 @@ final class TournamentFactory extends ModelFactory
} }
/** /**
*
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#model-factories * @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#model-factories
* *
* @todo add your default values here * @todo add your default values here
*/ */
protected function getDefaults(): array protected function defaults(): array
{ {
return [ return [
'name' => self::faker()->text(255), 'name' => self::faker()->text(255),
'startDate' => self::faker()->dateTime(), 'startDate' => self::faker()->dateTime()
]; ];
} }
/** /**
*
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#initialization * @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#initialization
*/ */
protected function initialize(): self protected function initialize(): self
{ {
return $this return $this;
// ->afterInstantiate(function(Tournament $tournament): void {}) // ->afterInstantiate(function(Tournament $tournament): void {})
;
} }
protected static function getClass(): string public static function class(): string
{ {
return Tournament::class; return Tournament::class;
} }

@ -2,7 +2,7 @@
namespace App\Factory; namespace App\Factory;
use App\Entity\User; use App\Entity\User;
use Zenstruck\Foundry\ModelFactory; use Zenstruck\Foundry\Persistence\PersistentProxyObjectFactory;
/** /**
* *
@ -24,7 +24,7 @@ use Zenstruck\Foundry\ModelFactory;
* @method static User[]|Proxy[] randomRange(int $min, int $max, array $attributes = []) * @method static User[]|Proxy[] randomRange(int $min, int $max, array $attributes = [])
* @method static User[]|Proxy[] randomSet(int $number, array $attributes = []) * @method static User[]|Proxy[] randomSet(int $number, array $attributes = [])
*/ */
final class UserFactory extends ModelFactory final class UserFactory extends PersistentProxyObjectFactory
{ {
/** /**
@ -44,7 +44,7 @@ final class UserFactory extends ModelFactory
* *
* @todo add your default values here * @todo add your default values here
*/ */
protected function getDefaults(): array protected function defaults(): array
{ {
return [ return [
'authName' => self::faker()->userName(), 'authName' => self::faker()->userName(),
@ -62,7 +62,7 @@ final class UserFactory extends ModelFactory
// ->afterInstantiate(function(User $user): void {}) // ->afterInstantiate(function(User $user): void {})
} }
protected static function getClass(): string public static function class(): string
{ {
return User::class; return User::class;
} }

@ -35,6 +35,8 @@ class DojoPostProcessor implements ProcessorInterface
private function updateDojo(Dojo $dojo): void private function updateDojo(Dojo $dojo): void
{ {
$user = $this->security->getUser();
$dojo->setOwner($this->security->getUser()); $dojo->setOwner($this->security->getUser());
$user->setDojo($dojo);
} }
} }

@ -1,14 +1,30 @@
<?php <?php
namespace App\Tests; namespace App\Tests;
use App\Entity\Dojo;
use App\Factory\CharacterFactory; use App\Factory\CharacterFactory;
use App\Factory\DojoFactory; use App\Factory\DojoFactory;
use App\Factory\TechniqueFactory; use App\Factory\TechniqueFactory;
use App\Factory\UserFactory; use App\Factory\UserFactory;
use Zenstruck\Foundry\Proxy;
class CharacterTest extends AbstractTest class CharacterTest extends AbstractTest
{ {
private function createCharacters(Proxy|Dojo $dojo): array
{
$technique = TechniqueFactory::createOne();
$characters = CharacterFactory::createMany(4, [
'dojo' => $dojo,
'techniques' => [
$technique
]
]);
return $characters;
}
/** /**
* Requirement: A user should be able see all characters from a dojo, but only the public fields! * Requirement: A user should be able see all characters from a dojo, but only the public fields!
*/ */
@ -92,6 +108,29 @@ class CharacterTest extends AbstractTest
->toBase32(), $chars[0]['techniques'][0]); ->toBase32(), $chars[0]['techniques'][0]);
} }
/**
* Regression test, to verify that the method will also work when multiple dojos are created.
*/
public function testRetrieveCharactersFromOwnDojoOnly(): void
{
$dojo = DojoFactory::createOne([
'owner' => UserFactory::createOne()
]);
$chars = $this->createCharacters($dojo);
$otherDojos = DojoFactory::createMany(10);
foreach ($otherDojos as $otherDojo) {
$this->createCharacters($otherDojo);
}
$response = static::createClientWithToken($dojo->getOwner()->authName)->request('GET', '/api/dojo/characters');
$this->assertResponseStatusCodeSame(200);
$readChars = $response->toArray();
$this->assertEquals(count($chars), count($readChars));
}
/** /**
* Requirement: MVP only (in the future the recuitment will be different). * Requirement: MVP only (in the future the recuitment will be different).
* A user should be able to create a single character. * A user should be able to create a single character.

@ -11,7 +11,7 @@ class DojoTest extends AbstractTest
/** /**
* Requirement: A user should be able to create a dojo! * Requirement: A user should be able to create a dojo!
*/ */
public function testCreateDojo(): void public function testDojoCreate(): void
{ {
$userName = "FooBarFigher"; $userName = "FooBarFigher";
$dojoName = "BigFightDojo"; $dojoName = "BigFightDojo";
@ -27,58 +27,18 @@ class DojoTest extends AbstractTest
$this->assertResponseStatusCodeSame(201); $this->assertResponseStatusCodeSame(201);
$this->assertCount(1, $userRepository->findByAuthName($userName)); $user = $userRepository->findOneByAuthName($userName);
}
/**
* Requirement: A user should be request his own dojo!
*/
public function testUserReadDojo(): void
{
$userName = "FooBarFigher";
$dojoName = "BigFightDojo";
$dojo = DojoFactory::createOne(
[
'name' => $dojoName,
'owner' => UserFactory::createOne([
'authName' => $userName
])
]);
static::createClientWithToken($userName)->request('GET', '/api/dojo');
$this->assertResponseStatusCodeSame(200);
$this->assertJsonContains(
[
'name' => 'BigFightDojo',
'members' => [],
'owner' => $this->getIri($dojo->getOwner()),
'id' => $dojo->getId()
->toBase32()
]);
}
/**
* Requirement: A user should be request his own dojo!
* Fails, if the dojo is not yet created.
*/
public function testUserReadDojoNotYetCreated(): void
{
$userName = "FooBarFigher";
$userRepository = $this->getContainer()->get(UserRepository::class);
$this->assertCount(0, $userRepository->findByAuthName($userName));
static::createClientWithToken($userName)->request('GET', '/api/dojo'); $this->assertJsonContains([
'name' => $dojoName,
$this->assertResponseStatusCodeSame(404); 'owner' => $this->getIri($user)
]);
} }
/** /**
* Requirement: A user should NOT be able to create more than one dojos! * Requirement: A user should NOT be able to create more than one dojos!
*/ */
public function testUserCannotCreateMultipleDojos(): void public function testDojoUserCannotCreateMultipleDojos(): void
{ {
$userName = "FooBarFigher"; $userName = "FooBarFigher";
$dojoName = "BigFightDojo"; $dojoName = "BigFightDojo";
@ -102,7 +62,7 @@ class DojoTest extends AbstractTest
* Requirement: A user should be able to change the dojos name! * Requirement: A user should be able to change the dojos name!
* FIXME: Add limitation so users will not do this frequently. * FIXME: Add limitation so users will not do this frequently.
*/ */
public function testChangeDojoName(): void public function testDojoChangeDojoName(): void
{ {
$userName = "FooBarFigher"; $userName = "FooBarFigher";
$dojoName = "BigFightDojo"; $dojoName = "BigFightDojo";
@ -127,5 +87,24 @@ class DojoTest extends AbstractTest
$this->assertResponseStatusCodeSame(200); $this->assertResponseStatusCodeSame(200);
} }
public function testDojoRetrieve(): void
{
$userName = "FooBarFigher";
$dojoName = "SmallFightDojo";
$dojo = DojoFactory::createOne(
[
'name' => $dojoName,
'owner' => UserFactory::createOne([
'authName' => $userName
])
]);
static::createClientWithToken($userName)->request('GET', '/api/dojos/' . $dojo->getId());
$this->assertJsonContains([
'name' => $dojoName
]);
}
} }

@ -6,6 +6,18 @@ use App\Factory\UserFactory;
class UserTest extends AbstractTest class UserTest extends AbstractTest
{ {
public function testUserGetByAuthname(): void
{
$requestUser = UserFactory::createOne();
UserFactory::createMany(5);
$response = static::createClientWithToken($requestUser->authName)->request('GET',
'/api/users/authName/' . $requestUser->authName);
$this->assertResponseStatusCodeSame(200);
$this->assertEquals($requestUser->getId(), $response->toArray()['id']);
}
/** /**
* Requirement: A user should be able to update his properties * Requirement: A user should be able to update his properties
*/ */
@ -53,7 +65,7 @@ class UserTest extends AbstractTest
] ]
]); ]);
$this->assertResponseStatusCodeSame(405); $this->assertResponseStatusCodeSame(200);
$this->assertNotEquals("foo.bar", $response->toArray()['authName']); $this->assertNotEquals("foo.bar", $response->toArray()['authName']);
} }

Loading…
Cancel
Save