diff --git a/composer.json b/composer.json index d59ef97..7fbd14b 100644 --- a/composer.json +++ b/composer.json @@ -106,7 +106,7 @@ "symfony/browser-kit": "7.0.*", "symfony/css-selector": "7.0.*", "symfony/debug-bundle": "7.0.*", - "symfony/maker-bundle": "^1.0", + "symfony/maker-bundle": "^1.59", "symfony/phpunit-bridge": "^7.0", "symfony/stopwatch": "7.0.*", "symfony/web-profiler-bundle": "7.0.*" diff --git a/composer.lock b/composer.lock index 9e8ea25..75b7896 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "888e1953f86d0f1fe9b271b85aab0ed0", + "content-hash": "c3dc9b5ee79b98f2d1fabe3668860864", "packages": [ { "name": "composer/semver", @@ -3507,16 +3507,16 @@ }, { "name": "symfony/form", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "b4df6a399a2b03782a0163807239db342659f54f" + "reference": "1d0128e2f7e80c346ec51fa4d1ce4fec0d435eeb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/b4df6a399a2b03782a0163807239db342659f54f", - "reference": "b4df6a399a2b03782a0163807239db342659f54f", + "url": "https://api.github.com/repos/symfony/form/zipball/1d0128e2f7e80c346ec51fa4d1ce4fec0d435eeb", + "reference": "1d0128e2f7e80c346ec51fa4d1ce4fec0d435eeb", "shasum": "" }, "require": { @@ -3583,7 +3583,7 @@ "description": "Allows to easily create, process and reuse HTML forms", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/form/tree/v7.0.7" + "source": "https://github.com/symfony/form/tree/v7.0.8" }, "funding": [ { @@ -3599,7 +3599,7 @@ "type": "tidelift" } ], - "time": "2024-04-28T11:44:19+00:00" + "time": "2024-05-31T14:55:39+00:00" }, { "name": "symfony/framework-bundle", @@ -6887,16 +6887,16 @@ }, { "name": "symfony/validator", - "version": "v7.0.7", + "version": "v7.0.8", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "ab4e75b9d23ba70e78480aecbe4d8da15adf10eb" + "reference": "23af65dff1f4dfee9aab3a0123a243e40fa3d9cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/ab4e75b9d23ba70e78480aecbe4d8da15adf10eb", - "reference": "ab4e75b9d23ba70e78480aecbe4d8da15adf10eb", + "url": "https://api.github.com/repos/symfony/validator/zipball/23af65dff1f4dfee9aab3a0123a243e40fa3d9cf", + "reference": "23af65dff1f4dfee9aab3a0123a243e40fa3d9cf", "shasum": "" }, "require": { @@ -6941,7 +6941,8 @@ "Symfony\\Component\\Validator\\": "" }, "exclude-from-classmap": [ - "/Tests/" + "/Tests/", + "/Resources/bin/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -6961,7 +6962,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v7.0.7" + "source": "https://github.com/symfony/validator/tree/v7.0.8" }, "funding": [ { @@ -6977,7 +6978,7 @@ "type": "tidelift" } ], - "time": "2024-04-28T11:44:19+00:00" + "time": "2024-06-02T15:49:03+00:00" }, { "name": "symfony/var-dumper", diff --git a/src/Controller/PostController.php b/src/Controller/PostController.php index 0df3016..c8cdd5f 100644 --- a/src/Controller/PostController.php +++ b/src/Controller/PostController.php @@ -2,19 +2,84 @@ namespace App\Controller; +use App\Entity\Post; +use App\Form\PostType; use App\Repository\PostRepository; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; +use Symfony\Component\Security\Http\Attribute\IsGranted; +#[Route('/post')] class PostController extends AbstractController { - #[Route('/', name: 'app_posts')] - public function index(PostRepository $repository): Response + #[Route('/', name: 'app_post_index', methods: ['GET'])] + public function index(PostRepository $postRepository): Response { - $posts = $repository->findAll(); return $this->render('post/index.html.twig', [ - 'posts' => $posts, + 'posts' => $postRepository->findAll(), ]); } + + #[Route('/new', name: 'app_post_new', methods: ['GET', 'POST'])] + #[IsGranted('ROLE_USER')] + public function new(Request $request, EntityManagerInterface $entityManager): Response + { + $post = new Post(); + $form = $this->createForm(PostType::class, $post); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $entityManager->persist($post); + $entityManager->flush(); + + return $this->redirectToRoute('app_post_index', [], Response::HTTP_SEE_OTHER); + } + + return $this->render('post/new.html.twig', [ + 'post' => $post, + 'form' => $form, + ]); + } + + #[Route('/{id}', name: 'app_post_show', methods: ['GET'])] + public function show(Post $post): Response + { + return $this->render('post/show.html.twig', [ + 'post' => $post, + ]); + } + + #[Route('/{id}/edit', name: 'app_post_edit', methods: ['GET', 'POST'])] + #[IsGranted('ROLE_USER')] + public function edit(Request $request, Post $post, EntityManagerInterface $entityManager): Response + { + $form = $this->createForm(PostType::class, $post); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $entityManager->flush(); + + return $this->redirectToRoute('app_post_index', [], Response::HTTP_SEE_OTHER); + } + + return $this->render('post/edit.html.twig', [ + 'post' => $post, + 'form' => $form, + ]); + } + + #[Route('/{id}', name: 'app_post_delete', methods: ['POST'])] + #[IsGranted('ROLE_USER')] + public function delete(Request $request, Post $post, EntityManagerInterface $entityManager): Response + { + if ($this->isCsrfTokenValid('delete'.$post->getId(), (string) $request->getPayload()->get('_token'))) { + $entityManager->remove($post); + $entityManager->flush(); + } + + return $this->redirectToRoute('app_post_index', [], Response::HTTP_SEE_OTHER); + } } diff --git a/src/Controller/RegistrationController.php b/src/Controller/RegistrationController.php index 6bfc237..43043a9 100644 --- a/src/Controller/RegistrationController.php +++ b/src/Controller/RegistrationController.php @@ -34,7 +34,11 @@ class RegistrationController extends AbstractController // do anything else you need here, like send an email - return $this->redirectToRoute('_profiler_home'); + return $this->redirectToRoute('app_login'); + } + + if ($this->getUser()) { + return $this->redirectToRoute('app_posts'); } return $this->render('registration/register.html.twig', [ diff --git a/src/Controller/SpeciesController.php b/src/Controller/SpeciesController.php new file mode 100644 index 0000000..b63b960 --- /dev/null +++ b/src/Controller/SpeciesController.php @@ -0,0 +1,85 @@ +render('species/index.html.twig', [ + 'species' => $speciesRepository->findAll(), + ]); + } + + #[Route('/new', name: 'app_species_new', methods: ['GET', 'POST'])] + #[IsGranted('ROLE_USER')] + public function new(Request $request, EntityManagerInterface $entityManager): Response + { + $species = new Species(); + $form = $this->createForm(SpeciesType::class, $species); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $entityManager->persist($species); + $entityManager->flush(); + + return $this->redirectToRoute('app_species_index', [], Response::HTTP_SEE_OTHER); + } + + return $this->render('species/new.html.twig', [ + 'species' => $species, + 'form' => $form, + ]); + } + + #[Route('/{id}', name: 'app_species_show', methods: ['GET'])] + public function show(Species $species): Response + { + return $this->render('species/show.html.twig', [ + 'species' => $species, + ]); + } + + #[Route('/{id}/edit', name: 'app_species_edit', methods: ['GET', 'POST'])] + #[IsGranted('ROLE_USER')] + public function edit(Request $request, Species $species, EntityManagerInterface $entityManager): Response + { + $form = $this->createForm(SpeciesType::class, $species); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $entityManager->flush(); + + return $this->redirectToRoute('app_species_index', [], Response::HTTP_SEE_OTHER); + } + + return $this->render('species/edit.html.twig', [ + 'species' => $species, + 'form' => $form, + ]); + } + + #[Route('/{id}', name: 'app_species_delete', methods: ['POST'])] + #[IsGranted('ROLE_USER')] + public function delete(Request $request, Species $species, EntityManagerInterface $entityManager): Response + { + if ($this->isCsrfTokenValid('delete'.$species->getId(), (string) $request->getPayload()->get('_token'))) { + $entityManager->remove($species); + $entityManager->flush(); + } + + return $this->redirectToRoute('app_species_index', [], Response::HTTP_SEE_OTHER); + } +} diff --git a/src/DataFixtures/AppFixtures.php b/src/DataFixtures/AppFixtures.php index 12d5f40..3b45990 100644 --- a/src/DataFixtures/AppFixtures.php +++ b/src/DataFixtures/AppFixtures.php @@ -4,17 +4,29 @@ namespace App\DataFixtures; use App\Entity\Post; use App\Entity\Species; +use App\Entity\User; use DateTimeImmutable; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Persistence\ObjectManager; +use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; class AppFixtures extends Fixture { + public function __construct( + private readonly UserPasswordHasherInterface $passwordHasher + ) + { + } + public function load(ObjectManager $manager): void { + $user = (new User())->setEmail('test@test.fr'); + $user->setPassword($this->passwordHasher->hashPassword($user, 'password')); + $manager->persist($user); + $faker = \Faker\Factory::create(); for ($i = 0; $i < 20; ++$i) { - $name = $faker->text(); + $name = $faker->name(); $species = (new Species()) ->setScientificName($name) ->setVernacularName($name) diff --git a/src/Entity/Post.php b/src/Entity/Post.php index 17ce70c..58f13d2 100644 --- a/src/Entity/Post.php +++ b/src/Entity/Post.php @@ -5,8 +5,10 @@ namespace App\Entity; use App\Repository\PostRepository; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity(repositoryClass: PostRepository::class)] +#[ORM\HasLifecycleCallbacks] class Post { #[ORM\Id] @@ -15,21 +17,26 @@ class Post private ?int $id = null; #[ORM\Column] + #[Assert\NotBlank] private ?\DateTimeImmutable $foundDate = null; #[ORM\Column] private ?\DateTimeImmutable $publicationDate = null; #[ORM\Column(nullable: true)] + #[Assert\NotBlank] private ?float $latitude = null; #[ORM\Column(nullable: true)] + #[Assert\NotBlank] private ?float $longitude = null; #[ORM\Column(nullable: true)] + #[Assert\NotBlank] private ?float $altitude = null; #[ORM\Column(type: Types::TEXT)] + #[Assert\NotBlank] private ?string $commentary = null; #[ORM\ManyToOne(inversedBy: 'posts')] @@ -122,4 +129,12 @@ class Post return $this; } + + #[ORM\PrePersist] + public function setPublicationDateValue(): void + { + if ($this->publicationDate === null) { + $this->publicationDate = new \DateTimeImmutable(); + } + } } diff --git a/src/Entity/Species.php b/src/Entity/Species.php index 9243896..2dd9528 100644 --- a/src/Entity/Species.php +++ b/src/Entity/Species.php @@ -6,6 +6,7 @@ use App\Repository\SpeciesRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity(repositoryClass: SpeciesRepository::class)] class Species @@ -16,12 +17,15 @@ class Species private ?int $id = null; #[ORM\Column(length: 255)] + #[Assert\NotBlank] private ?string $scientific_name = null; #[ORM\Column(length: 255)] + #[Assert\NotBlank] private ?string $vernacular_name = null; #[ORM\Column(length: 255)] + #[Assert\NotBlank] private ?string $region = null; /** diff --git a/src/Form/PostType.php b/src/Form/PostType.php new file mode 100644 index 0000000..bea7e6f --- /dev/null +++ b/src/Form/PostType.php @@ -0,0 +1,38 @@ +add('foundDate', null, [ + 'widget' => 'single_text', + ]) + ->add('latitude') + ->add('longitude') + ->add('altitude') + ->add('commentary') + ->add('species', EntityType::class, [ + 'class' => Species::class, + 'choice_label' => 'scientific_name', + ]) + + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Post::class, + ]); + } +} diff --git a/src/Form/SpeciesType.php b/src/Form/SpeciesType.php new file mode 100644 index 0000000..ae3b919 --- /dev/null +++ b/src/Form/SpeciesType.php @@ -0,0 +1,27 @@ +add('scientific_name') + ->add('vernacular_name') + ->add('region') + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Species::class, + ]); + } +} diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index 4f2804e..e861224 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -33,6 +33,16 @@ class UserRepository extends ServiceEntityRepository implements PasswordUpgrader $this->getEntityManager()->flush(); } + public function findOneByEmail(string $email): ?User + { + return $this->createQueryBuilder('u') + ->andWhere('u.email = :email') + ->setParameter('email', $email) + ->getQuery() + ->getOneOrNullResult() + ; + } + // /** // * @return User[] Returns an array of User objects // */ diff --git a/templates/post/_delete_form.html.twig b/templates/post/_delete_form.html.twig new file mode 100644 index 0000000..1223c9b --- /dev/null +++ b/templates/post/_delete_form.html.twig @@ -0,0 +1,4 @@ +
+ + +
diff --git a/templates/post/_form.html.twig b/templates/post/_form.html.twig new file mode 100644 index 0000000..bf20b98 --- /dev/null +++ b/templates/post/_form.html.twig @@ -0,0 +1,4 @@ +{{ form_start(form) }} + {{ form_widget(form) }} + +{{ form_end(form) }} diff --git a/templates/post/edit.html.twig b/templates/post/edit.html.twig new file mode 100644 index 0000000..16b6b5f --- /dev/null +++ b/templates/post/edit.html.twig @@ -0,0 +1,13 @@ +{% extends 'base.html.twig' %} + +{% block title %}Edit Post{% endblock %} + +{% block body %} +

Edit Post

+ + {{ include('post/_form.html.twig', {'button_label': 'Update'}) }} + + back to list + + {{ include('post/_delete_form.html.twig') }} +{% endblock %} diff --git a/templates/post/index.html.twig b/templates/post/index.html.twig index 94f3756..49ca738 100644 --- a/templates/post/index.html.twig +++ b/templates/post/index.html.twig @@ -1,11 +1,45 @@ {% extends 'base.html.twig' %} -{% block title %}Posts!{% endblock %} +{% block title %}Post index{% endblock %} {% block body %} -{% for post in posts %} -
- #{{ post.id }} trouvé le {{ post.foundDate | date("d/m/Y \\à H \\h") }} -
-{% endfor %} +

Post index

+ + + + + + + + + + + + + + + + {% for post in posts %} + + + + + + + + + + + {% else %} + + + + {% endfor %} + +
IdFoundDatePublicationDateLatitudeLongitudeAltitudeCommentaryactions
{{ post.id }}{{ post.foundDate ? post.foundDate|date('Y-m-d H:i:s') : '' }}{{ post.publicationDate ? post.publicationDate|date('Y-m-d H:i:s') : '' }}{{ post.latitude }}{{ post.longitude }}{{ post.altitude }}{{ post.commentary }} + show + edit +
no records found
+ + Create new {% endblock %} diff --git a/templates/post/new.html.twig b/templates/post/new.html.twig new file mode 100644 index 0000000..b8bc236 --- /dev/null +++ b/templates/post/new.html.twig @@ -0,0 +1,11 @@ +{% extends 'base.html.twig' %} + +{% block title %}New Post{% endblock %} + +{% block body %} +

Create new Post

+ + {{ include('post/_form.html.twig') }} + + back to list +{% endblock %} diff --git a/templates/post/show.html.twig b/templates/post/show.html.twig new file mode 100644 index 0000000..a332dba --- /dev/null +++ b/templates/post/show.html.twig @@ -0,0 +1,46 @@ +{% extends 'base.html.twig' %} + +{% block title %}Post{% endblock %} + +{% block body %} +

Post

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Id{{ post.id }}
FoundDate{{ post.foundDate ? post.foundDate|date('Y-m-d H:i:s') : '' }}
PublicationDate{{ post.publicationDate ? post.publicationDate|date('Y-m-d H:i:s') : '' }}
Latitude{{ post.latitude }}
Longitude{{ post.longitude }}
Altitude{{ post.altitude }}
Commentary{{ post.commentary }}
+ + back to list + + edit + + {{ include('post/_delete_form.html.twig') }} +{% endblock %} diff --git a/templates/species/_delete_form.html.twig b/templates/species/_delete_form.html.twig new file mode 100644 index 0000000..9e7c05a --- /dev/null +++ b/templates/species/_delete_form.html.twig @@ -0,0 +1,4 @@ +
+ + +
diff --git a/templates/species/_form.html.twig b/templates/species/_form.html.twig new file mode 100644 index 0000000..bf20b98 --- /dev/null +++ b/templates/species/_form.html.twig @@ -0,0 +1,4 @@ +{{ form_start(form) }} + {{ form_widget(form) }} + +{{ form_end(form) }} diff --git a/templates/species/edit.html.twig b/templates/species/edit.html.twig new file mode 100644 index 0000000..8e4401b --- /dev/null +++ b/templates/species/edit.html.twig @@ -0,0 +1,13 @@ +{% extends 'base.html.twig' %} + +{% block title %}Edit Species{% endblock %} + +{% block body %} +

Edit Species

+ + {{ include('species/_form.html.twig', {'button_label': 'Update'}) }} + + back to list + + {{ include('species/_delete_form.html.twig') }} +{% endblock %} diff --git a/templates/species/index.html.twig b/templates/species/index.html.twig new file mode 100644 index 0000000..39c0d06 --- /dev/null +++ b/templates/species/index.html.twig @@ -0,0 +1,39 @@ +{% extends 'base.html.twig' %} + +{% block title %}Species index{% endblock %} + +{% block body %} +

Species index

+ + + + + + + + + + + + + {% for species in species %} + + + + + + + + {% else %} + + + + {% endfor %} + +
IdScientific_nameVernacular_nameRegionactions
{{ species.id }}{{ species.scientificName }}{{ species.vernacularName }}{{ species.region }} + show + edit +
no records found
+ + Create new +{% endblock %} diff --git a/templates/species/new.html.twig b/templates/species/new.html.twig new file mode 100644 index 0000000..8e58597 --- /dev/null +++ b/templates/species/new.html.twig @@ -0,0 +1,11 @@ +{% extends 'base.html.twig' %} + +{% block title %}New Species{% endblock %} + +{% block body %} +

Create new Species

+ + {{ include('species/_form.html.twig') }} + + back to list +{% endblock %} diff --git a/templates/species/show.html.twig b/templates/species/show.html.twig new file mode 100644 index 0000000..d0b5a78 --- /dev/null +++ b/templates/species/show.html.twig @@ -0,0 +1,34 @@ +{% extends 'base.html.twig' %} + +{% block title %}Species{% endblock %} + +{% block body %} +

Species

+ + + + + + + + + + + + + + + + + + + + +
Id{{ species.id }}
Scientific_name{{ species.scientificName }}
Vernacular_name{{ species.vernacularName }}
Region{{ species.region }}
+ + back to list + + edit + + {{ include('species/_delete_form.html.twig') }} +{% endblock %} diff --git a/tests/Controller/PostControllerTest.php b/tests/Controller/PostControllerTest.php new file mode 100644 index 0000000..ea52747 --- /dev/null +++ b/tests/Controller/PostControllerTest.php @@ -0,0 +1,128 @@ +client = static::createClient(); + /** @var EntityManagerInterface $manager */ + $manager = static::getContainer()->get(EntityManagerInterface::class); + $this->manager = $manager; + $this->repository = $this->manager->getRepository(Post::class); + + foreach ($this->repository->findAll() as $object) { + $this->manager->remove($object); + } + + $this->manager->flush(); + + $userRepository = $this->manager->getRepository(User::class); + /** @var User $user */ + $user = $userRepository->findOneByEmail('test@test.fr'); + $this->client->loginUser($user); + $this->client->request('GET', sprintf('%snew', $this->path)); + } + + public function testIndex(): void + { + $crawler = $this->client->request('GET', $this->path); + + self::assertResponseStatusCodeSame(200); + self::assertPageTitleContains('Post index'); + + // Use the $crawler to perform additional assertions e.g. + // self::assertSame('Some text on the page', $crawler->filter('.p')->first()); + } + + public function testNew(): void + { + self::assertResponseStatusCodeSame(200); + + $this->client->submitForm('Save', [ + 'post[foundDate]' => '2024-01-01 00:00:00', + 'post[latitude]' => '45.0', + 'post[longitude]' => '45.0', + 'post[altitude]' => '500.0', + 'post[commentary]' => 'Testing', + ]); + + self::assertResponseRedirects($this->path); + + self::assertSame(1, $this->repository->count()); + } + + public function testShow(): void + { + $fixture = new Post(); + $fixture->setFoundDate(new \DateTimeImmutable('2024-01-01 00:00:00')); + $fixture->setCommentary('Cool stuff'); + + $this->manager->persist($fixture); + $this->manager->flush(); + + $this->client->request('GET', sprintf('%s%s', $this->path, $fixture->getId())); + + self::assertResponseStatusCodeSame(200); + self::assertSelectorTextContains('h1', 'Post'); + } + + public function testEdit(): void + { + $fixture = new Post(); + $fixture->setFoundDate(new \DateTimeImmutable('2024-01-01 00:00:00')); + $fixture->setCommentary('Cool stuff'); + + $this->manager->persist($fixture); + $this->manager->flush(); + + $this->client->request('GET', sprintf('%s%s/edit', $this->path, $fixture->getId())); + + $this->client->submitForm('Update', [ + 'post[foundDate]' => '2024-03-25 00:00:00', + 'post[latitude]' => '90', + 'post[longitude]' => '90', + 'post[altitude]' => '200', + 'post[commentary]' => 'Something New', + ]); + + self::assertResponseRedirects('/post/'); + + $fixture = $this->repository->findAll(); + + self::assertEquals(new \DateTimeImmutable('2024-03-25 00:00:00'), $fixture[0]->getFoundDate()); + self::assertSame(90., $fixture[0]->getLatitude()); + self::assertSame(90., $fixture[0]->getLongitude()); + self::assertSame(200., $fixture[0]->getAltitude()); + self::assertSame('Something New', $fixture[0]->getCommentary()); + } + + public function testRemove(): void + { + $fixture = new Post(); + $fixture->setFoundDate(new \DateTimeImmutable('2024-01-01 00:00:00')); + $fixture->setCommentary('Cool stuff'); + + $this->manager->persist($fixture); + $this->manager->flush(); + + $this->client->request('GET', sprintf('%s%s', $this->path, $fixture->getId())); + $this->client->submitForm('Delete'); + + self::assertResponseRedirects('/post/'); + self::assertSame(0, $this->repository->count()); + } +} diff --git a/tests/Controller/SpeciesControllerTest.php b/tests/Controller/SpeciesControllerTest.php new file mode 100644 index 0000000..5ce80dd --- /dev/null +++ b/tests/Controller/SpeciesControllerTest.php @@ -0,0 +1,129 @@ +client = static::createClient(); + /** @var EntityManagerInterface $manager */ + $manager = static::getContainer()->get(EntityManagerInterface::class); + $this->manager = $manager; + $this->repository = $this->manager->getRepository(Species::class); + + foreach ($this->repository->findAll() as $object) { + $this->manager->remove($object); + } + + $this->manager->flush(); + + $userRepository = $this->manager->getRepository(User::class); + /** @var User $user */ + $user = $userRepository->findOneByEmail('test@test.fr'); + $this->client->loginUser($user); + $this->client->request('GET', sprintf('%snew', $this->path)); + } + + public function testIndex(): void + { + $crawler = $this->client->request('GET', $this->path); + + self::assertResponseStatusCodeSame(200); + self::assertPageTitleContains('Species index'); + + // Use the $crawler to perform additional assertions e.g. + // self::assertSame('Some text on the page', $crawler->filter('.p')->first()); + } + + public function testNew(): void + { + $this->client->request('GET', sprintf('%snew', $this->path)); + + self::assertResponseStatusCodeSame(200); + + $this->client->submitForm('Save', [ + 'species[scientific_name]' => 'Testing', + 'species[vernacular_name]' => 'Testing', + 'species[region]' => 'Testing', + ]); + + self::assertResponseRedirects($this->path); + + self::assertSame(1, $this->repository->count([])); + } + + public function testShow(): void + { + $fixture = new Species(); + $fixture->setScientificName('My Title'); + $fixture->setVernacularName('My Title'); + $fixture->setRegion('My Title'); + + $this->manager->persist($fixture); + $this->manager->flush(); + + $this->client->request('GET', sprintf('%s%s', $this->path, $fixture->getId())); + + self::assertResponseStatusCodeSame(200); + self::assertPageTitleContains('Species'); + + // Use assertions to check that the properties are properly displayed. + } + + public function testEdit(): void + { + $fixture = new Species(); + $fixture->setScientificName('Value'); + $fixture->setVernacularName('Value'); + $fixture->setRegion('Value'); + + $this->manager->persist($fixture); + $this->manager->flush(); + + $this->client->request('GET', sprintf('%s%s/edit', $this->path, $fixture->getId())); + + $this->client->submitForm('Update', [ + 'species[scientific_name]' => 'Something New', + 'species[vernacular_name]' => 'Something New', + 'species[region]' => 'Something New', + ]); + + self::assertResponseRedirects('/species/'); + + $fixture = $this->repository->findAll(); + + self::assertSame('Something New', $fixture[0]->getScientificName()); + self::assertSame('Something New', $fixture[0]->getVernacularName()); + self::assertSame('Something New', $fixture[0]->getRegion()); + } + + public function testRemove(): void + { + $fixture = new Species(); + $fixture->setScientificName('Value'); + $fixture->setVernacularName('Value'); + $fixture->setRegion('Value'); + + $this->manager->persist($fixture); + $this->manager->flush(); + + $this->client->request('GET', sprintf('%s%s', $this->path, $fixture->getId())); + $this->client->submitForm('Delete'); + + self::assertResponseRedirects('/species/'); + self::assertSame(0, $this->repository->count([])); + } +}