played around with embedded entities

feature/symfony_upgrade
Hecht 4 years ago
parent 334f734012
commit 994e6e17cb

@ -11,6 +11,9 @@ App\Entity\Hero:
type: string type: string
length: 32 length: 32
unique: true unique: true
embedded:
skills:
class: Skillz
manyToOne: manyToOne:
user: user:

@ -0,0 +1,18 @@
App\Entity\Skillz:
type: embeddable
fields:
constitution: # basically the HP
type: integer
nullable: false
ki: # former MP! Some moves will require Ki to be available
type: integer
nullable: false
strength: # damage dealer / block skill?
type: integer
nullable: false
agility: # evade / hit chance skill??
type: integer
nullable: false
stamina: # if low => one is vulnerable for critical hits or slow attack speed / low damage
type: integer
nullable: false

@ -1,4 +1,8 @@
security: security:
encoders:
App\Entity\User:
algorithm: argon2i
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers: providers:
users_in_memory: { memory: null } users_in_memory: { memory: null }
@ -6,6 +10,12 @@ security:
dev: dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/ pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false security: false
api:
pattern: ^/api/
guard:
authenticators:
- App\Security\TokenAuthenticator
stateless: true
main: main:
anonymous: true anonymous: true
lazy: true lazy: true

@ -6,10 +6,14 @@ use App\Repository\HeroRepository;
use FOS\RestBundle\Controller\Annotations as Rest; use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Controller\AbstractFOSRestController; use FOS\RestBundle\Controller\AbstractFOSRestController;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use App\Entity\Hero;
/**
* @Rest\Route("api/hero")
*/
class HeroController extends AbstractFOSRestController class HeroController extends AbstractFOSRestController
{ {
protected $heroRepository; protected HeroRepository $heroRepository;
public function __construct(HeroRepository $heroRepository) public function __construct(HeroRepository $heroRepository)
{ {
@ -17,12 +21,20 @@ class HeroController extends AbstractFOSRestController
} }
/** /**
* @Rest\Route("api/heroes") * @Rest\Route("es")
* @Rest\View() * @Rest\View()
*/ */
public function cgetAction() public function cgetAction() : array
{ {
$heroes = $this->heroRepository->findAll(); return $this->heroRepository->findAll();
return $this->view($heroes, Response::HTTP_OK); }
/**
* @Rest\Route("/{id}"))
* @Rest\View()
*/
public function getAction(int $id) : ?Hero
{
return $this->heroRepository->find($id);
} }
} }

@ -6,10 +6,14 @@ use App\Repository\UserRepository;
use FOS\RestBundle\Controller\Annotations as Rest; use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Controller\AbstractFOSRestController; use FOS\RestBundle\Controller\AbstractFOSRestController;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use App\Entity\User;
/**
* @Rest\Route("api/user")
*/
class UserController extends AbstractFOSRestController class UserController extends AbstractFOSRestController
{ {
protected $userRepository; protected UserRepository $userRepository;
public function __construct(UserRepository $userRepository) public function __construct(UserRepository $userRepository)
{ {
@ -17,13 +21,21 @@ class UserController extends AbstractFOSRestController
} }
/** /**
* @Rest\Route("api/users") * @Rest\Route("s")
* @Rest\View() * @Rest\View()
*/ */
public function cgetAction() public function cgetAction() : array
{ {
$users = $this->userRepository->findAll(); return $this->userRepository->findAll();
return $this->view($users, Response::HTTP_OK); }
/**
* @Rest\Route("/{id}"))
* @Rest\View()
*/
public function getAction(int $id) : ?User
{
return $this->userRepository->find($id);
} }
} }

@ -13,7 +13,7 @@ class UserFixtures extends Fixture
public const DUDE_USER_REFERENCE = 'dummy-user'; public const DUDE_USER_REFERENCE = 'dummy-user';
private $passwordEncoder; private UserPasswordEncoderInterface $passwordEncoder;
public function __construct(UserPasswordEncoderInterface $passwordEncoder) public function __construct(UserPasswordEncoderInterface $passwordEncoder)
{ {
@ -25,13 +25,13 @@ class UserFixtures extends Fixture
$userAdmin = new User(); $userAdmin = new User();
$userAdmin->setUsername('admin'); $userAdmin->setUsername('admin');
$this->setPassword($userAdmin, '123456789'); $this->setPassword($userAdmin, '123456789');
$userAdmin->setApiToken('ItsHammerTime!'); $userAdmin->setApiToken(self::ADMIN_USER_REFERENCE);
$manager->persist($userAdmin); $manager->persist($userAdmin);
$userDude = new User(); $userDude = new User();
$userDude->setUsername('dude'); $userDude->setUsername('dude');
$this->setPassword($userDude, '1234'); $this->setPassword($userDude, '1234');
$userDude->setApiToken('ItsDuderzeit!'); $userDude->setApiToken(self::DUDE_USER_REFERENCE);
$manager->persist($userDude); $manager->persist($userDude);
$manager->flush(); $manager->flush();
@ -44,4 +44,5 @@ class UserFixtures extends Fixture
{ {
$user->setPassword($this->passwordEncoder->encodePassword($user, $plainPassword)); $user->setPassword($this->passwordEncoder->encodePassword($user, $plainPassword));
} }
} }

