diff --git a/.gitignore b/.gitignore index bc43c21..a05046b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ ###< symfony/phpunit-bridge ### .idea +/codecoverage diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 0bd20c8..6504cd5 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -24,6 +24,9 @@ src + + src/Kernel.php + diff --git a/src/Controller/CarController.php b/src/Controller/CarController.php new file mode 100644 index 0000000..9d083ba --- /dev/null +++ b/src/Controller/CarController.php @@ -0,0 +1,75 @@ +carMakeRepository = $carMakeRepository; + $this->carRepository = $carRepository; + } + + /** + * @Route("/", name="home") + */ + public function index(): Response + { + $makeList = $this->carMakeRepository->findAll(); + + return $this->render('home.html.twig', [ + 'makeList' => $makeList, + ]); + } + + /** + * @Route("/make/{makeId}", name="make") + */ + public function make(int $makeId): Response + { + $make = $this->carMakeRepository->find($makeId); + + if (!$make instanceof CarMake) { + throw $this->createNotFoundException('The make does not exist'); + } + + return $this->render('make.html.twig', [ + 'make' => $make, + ]); + } + + /** + * @Route("/car/{carId}", name="car") + */ + public function car(int $carId): Response + { + $car = $this->carRepository->find($carId); + if (!$car instanceof Car) { + throw $this->createNotFoundException('The car does not exist'); + } + + return $this->render('car.html.twig', [ + 'car' => $car, + ]); + } + +} diff --git a/templates/car.html.twig b/templates/car.html.twig new file mode 100644 index 0000000..0b36de1 --- /dev/null +++ b/templates/car.html.twig @@ -0,0 +1,11 @@ +{% extends 'base.html.twig' %} + +{% block title %}Detail{% endblock %} + +{% block body %} + +

{{ car.model }}

+

{{ car.make.name }}

+

{{ car.description }}

+ +{% endblock %} diff --git a/templates/home.html.twig b/templates/home.html.twig new file mode 100644 index 0000000..f86d17d --- /dev/null +++ b/templates/home.html.twig @@ -0,0 +1,15 @@ +{% extends 'base.html.twig' %} + +{% block title %}Start{% endblock %} + +{% block body %} + +

Car

+ + + +{% endblock %} diff --git a/templates/make.html.twig b/templates/make.html.twig new file mode 100644 index 0000000..211135b --- /dev/null +++ b/templates/make.html.twig @@ -0,0 +1,15 @@ +{% extends 'base.html.twig' %} + +{% block title %}List{% endblock %} + +{% block body %} + +

{{ make.name }}

+ + + +{% endblock %} diff --git a/tests/Acceptance/Controller/CarControllerTest.php b/tests/Acceptance/Controller/CarControllerTest.php new file mode 100644 index 0000000..f0f3a46 --- /dev/null +++ b/tests/Acceptance/Controller/CarControllerTest.php @@ -0,0 +1,186 @@ +client = self::createClient(); + + $this->entityManager = $this->client->getContainer() + ->get('doctrine') + ->getManager(); + } + + protected function tearDown(): void + { + parent::tearDown(); + + $connection = $this->entityManager->getConnection(); + + $connection->executeUpdate('DELETE FROM car'); + $connection->executeUpdate('ALTER TABLE car AUTO_INCREMENT=0'); + $connection->executeUpdate('DELETE FROM car_make'); + $connection->executeUpdate('ALTER TABLE car_make AUTO_INCREMENT=0'); + + $this->entityManager = null; + } + + public function testHomePage() + { + $this->createData(); + $crawler = $this->client->request( + 'GET', + '/' + ); + self::assertResponseStatusCodeSame(200); + self::assertSelectorTextContains('h1', 'Car'); + + $makeList = $crawler->filter('ul.car > li > a'); + + self::assertCount(2, $makeList); + + $bmwInfo = $makeList->getNode(0); + self::assertSame('BMW', $bmwInfo->nodeValue); + self::assertSame('http://localhost/make/1', $bmwInfo->attributes->item(0)->nodeValue); + + $audiInfo = $makeList->getNode(1); + self::assertSame('Audi', $audiInfo->nodeValue); + self::assertSame('http://localhost/make/2', $audiInfo->attributes->item(0)->nodeValue); + } + + public function testMakeBmwPage() + { + $this->createData(); + $crawler = $this->client->request( + 'GET', + '/make/1' + ); + self::assertResponseStatusCodeSame(200); + self::assertSelectorTextContains('h1', 'BMW'); + + $makeList = $crawler->filter('ul.car > li > a'); + + self::assertCount(1, $makeList); + + $bmwInfo = $makeList->getNode(0); + self::assertSame('6 Series', $bmwInfo->nodeValue); + self::assertSame('http://localhost/car/1', $bmwInfo->attributes->item(0)->nodeValue); + } + + public function testMakeAudiPage() + { + $this->createData(); + $crawler = $this->client->request( + 'GET', + '/make/2' + ); + self::assertResponseStatusCodeSame(200); + self::assertSelectorTextContains('h1', 'Audi'); + + $makeList = $crawler->filter('ul.car > li > a'); + + self::assertCount(3, $makeList); + + $bmwInfo = $makeList->getNode(0); + self::assertSame('TT', $bmwInfo->nodeValue); + self::assertSame('http://localhost/car/2', $bmwInfo->attributes->item(0)->nodeValue); + + $bmwInfo = $makeList->getNode(1); + self::assertSame('A8', $bmwInfo->nodeValue); + self::assertSame('http://localhost/car/3', $bmwInfo->attributes->item(0)->nodeValue); + + $bmwInfo = $makeList->getNode(2); + self::assertSame('S4', $bmwInfo->nodeValue); + self::assertSame('http://localhost/car/4', $bmwInfo->attributes->item(0)->nodeValue); + } + + public function testMakeNotFound() + { + $this->client->request( + 'GET', + '/make/99' + ); + self::assertResponseStatusCodeSame(404); + } + + public function testAudiTTCarPage() + { + $this->createData(); + $this->client->request( + 'GET', + '/car/2' + ); + self::assertResponseStatusCodeSame(200); + self::assertSelectorTextContains('h1', 'TT'); + self::assertSelectorTextContains('h2', 'Audi'); + self::assertSelectorTextContains('h3', 'id luctus nec molestie sed justo'); + } + + public function testCarPageWhenCarNotFound() + { + $this->client->request( + 'GET', + '/car/99' + ); + self::assertResponseStatusCodeSame(404); + } + + + private function createData() + { + $data = [ + 'BMW' => + [ + [ + 'model' => '6 Series', + 'desc' => 'id luctus nec molestie sed justo ', + ], + ], + 'Audi' => + [ + [ + 'model' => 'TT', + 'desc' => 'id luctus nec molestie sed justo', + ], + [ + 'model' => 'A8', + 'desc' => 'dictumst morbi vestibulum velit id pretium iaculis diam erat fermentum', + ], + [ + 'model' => 'S4', + 'desc' => 'volutpat dui maecenas tristique est', + ], + ], + ]; + + foreach ($data as $make => $modelList) { + $carMake = new CarMake(); + $carMake->setName($make); + foreach ($modelList as $model) { + $car = new Car(); + $car->setModel($model['model']); + $car->setDescription($model['desc']); + + $carMake->addCar($car); + $this->entityManager->persist($car); + } + $this->entityManager->persist($carMake); + } + + $this->entityManager->flush(); + } + +}