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();
+ }
+
+}