@ -4,11 +4,18 @@ namespace App\Entity;
class Hero class Hero
{ {
private $id; private ?int $id;
private $name; private ?string $name;
private $user; private ?User $user;
private Skillz $skills;
public function __construct()
{
$this->skills = new Skillz();
}
public function getId(): ?int public function getId(): ?int
{ {
@ -38,4 +45,16 @@ class Hero
return $this; return $this;
} }
public function getSkills(): Skillz
{
return $this->skills;
}
public function setSkills(Skillz $skills): self
{
$this->skills = $skills;
return $this;
}
} }

@ -0,0 +1,72 @@
<?php
namespace App\Entity;
class Skillz
{
private int $constitution = 0;
private int $ki = 0;
private int $strength = 0;
private int $agility = 0;
private int $stamina = 0;
public function getStrength(): ?int
{
return $this->strength;
}
public function setStrength(int $strength): self
{
$this->strength = $strength;
return $this;
}
public function getAgility(): ?int
{
return $this->agility;
}
public function setAgility(int $agility): self
{
$this->agility = $agility;
return $this;
}
public function getStamina(): ?int
{
return $this->stamina;
}
public function setStamina(int $stamina): self
{
$this->stamina = $stamina;
return $this;
}
public function getConstitution(): ?int
{
return $this->constitution;
}
public function setConstitution(int $constitution): self
{
$this->constitution = $constitution;
return $this;
}
public function getKi(): ?int
{
return $this->ki;
}
public function setKi(int $ki): self
{
$this->ki = $ki;
return $this;
}
}

@ -8,17 +8,17 @@ use Symfony\Component\Security\Core\User\UserInterface;
class User implements UserInterface class User implements UserInterface
{ {
private $id; private ?int $id;
private $username; private ?string $username;
private $password; private ?string $password;
private $apiToken; private ?string $apiToken;
private $roles = []; private array $roles = [];
private $heroes; private Collection $heroes;
public function __construct() public function __construct()
{ {

@ -14,10 +14,7 @@ use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
class TokenAuthenticator extends AbstractGuardAuthenticator class TokenAuthenticator extends AbstractGuardAuthenticator
{ {
/** private UserRepository $userRepository;
* @var UserRepository
*/
private $userRepository;
public function __construct(UserRepository $userRepository) public function __construct(UserRepository $userRepository)
{ {
@ -90,7 +87,8 @@ class TokenAuthenticator extends AbstractGuardAuthenticator
throw new UnauthorizedHttpException('', 'Authentication Required'); throw new UnauthorizedHttpException('', 'Authentication Required');
} }
public function supportsRememberMe()
public function supportsRememberMe() : bool
{ {
return false; return false;
} }

@ -23,7 +23,11 @@ class RestTestBase extends WebTestCase
protected function reloadDoctrineFixtures() protected function reloadDoctrineFixtures()
{ {
self::runCommand('doctrine:migration:migrate'); // we need our fixtures to be stateless, so remove everything and recreate to get the same
// index values all along the tests
self::runCommand('doctrine:schema:drop --force -n');
self::runCommand('doctrine:schema:create -n');
self::runCommand('doctrine:migration:migrate -n');
self::runCommand('doctrine:fixtures:load --purge-with-truncate -n'); self::runCommand('doctrine:fixtures:load --purge-with-truncate -n');
} }

@ -3,6 +3,8 @@
namespace App\Tests\Controller; namespace App\Tests\Controller;
use App\DataFixtures\UserFixtures; use App\DataFixtures\UserFixtures;
use App\Entity\User;
use App\Entity\Hero;
class UserControllerTest extends RestTestBase class UserControllerTest extends RestTestBase
{ {
@ -28,4 +30,32 @@ class UserControllerTest extends RestTestBase
$this->assertEquals(200, $response->getStatusCode(), 'Status code was ' . $response->getStatusCode() . ' but expected 200: ' . $response->getContent()); $this->assertEquals(200, $response->getStatusCode(), 'Status code was ' . $response->getStatusCode() . ' but expected 200: ' . $response->getContent());
} }
/**
* This test verifies that requesting
*/
public function testRetrieveUserWithID1()
{
$this->createRequestBuilder()
->setMethod('GET')
->setUri('/api/user/1')
->setAcceptType('application/json')
->addServerParameter('HTTP_X-AUTH-TOKEN', UserFixtures::ADMIN_USER_REFERENCE)
->request();
$response = $this->client->getResponse();
$this->assertTrue(
$response->headers->contains('Content-Type', 'application/json'),
'the "Content-Type" header is "' . $response->headers->get('Content-Type') . '"' // optional message shown on failure
);
$this->assertEquals(200, $response->getStatusCode(), 'Status code was ' . $response->getStatusCode() . ' but expected 200: ' . $response->getContent());
}
public function testUserDefaults()
{
$hero = new Hero();
$this->assertEquals(0, $hero->getStrength());
}
} }

Loading…
Cancel
Save