From 84eba7980e267898e6a1d589a0471184e018d72d Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Tue, 6 Sep 2022 08:37:27 -0300 Subject: [PATCH 01/54] antes de mudar config doctrine --- app/Entities/Subjects.php | 42 ++++++++++++++++++++++++++ app/Repositorys/SubjectsRepository.php | 30 ++++++++++++++++++ cli-config.php | 0 composer.json | 10 +++--- composer.lock | 24 +++++++-------- config/database.php | 4 +-- config/doctrine.php | 2 +- storage/database.sqlite | 0 8 files changed, 92 insertions(+), 20 deletions(-) create mode 100644 app/Entities/Subjects.php create mode 100644 app/Repositorys/SubjectsRepository.php create mode 100644 cli-config.php create mode 100755 storage/database.sqlite diff --git a/app/Entities/Subjects.php b/app/Entities/Subjects.php new file mode 100644 index 0000000..7429094 --- /dev/null +++ b/app/Entities/Subjects.php @@ -0,0 +1,42 @@ +setName($input['name']); + } + + protected function getSubject() + { + return $this->id; + } + + protected function getName() + { + return $this->name; + } +} \ No newline at end of file diff --git a/app/Repositorys/SubjectsRepository.php b/app/Repositorys/SubjectsRepository.php new file mode 100644 index 0000000..5d35cbb --- /dev/null +++ b/app/Repositorys/SubjectsRepository.php @@ -0,0 +1,30 @@ +entityManager = $entityManager; + } + + public function create(Request $request) + { + $subject = $this->prepareData($request); + + $this->entityManager->persist($subject); + $this->entityManager->flush(); + } + + +} \ No newline at end of file diff --git a/cli-config.php b/cli-config.php new file mode 100644 index 0000000..e69de29 diff --git a/composer.json b/composer.json index ea5c347..6ff8fc2 100644 --- a/composer.json +++ b/composer.json @@ -6,15 +6,15 @@ "license": "MIT", "require": { "php": "^8.0.2", - "guzzlehttp/guzzle": "^7.2", - "laravel/framework": "^9.19", - "laravel/sanctum": "^3.0", - "laravel/tinker": "^2.7", "beberlei/doctrineextensions": "^1.3", "doctrine/migrations": "3.4", "gedmo/doctrine-extensions": "^3.8", + "guzzlehttp/guzzle": "^7.2", "laravel-doctrine/extensions": "^1.5", - "laravel-doctrine/orm": "^1.8" + "laravel-doctrine/orm": "^1.8", + "laravel/framework": "^9.19", + "laravel/sanctum": "^3.0", + "laravel/tinker": "^2.7" }, "require-dev": { "fakerphp/faker": "^1.9.1", diff --git a/composer.lock b/composer.lock index d709c91..e7f4068 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": "95e55251f226d85834d17a2bb30f70a9", + "content-hash": "f13b6b3c91ced1175ae506aee177139e", "packages": [ { "name": "beberlei/doctrineextensions", @@ -3190,16 +3190,16 @@ }, { "name": "nesbot/carbon", - "version": "2.62.0", + "version": "2.62.1", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "7507aec3d626797ce2123cf6c6556683be22b5f8" + "reference": "01bc4cdefe98ef58d1f9cb31bdbbddddf2a88f7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7507aec3d626797ce2123cf6c6556683be22b5f8", - "reference": "7507aec3d626797ce2123cf6c6556683be22b5f8", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/01bc4cdefe98ef58d1f9cb31bdbbddddf2a88f7a", + "reference": "01bc4cdefe98ef58d1f9cb31bdbbddddf2a88f7a", "shasum": "" }, "require": { @@ -3288,7 +3288,7 @@ "type": "tidelift" } ], - "time": "2022-08-28T19:48:05+00:00" + "time": "2022-09-02T07:48:13+00:00" }, { "name": "nette/schema", @@ -3439,16 +3439,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.14.0", + "version": "v4.15.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", "shasum": "" }, "require": { @@ -3489,9 +3489,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" }, - "time": "2022-05-31T20:59:12+00:00" + "time": "2022-09-04T07:30:47+00:00" }, { "name": "nunomaduro/termwind", diff --git a/config/database.php b/config/database.php index 137ad18..3803f93 100644 --- a/config/database.php +++ b/config/database.php @@ -15,7 +15,7 @@ | */ - 'default' => env('DB_CONNECTION', 'mysql'), + 'default' => 'sqlite', /* |-------------------------------------------------------------------------- @@ -36,7 +36,7 @@ 'connections' => [ 'sqlite' => [ - 'driver' => 'sqlite', + 'driver' => 'pdo_sqlite', 'url' => env('DATABASE_URL'), 'database' => env('DB_DATABASE', database_path('database.sqlite')), 'prefix' => '', diff --git a/config/doctrine.php b/config/doctrine.php index 0d60b60..cea1778 100644 --- a/config/doctrine.php +++ b/config/doctrine.php @@ -31,7 +31,7 @@ 'connection' => env('DB_CONNECTION', 'mysql'), 'namespaces' => [], 'paths' => [ - base_path('app/Packages') + base_path('app/Entities') ], 'repository' => Doctrine\ORM\EntityRepository::class, 'proxies' => [ diff --git a/storage/database.sqlite b/storage/database.sqlite new file mode 100755 index 0000000..e69de29 From 4b7b5823b149cea274792d453ecf337a8603c360 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Tue, 6 Sep 2022 15:18:45 -0300 Subject: [PATCH 02/54] restaura config app e database para padrao --- config/app.php | 2 +- config/database.php | 7 +++---- teste.php | 1 + 3 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 teste.php diff --git a/config/app.php b/config/app.php index 687d31b..547e629 100644 --- a/config/app.php +++ b/config/app.php @@ -217,4 +217,4 @@ // 'ExampleClass' => App\Example\ExampleClass::class, ])->toArray(), -]; +]; \ No newline at end of file diff --git a/config/database.php b/config/database.php index 3803f93..6dd3670 100644 --- a/config/database.php +++ b/config/database.php @@ -15,7 +15,7 @@ | */ - 'default' => 'sqlite', + 'default' => env('DB_CONNECTION', 'mysql'), /* |-------------------------------------------------------------------------- @@ -36,7 +36,7 @@ 'connections' => [ 'sqlite' => [ - 'driver' => 'pdo_sqlite', + 'driver' => 'sqlite', 'url' => env('DATABASE_URL'), 'database' => env('DB_DATABASE', database_path('database.sqlite')), 'prefix' => '', @@ -147,5 +147,4 @@ ], ], - -]; +]; \ No newline at end of file diff --git a/teste.php b/teste.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/teste.php @@ -0,0 +1 @@ + Date: Sun, 11 Sep 2022 13:00:19 -0300 Subject: [PATCH 03/54] Adiciona rota de criacao, e delete de materias. Juntamente com boilerplate de Repositorys --- app/Entities/Subjects.php | 42 ---------------- app/Http/Controllers/SubjectController.php | 43 ++++++++++++++++ app/Http/Middleware/VerifyCsrfToken.php | 3 +- app/Models/Subject.php | 40 +++++++++++++++ app/Repositorys/Interfaces/ISubject.php | 14 ++++++ app/Repositorys/SubjectRepository.php | 57 ++++++++++++++++++++++ app/Repositorys/SubjectsRepository.php | 30 ------------ composer.lock | 38 +++++++-------- config/doctrine.php | 4 +- routes/web.php | 7 +-- teste.php | 1 - 11 files changed, 181 insertions(+), 98 deletions(-) delete mode 100644 app/Entities/Subjects.php create mode 100644 app/Http/Controllers/SubjectController.php create mode 100644 app/Models/Subject.php create mode 100644 app/Repositorys/Interfaces/ISubject.php create mode 100644 app/Repositorys/SubjectRepository.php delete mode 100644 app/Repositorys/SubjectsRepository.php delete mode 100644 teste.php diff --git a/app/Entities/Subjects.php b/app/Entities/Subjects.php deleted file mode 100644 index 7429094..0000000 --- a/app/Entities/Subjects.php +++ /dev/null @@ -1,42 +0,0 @@ -setName($input['name']); - } - - protected function getSubject() - { - return $this->id; - } - - protected function getName() - { - return $this->name; - } -} \ No newline at end of file diff --git a/app/Http/Controllers/SubjectController.php b/app/Http/Controllers/SubjectController.php new file mode 100644 index 0000000..0b137ae --- /dev/null +++ b/app/Http/Controllers/SubjectController.php @@ -0,0 +1,43 @@ +subjects = $subjects; + } + + public function store(Request $request): JsonResponse + { + $this->subjects->create($request); + + return response()->json(['message' => 'Subject ' . $request->get('name') . ' created successfully']); + } + + public function remove(Request $request): JsonResponse + { + $subjectToDelete = $this->subjects->getById($request->get('id')); + + $this->subjects->remove($subjectToDelete); + + return response()->json(['message' => 'Subject ' . $request->get('name') . ' deleted successfully']); + } + + + public function index() + { + $subjects = $this->subjects->getAll(); + + return response()->json($subjects); + } +} \ No newline at end of file diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 9e86521..5d46c4c 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -12,6 +12,7 @@ class VerifyCsrfToken extends Middleware * @var array */ protected $except = [ - // + '/subject/create', + '/subject/remove', ]; } diff --git a/app/Models/Subject.php b/app/Models/Subject.php new file mode 100644 index 0000000..3c5ac79 --- /dev/null +++ b/app/Models/Subject.php @@ -0,0 +1,40 @@ +setName($input['name']); + } + + protected function getSubject(): int + { + return $this->id; + } + + protected function getSubjectName(): string + { + return $this->name; + } + + protected function setName(string $name): void + { + $this->name = $name; + } +} \ No newline at end of file diff --git a/app/Repositorys/Interfaces/ISubject.php b/app/Repositorys/Interfaces/ISubject.php new file mode 100644 index 0000000..2d1cd72 --- /dev/null +++ b/app/Repositorys/Interfaces/ISubject.php @@ -0,0 +1,14 @@ +entityManager = $entityManager; + } + + public function create(Request $request) + { + $subject = $this->prepareData($request); + + $this->entityManager->persist($subject); + $this->entityManager->flush(); + } + + public function remove(Subject $subject) + { + try { + $this->entityManager->remove($subject); + + $this->entityManager->flush(); + + }catch (\Exception $e) { + throw new \Exception($e->getMessage()); + } + } + + public function getAll() : array + { + return $this->entityManager->getRepository( + Subject::class ) + ->findAll(); + } + + private function prepareData(Request $request) + { + return new Subject($request); + } + + public function getById(string $id) + { + return $this->entityManager->getRepository( + Subject::class) + ->findOneBy(['id' => $id]); + } +} \ No newline at end of file diff --git a/app/Repositorys/SubjectsRepository.php b/app/Repositorys/SubjectsRepository.php deleted file mode 100644 index 5d35cbb..0000000 --- a/app/Repositorys/SubjectsRepository.php +++ /dev/null @@ -1,30 +0,0 @@ -entityManager = $entityManager; - } - - public function create(Request $request) - { - $subject = $this->prepareData($request); - - $this->entityManager->persist($subject); - $this->entityManager->flush(); - } - - -} \ No newline at end of file diff --git a/composer.lock b/composer.lock index e7f4068..2a816e3 100644 --- a/composer.lock +++ b/composer.lock @@ -2381,16 +2381,16 @@ }, { "name": "laravel/framework", - "version": "v9.27.0", + "version": "v9.28.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "27572f45120fd3977d92651a71d8c711a9aaa790" + "reference": "396a89e1f3654123d1c7f56306051212e5c75bc0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/27572f45120fd3977d92651a71d8c711a9aaa790", - "reference": "27572f45120fd3977d92651a71d8c711a9aaa790", + "url": "https://api.github.com/repos/laravel/framework/zipball/396a89e1f3654123d1c7f56306051212e5c75bc0", + "reference": "396a89e1f3654123d1c7f56306051212e5c75bc0", "shasum": "" }, "require": { @@ -2557,7 +2557,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-08-30T13:34:43+00:00" + "time": "2022-09-06T14:57:01+00:00" }, { "name": "laravel/sanctum", @@ -7453,16 +7453,16 @@ }, { "name": "laravel/pint", - "version": "v1.1.2", + "version": "v1.1.3", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "ebfe95b446e4395eba1eefb8615214fb55163165" + "reference": "9fb8e93074de3c04a0975beb90dcb38562afbdaa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/ebfe95b446e4395eba1eefb8615214fb55163165", - "reference": "ebfe95b446e4395eba1eefb8615214fb55163165", + "url": "https://api.github.com/repos/laravel/pint/zipball/9fb8e93074de3c04a0975beb90dcb38562afbdaa", + "reference": "9fb8e93074de3c04a0975beb90dcb38562afbdaa", "shasum": "" }, "require": { @@ -7473,13 +7473,13 @@ "php": "^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.10.0", - "illuminate/view": "^9.26.0", + "friendsofphp/php-cs-fixer": "^3.11.0", + "illuminate/view": "^9.27", "laravel-zero/framework": "^9.1.3", "mockery/mockery": "^1.5.0", - "nunomaduro/larastan": "^2.1.12", + "nunomaduro/larastan": "^2.2", "nunomaduro/termwind": "^1.14.0", - "pestphp/pest": "^1.22.0" + "pestphp/pest": "^1.22.1" }, "bin": [ "builds/pint" @@ -7515,20 +7515,20 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2022-08-30T15:28:20+00:00" + "time": "2022-09-06T16:01:44+00:00" }, { "name": "laravel/sail", - "version": "v1.15.4", + "version": "v1.16.0", "source": { "type": "git", "url": "https://github.com/laravel/sail.git", - "reference": "853dea1fa866a52a93beccc4e5affdc49b98e7d5" + "reference": "73030c18b769f27e6f6aacf7848d024fa9a55560" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sail/zipball/853dea1fa866a52a93beccc4e5affdc49b98e7d5", - "reference": "853dea1fa866a52a93beccc4e5affdc49b98e7d5", + "url": "https://api.github.com/repos/laravel/sail/zipball/73030c18b769f27e6f6aacf7848d024fa9a55560", + "reference": "73030c18b769f27e6f6aacf7848d024fa9a55560", "shasum": "" }, "require": { @@ -7575,7 +7575,7 @@ "issues": "https://github.com/laravel/sail/issues", "source": "https://github.com/laravel/sail" }, - "time": "2022-08-17T13:17:15+00:00" + "time": "2022-08-31T16:38:14+00:00" }, { "name": "mockery/mockery", diff --git a/config/doctrine.php b/config/doctrine.php index cea1778..c9b7880 100644 --- a/config/doctrine.php +++ b/config/doctrine.php @@ -27,11 +27,11 @@ 'managers' => [ 'default' => [ 'dev' => env('APP_DEBUG', false), - 'meta' => env('DOCTRINE_METADATA', 'annotations'), + 'meta' => env('DOCTRINE_METADATA', 'attributes'), 'connection' => env('DB_CONNECTION', 'mysql'), 'namespaces' => [], 'paths' => [ - base_path('app/Entities') + base_path('app/Models') ], 'repository' => Doctrine\ORM\EntityRepository::class, 'proxies' => [ diff --git a/routes/web.php b/routes/web.php index b130397..cbfd594 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,5 +1,6 @@ Date: Sun, 11 Sep 2022 14:03:38 -0300 Subject: [PATCH 04/54] adiciona rota para criar, procurar e deletar estudantes. Bem como repository, model e controller --- app/Http/Controllers/StudentController.php | 43 ++++++++++++++++ app/Http/Middleware/VerifyCsrfToken.php | 3 +- app/Models/Student.php | 40 +++++++++++++++ app/Repositorys/Interfaces/IStudent.php | 14 ++++++ app/Repositorys/Interfaces/ISubject.php | 4 +- app/Repositorys/StudentRepository.php | 58 ++++++++++++++++++++++ app/Repositorys/SubjectRepository.php | 10 ++-- routes/web.php | 5 ++ 8 files changed, 168 insertions(+), 9 deletions(-) create mode 100644 app/Http/Controllers/StudentController.php create mode 100644 app/Models/Student.php create mode 100644 app/Repositorys/Interfaces/IStudent.php create mode 100644 app/Repositorys/StudentRepository.php diff --git a/app/Http/Controllers/StudentController.php b/app/Http/Controllers/StudentController.php new file mode 100644 index 0000000..fe67cbd --- /dev/null +++ b/app/Http/Controllers/StudentController.php @@ -0,0 +1,43 @@ +student = $student; + } + + public function store(Request $request): JsonResponse + { + $this->student->create($request); + + return response()->json(['message' => 'The student ' . $request->get('name') . ' are created successfully']); + } + + public function remove(Request $request): JsonResponse + { + $studentToDelete = $this->student->getById($request->get('id')); + + $this->student->remove($studentToDelete); + + return response()->json(['message' => 'The student ' . $request->get('name') . ' are deleted successfully']); + } + + + public function index() + { + $student = $this->student->getAll(); + + return response()->json($student); + } +} \ No newline at end of file diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 5d46c4c..4643b32 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -12,7 +12,6 @@ class VerifyCsrfToken extends Middleware * @var array */ protected $except = [ - '/subject/create', - '/subject/remove', + '/*', ]; } diff --git a/app/Models/Student.php b/app/Models/Student.php new file mode 100644 index 0000000..37fd28a --- /dev/null +++ b/app/Models/Student.php @@ -0,0 +1,40 @@ +setName($input['name']); + } + + protected function getStudent(): int + { + return $this->id; + } + + protected function getStudentName(): string + { + return $this->name; + } + + protected function setName(string $name): void + { + $this->name = $name; + } +} \ No newline at end of file diff --git a/app/Repositorys/Interfaces/IStudent.php b/app/Repositorys/Interfaces/IStudent.php new file mode 100644 index 0000000..5b9b718 --- /dev/null +++ b/app/Repositorys/Interfaces/IStudent.php @@ -0,0 +1,14 @@ +entityManager = $entityManager; + } + + public function create(Request $request) + { + $student = $this->prepareData($request); + + $this->entityManager->persist($student); + $this->entityManager->flush(); + } + + public function remove(Student $student) + { + try { + $this->entityManager->remove($student); + + $this->entityManager->flush(); + + }catch (\Exception $e) { + throw new \Exception($e->getMessage()); + } + } + + public function getAll() : array + { + return $this->entityManager->getRepository( + Student::class ) + ->findAll(); + } + + private function prepareData(Request $request) + { + return new Student($request); + } + + public function getById(string $id) + { + return $this->entityManager->getRepository( + Student::class) + ->findOneBy(['id' => $id]); + } +} \ No newline at end of file diff --git a/app/Repositorys/SubjectRepository.php b/app/Repositorys/SubjectRepository.php index 6595ebc..6202547 100644 --- a/app/Repositorys/SubjectRepository.php +++ b/app/Repositorys/SubjectRepository.php @@ -2,7 +2,7 @@ namespace App\Repositorys; -use App\Models\Subject; +use App\Models\Student; use App\Repositorys\Interfaces\ISubject; use Doctrine\ORM\EntityManager; use Illuminate\Http\Request; @@ -24,7 +24,7 @@ public function create(Request $request) $this->entityManager->flush(); } - public function remove(Subject $subject) + public function remove(Student $subject) { try { $this->entityManager->remove($subject); @@ -39,19 +39,19 @@ public function remove(Subject $subject) public function getAll() : array { return $this->entityManager->getRepository( - Subject::class ) + Student::class ) ->findAll(); } private function prepareData(Request $request) { - return new Subject($request); + return new Student($request); } public function getById(string $id) { return $this->entityManager->getRepository( - Subject::class) + Student::class) ->findOneBy(['id' => $id]); } } \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index cbfd594..c4fbfc6 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,5 +1,6 @@ Date: Thu, 15 Sep 2022 15:53:05 -0300 Subject: [PATCH 05/54] encerra entidades e relacoes entre elas v0.1 --- app/Http/Controllers/AnswerController.php | 9 +++ app/Http/Controllers/QuestionController.php | 9 +++ app/Http/Errors/ErrorHandler.php | 9 +++ app/Models/Answer.php | 71 +++++++++++++++++++++ app/Models/Exam.php | 31 +++++++++ app/Models/ExamAnswer.php | 31 +++++++++ app/Models/ExamQuestion.php | 25 ++++++++ app/Models/Question.php | 57 +++++++++++++++++ app/Models/Subject.php | 9 ++- app/Repositorys/Interfaces/IQuestion.php | 9 +++ app/Repositorys/QuestionRepository.php | 9 +++ 11 files changed, 267 insertions(+), 2 deletions(-) create mode 100644 app/Http/Controllers/AnswerController.php create mode 100644 app/Http/Controllers/QuestionController.php create mode 100644 app/Http/Errors/ErrorHandler.php create mode 100644 app/Models/Answer.php create mode 100644 app/Models/Exam.php create mode 100644 app/Models/ExamAnswer.php create mode 100644 app/Models/ExamQuestion.php create mode 100644 app/Models/Question.php create mode 100644 app/Repositorys/Interfaces/IQuestion.php create mode 100644 app/Repositorys/QuestionRepository.php diff --git a/app/Http/Controllers/AnswerController.php b/app/Http/Controllers/AnswerController.php new file mode 100644 index 0000000..22d2d73 --- /dev/null +++ b/app/Http/Controllers/AnswerController.php @@ -0,0 +1,9 @@ +setAnswer($input['answer']); + $this->setIsCorrect($input['is_correct']); + $this->setQuestionId($input['question_id']); + } + + public function getId(): string + { + return $this->id; + } + + public function getAnswer(): string + { + return $this->answer; + } + + public function setAnswer(string $answer): void + { + $this->answer = $answer; + } + + public function getIsCorrect(): string + { + return $this->is_correct; + } + + public function setIsCorrect(string $is_correct): void + { + $this->is_correct = $is_correct; + } + + public function getQuestionId(): string + { + return $this->question_id; + } + + public function setQuestionId(string $question_id): void + { + $this->question_id = $question_id; + } + +} \ No newline at end of file diff --git a/app/Models/Exam.php b/app/Models/Exam.php new file mode 100644 index 0000000..33ae08b --- /dev/null +++ b/app/Models/Exam.php @@ -0,0 +1,31 @@ +setQuestion($input['question']); + $this->setSubjectId($input['subject']); + } + + public function getId(): string + { + return $this->id; + } + + public function getQuestion(): string + { + return $this->question; + } + + public function setQuestion(string $question): void + { + $this->question = $question; + } + + public function getSubjectId(): string + { + return $this->subject_id; + } + + public function setSubjectId(string $subject_id): void + { + $this->subject_id = $subject_id; + } +} \ No newline at end of file diff --git a/app/Models/Subject.php b/app/Models/Subject.php index 3c5ac79..bb248a5 100644 --- a/app/Models/Subject.php +++ b/app/Models/Subject.php @@ -2,16 +2,21 @@ namespace App\Models; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\Entity; use Doctrine\ORM\Mapping\GeneratedValue; use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\OneToMany; use Doctrine\ORM\Mapping\Table; #[Entity] #[Table(name:"subjects")] class Subject { + #[OneToMany(mappedBy: "subject", targetEntity: Question::class)] + protected Collection $question; + #[Id, Column(type:"guid"), GeneratedValue(strategy: 'UUID')] protected string $id; @@ -20,10 +25,10 @@ class Subject public function __construct($input) { - $this->setName($input['name']); + $this->setName($input['subject']); } - protected function getSubject(): int + public function getSubject(): int { return $this->id; } diff --git a/app/Repositorys/Interfaces/IQuestion.php b/app/Repositorys/Interfaces/IQuestion.php new file mode 100644 index 0000000..5d3825e --- /dev/null +++ b/app/Repositorys/Interfaces/IQuestion.php @@ -0,0 +1,9 @@ + Date: Thu, 15 Sep 2022 18:37:24 -0300 Subject: [PATCH 06/54] teste --- app/Models/ExamQuestion.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/ExamQuestion.php b/app/Models/ExamQuestion.php index 2c4cdfc..011fd8c 100644 --- a/app/Models/ExamQuestion.php +++ b/app/Models/ExamQuestion.php @@ -17,7 +17,7 @@ class ExamQuestion #[Id, Column(type:"guid"), GeneratedValue(strategy: 'UUID')] protected string $id; - #[Column(type:"string")] + #[Column(type:"string ")] protected string $question; #[ManyToOne(targetEntity: Exam::class, inversedBy: "exam")] From 95fefe1f4a08f724768f29120d859fd6926fc318 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Thu, 15 Sep 2022 18:38:41 -0300 Subject: [PATCH 07/54] teste --- app/Models/ExamQuestion.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/ExamQuestion.php b/app/Models/ExamQuestion.php index 011fd8c..2c4cdfc 100644 --- a/app/Models/ExamQuestion.php +++ b/app/Models/ExamQuestion.php @@ -17,7 +17,7 @@ class ExamQuestion #[Id, Column(type:"guid"), GeneratedValue(strategy: 'UUID')] protected string $id; - #[Column(type:"string ")] + #[Column(type:"string")] protected string $question; #[ManyToOne(targetEntity: Exam::class, inversedBy: "exam")] From 291a67cf228b736ee4247ec1bdfa82c6d879db05 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Thu, 15 Sep 2022 19:11:08 -0300 Subject: [PATCH 08/54] add subject controller, and repository --- app/Http/Controllers/SubjectController.php | 3 ++- app/Models/Subject.php | 5 +++-- app/Repositorys/Interfaces/ISubject.php | 5 +++-- app/Repositorys/SubjectRepository.php | 16 +++++----------- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/app/Http/Controllers/SubjectController.php b/app/Http/Controllers/SubjectController.php index 0b137ae..aa5ebd7 100644 --- a/app/Http/Controllers/SubjectController.php +++ b/app/Http/Controllers/SubjectController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use App\Models\Subject; use App\Repositorys\SubjectRepository; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -19,7 +20,7 @@ public function __construct(SubjectRepository $subjects) public function store(Request $request): JsonResponse { - $this->subjects->create($request); + $this->subjects->create(new Subject($request)); return response()->json(['message' => 'Subject ' . $request->get('name') . ' created successfully']); } diff --git a/app/Models/Subject.php b/app/Models/Subject.php index bb248a5..19699f3 100644 --- a/app/Models/Subject.php +++ b/app/Models/Subject.php @@ -9,6 +9,7 @@ use Doctrine\ORM\Mapping\Id; use Doctrine\ORM\Mapping\OneToMany; use Doctrine\ORM\Mapping\Table; +use Illuminate\Http\Request; #[Entity] #[Table(name:"subjects")] @@ -23,9 +24,9 @@ class Subject #[Column(type:"string", unique:true)] protected string $name; - public function __construct($input) + public function __construct(Request $request) { - $this->setName($input['subject']); + $this->setName($request->get('name')); } public function getSubject(): int diff --git a/app/Repositorys/Interfaces/ISubject.php b/app/Repositorys/Interfaces/ISubject.php index f19403f..b714fbd 100644 --- a/app/Repositorys/Interfaces/ISubject.php +++ b/app/Repositorys/Interfaces/ISubject.php @@ -4,11 +4,12 @@ use App\Models\Student; +use App\Models\Subject; use Illuminate\Http\Request; interface ISubject { - public function create(Request $request); - public function remove(Student $subject); + public function create(Subject $subject); + public function remove(Subject $subject); public function getAll() : array; } \ No newline at end of file diff --git a/app/Repositorys/SubjectRepository.php b/app/Repositorys/SubjectRepository.php index 6202547..940c06e 100644 --- a/app/Repositorys/SubjectRepository.php +++ b/app/Repositorys/SubjectRepository.php @@ -3,6 +3,7 @@ namespace App\Repositorys; use App\Models\Student; +use App\Models\Subject; use App\Repositorys\Interfaces\ISubject; use Doctrine\ORM\EntityManager; use Illuminate\Http\Request; @@ -16,15 +17,13 @@ public function __construct(EntityManager $entityManager) $this->entityManager = $entityManager; } - public function create(Request $request) + public function create(Subject $subject) { - $subject = $this->prepareData($request); - $this->entityManager->persist($subject); $this->entityManager->flush(); } - public function remove(Student $subject) + public function remove(Subject $subject) { try { $this->entityManager->remove($subject); @@ -43,15 +42,10 @@ public function getAll() : array ->findAll(); } - private function prepareData(Request $request) - { - return new Student($request); - } - public function getById(string $id) { - return $this->entityManager->getRepository( - Student::class) + return $this->entityManager + ->getRepository(Student::class) ->findOneBy(['id' => $id]); } } \ No newline at end of file From c6b01e6e45e09a81d2fae1721083cbe9a8d923d1 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 21 Sep 2022 16:56:45 -0300 Subject: [PATCH 09/54] commit bomba atomica --- app/Http/Controllers/AnswerController.php | 31 +++++++++- app/Http/Controllers/ExamController.php | 68 +++++++++++++++++++++ app/Http/Controllers/QuestionController.php | 31 +++++++++- app/Http/Controllers/StudentController.php | 43 ++++++------- app/Http/Controllers/SubjectController.php | 41 ++++++------- app/Http/Errors/ErrorHandler.php | 8 ++- app/Http/Middleware/VerifyCsrfToken.php | 1 - app/Models/Answer.php | 31 +++------- app/Models/Exam.php | 57 ++++++++++++++--- app/Models/ExamAnswer.php | 18 +++--- app/Models/ExamQuestion.php | 13 +++- app/Models/Question.php | 27 +++----- app/Models/Student.php | 7 ++- app/Models/Subject.php | 9 ++- app/Repositorys/AnswerRepository.php | 38 ++++++++++++ app/Repositorys/ExamAnswersRepository.php | 23 +++++++ app/Repositorys/ExamQuestionsRepository.php | 35 +++++++++++ app/Repositorys/ExamRepository.php | 33 ++++++++++ app/Repositorys/Interfaces/IQuestion.php | 9 --- app/Repositorys/Interfaces/IStudent.php | 14 ----- app/Repositorys/Interfaces/ISubject.php | 15 ----- app/Repositorys/QuestionRepository.php | 43 +++++++++++++ app/Repositorys/StudentRepository.php | 38 ++---------- app/Repositorys/SubjectRepository.php | 33 +++------- app/Services/AnswerService.php | 64 +++++++++++++++++++ app/Services/ExamAnswersService.php | 42 +++++++++++++ app/Services/ExamQuestionsService.php | 45 ++++++++++++++ app/Services/ExamService.php | 64 +++++++++++++++++++ app/Services/QuestionService.php | 42 +++++++++++++ app/Services/StudentService.php | 32 ++++++++++ app/Services/SubjectService.php | 37 +++++++++++ routes/api.php | 18 ++++-- routes/web.php | 23 +++++-- 33 files changed, 805 insertions(+), 228 deletions(-) create mode 100644 app/Http/Controllers/ExamController.php create mode 100644 app/Repositorys/AnswerRepository.php create mode 100644 app/Repositorys/ExamAnswersRepository.php create mode 100644 app/Repositorys/ExamQuestionsRepository.php create mode 100644 app/Repositorys/ExamRepository.php delete mode 100644 app/Repositorys/Interfaces/IQuestion.php delete mode 100644 app/Repositorys/Interfaces/IStudent.php delete mode 100644 app/Repositorys/Interfaces/ISubject.php create mode 100644 app/Services/AnswerService.php create mode 100644 app/Services/ExamAnswersService.php create mode 100644 app/Services/ExamQuestionsService.php create mode 100644 app/Services/ExamService.php create mode 100644 app/Services/QuestionService.php create mode 100644 app/Services/StudentService.php create mode 100644 app/Services/SubjectService.php diff --git a/app/Http/Controllers/AnswerController.php b/app/Http/Controllers/AnswerController.php index 22d2d73..c8af435 100644 --- a/app/Http/Controllers/AnswerController.php +++ b/app/Http/Controllers/AnswerController.php @@ -3,7 +3,36 @@ namespace App\Http\Controllers; -class AnswerController +use App\Services\AnswerService; +use Illuminate\Http\JsonResponse; +use Illuminate\Http\Request; +use App\Http\Errors\ErrorHandler; + +class AnswerController extends Controller { + protected AnswerService $answerService; + + public function __construct(AnswerService $answerService) + { + $this->answerService = $answerService; + } + + public function store(Request $request): JsonResponse + { + try{ + $answer = $this->answerService + ->create( + $request->get('answer'), + $request->get('question_id'), + $request->get('is_correct') + ); + + return response()->json([ + 'message' => 'The answer ' . $answer->getAnswer() . ' are created successfully' + ]); + }catch (\Exception $e){ + ErrorHandler::handleException($e); + } + } } \ No newline at end of file diff --git a/app/Http/Controllers/ExamController.php b/app/Http/Controllers/ExamController.php new file mode 100644 index 0000000..b7703a4 --- /dev/null +++ b/app/Http/Controllers/ExamController.php @@ -0,0 +1,68 @@ +examService = $examService; + $this->examQuestionsService = $examQuestionsService; + $this->examAnswersService = $examAnswersService; + } + + public function store(Request $request): JsonResponse + { + try{ + $exam = $this->createExam( + $request->get('student_id'), + $request->get('subject_id'), + $request->get('question_quantity') + ); + + return response()->json([ + 'message' => 'The exam ' . $exam->getId() . ' are created successfully' + ]); + + }catch (\Exception $e){ + ErrorHandler::handleException($e); + } + } + + private function createExam($studentId, $subjectId, $questionQuantity): Exam + { + $exam = $this->examService->create($studentId, $subjectId, $questionQuantity); + + $this->createExamQuestions($exam); + $this->createExamAnswers($exam); + + return $exam; + } + + private function createExamQuestions(Exam $exam): void + { + $this->examQuestionsService->create($exam); + } + + private function createExamAnswers($exam) + { + $this->examAnswersService->create($exam); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/QuestionController.php b/app/Http/Controllers/QuestionController.php index f0af244..465fa99 100644 --- a/app/Http/Controllers/QuestionController.php +++ b/app/Http/Controllers/QuestionController.php @@ -3,7 +3,36 @@ namespace App\Http\Controllers; -class QuestionController +use App\Http\Errors\ErrorHandler; +use App\Models\Question; +use App\Repositorys\QuestionRepository; +use App\Services\QuestionService; +use Illuminate\Http\JsonResponse; +use Illuminate\Http\Request; + +class QuestionController extends Controller { + protected QuestionService $questionService; + + public function __construct(QuestionService $questionService) + { + $this->questionService = $questionService; + } + + public function store(Request $request): JsonResponse + { + try { + $question = $this->questionService + ->create( + $request->get('question'), + $request->get('subject') + ); + return response()->json( + ['message' => 'The question ' . $question->getQuestion() . ' are created successfully' + ]); + } catch (\Exception $e) { + ErrorHandler::handleException($e); + } + } } \ No newline at end of file diff --git a/app/Http/Controllers/StudentController.php b/app/Http/Controllers/StudentController.php index fe67cbd..294441b 100644 --- a/app/Http/Controllers/StudentController.php +++ b/app/Http/Controllers/StudentController.php @@ -3,41 +3,34 @@ namespace App\Http\Controllers; +use App\Http\Errors\ErrorHandler; +use App\Repositorys\QuestionRepository; use App\Repositorys\StudentRepository; -use App\Repositorys\SubjectRepository; +use App\Services\StudentService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; -class StudentController +class StudentController extends Controller { - protected StudentRepository $student; + protected StudentService $studentService; - public function __construct(StudentRepository $student) + public function __construct(StudentService $studentService) { - $this->student = $student; + $this->studentService = $studentService; } public function store(Request $request): JsonResponse { - $this->student->create($request); - - return response()->json(['message' => 'The student ' . $request->get('name') . ' are created successfully']); - } - - public function remove(Request $request): JsonResponse - { - $studentToDelete = $this->student->getById($request->get('id')); - - $this->student->remove($studentToDelete); - - return response()->json(['message' => 'The student ' . $request->get('name') . ' are deleted successfully']); - } - - - public function index() - { - $student = $this->student->getAll(); - - return response()->json($student); + try { + $student = $this->studentService + ->create($request->get('name') + ); + + return response()->json([ + 'message' => 'The student ' . $student->getStudentName() . ' are created successfully' + ]); + } catch (\Exception $e) { + ErrorHandler::handleException($e); + } } } \ No newline at end of file diff --git a/app/Http/Controllers/SubjectController.php b/app/Http/Controllers/SubjectController.php index aa5ebd7..d12846c 100644 --- a/app/Http/Controllers/SubjectController.php +++ b/app/Http/Controllers/SubjectController.php @@ -2,43 +2,36 @@ namespace App\Http\Controllers; +use App\Http\Errors\ErrorHandler; use App\Models\Subject; use App\Repositorys\SubjectRepository; +use App\Services\SubjectService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; -use Illuminate\Http\Response; class SubjectController extends Controller { - protected SubjectRepository $subjects; + protected SubjectService $subjectService; - public function __construct(SubjectRepository $subjects) + public function __construct(SubjectService $subjectService) { - $this->subjects = $subjects; + $this->subjectService = $subjectService; } public function store(Request $request): JsonResponse { - $this->subjects->create(new Subject($request)); - - return response()->json(['message' => 'Subject ' . $request->get('name') . ' created successfully']); - } - - public function remove(Request $request): JsonResponse - { - $subjectToDelete = $this->subjects->getById($request->get('id')); - - $this->subjects->remove($subjectToDelete); - - return response()->json(['message' => 'Subject ' . $request->get('name') . ' deleted successfully']); - } - - - public function index() - { - $subjects = $this->subjects->getAll(); - - return response()->json($subjects); + try { + $subject = $this->subjectService + ->create( + $request->get('subject') + ); + + return response()->json([ + 'message' => 'The subject ' . $subject->getSubject() . ' are created successfully' + ]); + } catch (\Exception $e) { + ErrorHandler::handleException($e); + } } } \ No newline at end of file diff --git a/app/Http/Errors/ErrorHandler.php b/app/Http/Errors/ErrorHandler.php index b0e251e..f975545 100644 --- a/app/Http/Errors/ErrorHandler.php +++ b/app/Http/Errors/ErrorHandler.php @@ -5,5 +5,11 @@ class ErrorHandler { - + public static function handleException(\Exception $e) + { + var_dump('HANDLE EXCEPTION'); + throw new \Exception( + $e->getMessage() . ' in ' . $e->getFile() . ' ' . $e->getLine() + ); + } } \ No newline at end of file diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 4643b32..94f2840 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -12,6 +12,5 @@ class VerifyCsrfToken extends Middleware * @var array */ protected $except = [ - '/*', ]; } diff --git a/app/Models/Answer.php b/app/Models/Answer.php index 21e7d9b..f31c85d 100644 --- a/app/Models/Answer.php +++ b/app/Models/Answer.php @@ -17,20 +17,19 @@ class Answer protected string $id; #[Column(type:"string")] - protected string $answer; + public string $answer; #[Column(type:"boolean")] - protected string $is_correct; + protected bool $is_correct; - #[ManyToOne(targetEntity: Question::class, inversedBy: "answer")] + #[ManyToOne(targetEntity: Question::class, cascade: ["persist"], inversedBy: "answer")] protected Question $question; - - public function __construct($input) + public function __construct($answer, bool $is_correct, Question $question,) { - $this->setAnswer($input['answer']); - $this->setIsCorrect($input['is_correct']); - $this->setQuestionId($input['question_id']); + $this->answer = $answer; + $this->is_correct = $is_correct; + $this->question = $question; } public function getId(): string @@ -43,29 +42,13 @@ public function getAnswer(): string return $this->answer; } - public function setAnswer(string $answer): void - { - $this->answer = $answer; - } - public function getIsCorrect(): string { return $this->is_correct; } - public function setIsCorrect(string $is_correct): void - { - $this->is_correct = $is_correct; - } - public function getQuestionId(): string { return $this->question_id; } - - public function setQuestionId(string $question_id): void - { - $this->question_id = $question_id; - } - } \ No newline at end of file diff --git a/app/Models/Exam.php b/app/Models/Exam.php index 33ae08b..e53046d 100644 --- a/app/Models/Exam.php +++ b/app/Models/Exam.php @@ -9,23 +9,66 @@ use Doctrine\ORM\Mapping\Id; use Doctrine\ORM\Mapping\ManyToOne; use Doctrine\ORM\Mapping\Table; +use Gedmo\Timestampable\Traits\TimestampableEntity; #[Entity] -#[Table(name:"exam")] +#[Table(name:"exams")] class Exam { + public function __construct(Student $student, Subject $subject, $questionQuantity) + { + $this->student = $student; + $this->subject = $subject; + $this->question_quantity = $questionQuantity; + } + + use TimestampableEntity; + #[Id, Column(type:"guid"), GeneratedValue(strategy: 'UUID')] protected string $id; + #[ManyToOne(targetEntity: Subject::class, cascade: ["persist"], inversedBy: "subject")] + protected Subject $subject; + + #[ManyToOne(targetEntity: Student::class, cascade: ["persist"], inversedBy: "student")] + protected Student $student; + + #[Column(type:"integer")] + protected int $score; + + #[Column(type:"integer")] + protected int $question_quantity; + #[Column(type:"datetime")] protected string $finished_at; - #[Column(type:"integer")] - protected string $score; + public function getId(): string + { + return $this->id; + } - #[ManyToOne(targetEntity: Subject::class, inversedBy: "subject")] - protected Subject $subject; + public function getFinishedAt(): string + { + return $this->finished_at; + } - #[ManyToOne(targetEntity: Student::class, inversedBy: "student")] - protected Student $student; + public function getScore(): string + { + return $this->score; + } + + public function getSubject(): Subject + { + return $this->subject; + } + + public function getStudent(): Student + { + return $this->student; + } + + public function getQuestionQuantity() + { + return $this->question_quantity; + } } \ No newline at end of file diff --git a/app/Models/ExamAnswer.php b/app/Models/ExamAnswer.php index 8ff3d21..a4af251 100644 --- a/app/Models/ExamAnswer.php +++ b/app/Models/ExamAnswer.php @@ -8,24 +8,28 @@ use Doctrine\ORM\Mapping\GeneratedValue; use Doctrine\ORM\Mapping\Id; use Doctrine\ORM\Mapping\ManyToOne; +use Doctrine\ORM\Mapping\OneToOne; use Doctrine\ORM\Mapping\Table; #[Entity] #[Table(name:"exam_answer")] class ExamAnswer { + public function __construct(ExamQuestion $question, Answer $correctAnswer) + { + $this->question = $question; + $this->correct_answer = $correctAnswer; + } + #[Id, Column(type:"guid"), GeneratedValue(strategy: 'UUID')] protected string $id; #[Column(type:"string")] - protected string $answer; - - #[Column(type:"boolean")] - protected string $is_correct; + protected string $student_answer; - #[Column(type:"boolean")] - protected string $is_marked; + #[OneToOne(targetEntity: Exam::class, cascade: ["persist"])] + protected Answer $correct_answer; - #[ManyToOne(targetEntity: ExamQuestion::class, inversedBy: "question")] + #[OneToOne(inversedBy: "question", targetEntity: ExamQuestion::class)] protected ExamQuestion $question; } \ No newline at end of file diff --git a/app/Models/ExamQuestion.php b/app/Models/ExamQuestion.php index 2c4cdfc..e4ba33c 100644 --- a/app/Models/ExamQuestion.php +++ b/app/Models/ExamQuestion.php @@ -8,18 +8,25 @@ use Doctrine\ORM\Mapping\GeneratedValue; use Doctrine\ORM\Mapping\Id; use Doctrine\ORM\Mapping\ManyToOne; +use Doctrine\ORM\Mapping\OneToOne; use Doctrine\ORM\Mapping\Table; #[Entity] #[Table(name:"exam_questions")] class ExamQuestion { + public function __construct(Question $question, Exam $exam) + { + $this->question = $question; + $this->exam = $exam; + } + #[Id, Column(type:"guid"), GeneratedValue(strategy: 'UUID')] protected string $id; - #[Column(type:"string")] - protected string $question; + #[OneToOne(targetEntity: Question::class, cascade: ["persist"])] + protected Question $question; - #[ManyToOne(targetEntity: Exam::class, inversedBy: "exam")] + #[ManyToOne(targetEntity: Exam::class, cascade: ["persist"], inversedBy: "exam")] protected Exam $exam; } \ No newline at end of file diff --git a/app/Models/Question.php b/app/Models/Question.php index 48615b5..45f1434 100644 --- a/app/Models/Question.php +++ b/app/Models/Question.php @@ -3,7 +3,6 @@ namespace App\Models; -use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\Entity; use Doctrine\ORM\Mapping\GeneratedValue; @@ -18,16 +17,16 @@ class Question #[Id, Column(type:"guid"), GeneratedValue(strategy: 'UUID')] protected string $id; + #[ManyToOne(targetEntity: Subject::class, cascade: ["persist"], inversedBy: "question")] + protected Subject $subject; + #[Column(type:"string")] protected string $question; - #[ManyToOne(targetEntity: Subject::class, inversedBy: "question")] - protected Subject $subject; - - public function __construct($input) + public function __construct(string $question, Subject $subject) { - $this->setQuestion($input['question']); - $this->setSubjectId($input['subject']); + $this->question = $question; + $this->subject = $subject; } public function getId(): string @@ -40,18 +39,8 @@ public function getQuestion(): string return $this->question; } - public function setQuestion(string $question): void - { - $this->question = $question; - } - - public function getSubjectId(): string - { - return $this->subject_id; - } - - public function setSubjectId(string $subject_id): void + public function getSubject(): string { - $this->subject_id = $subject_id; + return $this->subject; } } \ No newline at end of file diff --git a/app/Models/Student.php b/app/Models/Student.php index 37fd28a..1f00c11 100644 --- a/app/Models/Student.php +++ b/app/Models/Student.php @@ -7,6 +7,7 @@ use Doctrine\ORM\Mapping\GeneratedValue; use Doctrine\ORM\Mapping\Id; use Doctrine\ORM\Mapping\Table; +use http\Env\Request; #[Entity] #[Table(name:"students")] @@ -18,9 +19,9 @@ class Student #[Column(type:"string")] protected string $name; - public function __construct($input) + public function __construct($name) { - $this->setName($input['name']); + $this->setName($name); } protected function getStudent(): int @@ -28,7 +29,7 @@ protected function getStudent(): int return $this->id; } - protected function getStudentName(): string + public function getStudentName(): string { return $this->name; } diff --git a/app/Models/Subject.php b/app/Models/Subject.php index 19699f3..ad871ea 100644 --- a/app/Models/Subject.php +++ b/app/Models/Subject.php @@ -9,13 +9,12 @@ use Doctrine\ORM\Mapping\Id; use Doctrine\ORM\Mapping\OneToMany; use Doctrine\ORM\Mapping\Table; -use Illuminate\Http\Request; #[Entity] #[Table(name:"subjects")] class Subject { - #[OneToMany(mappedBy: "subject", targetEntity: Question::class)] + #[OneToMany(mappedBy: "subject", targetEntity: Question::class, cascade: ["persist"])] protected Collection $question; #[Id, Column(type:"guid"), GeneratedValue(strategy: 'UUID')] @@ -24,12 +23,12 @@ class Subject #[Column(type:"string", unique:true)] protected string $name; - public function __construct(Request $request) + public function __construct(string $subject) { - $this->setName($request->get('name')); + $this->setName($subject); } - public function getSubject(): int + public function getSubject(): string { return $this->id; } diff --git a/app/Repositorys/AnswerRepository.php b/app/Repositorys/AnswerRepository.php new file mode 100644 index 0000000..4072dfc --- /dev/null +++ b/app/Repositorys/AnswerRepository.php @@ -0,0 +1,38 @@ +entityManager = $entityManager; + } + + public function create(Answer $answer) : Answer + { + $this->entityManager->persist($answer); + $this->entityManager->flush(); + + return $answer; + } + + public function getCorrectAnswer(Question $question) { + $queryBuilder = $this->entityManager->createQueryBuilder(); + + return $queryBuilder->select('answer') + ->from(Answer::class, 'answer') + ->where('answer.is_correct = true') + ->andWhere('answer.question = :questionId') + ->setParameter('questionId', $question->getId()) + ->getQuery() + ->getOneOrNullResult(); + } +} \ No newline at end of file diff --git a/app/Repositorys/ExamAnswersRepository.php b/app/Repositorys/ExamAnswersRepository.php new file mode 100644 index 0000000..0797b52 --- /dev/null +++ b/app/Repositorys/ExamAnswersRepository.php @@ -0,0 +1,23 @@ +entityManager = $entityManager; + } + + public function create(ExamAnswer $examAnswer) + { + $this->entityManager->persist($examAnswer); + dd($this->entityManager->flush()); + } +} \ No newline at end of file diff --git a/app/Repositorys/ExamQuestionsRepository.php b/app/Repositorys/ExamQuestionsRepository.php new file mode 100644 index 0000000..5b60699 --- /dev/null +++ b/app/Repositorys/ExamQuestionsRepository.php @@ -0,0 +1,35 @@ +entityManager = $entityManager; + } + + public function create(ExamQuestion $examQuestion) + { + $this->entityManager->persist($examQuestion); + } + + public function findQuestionsByExam(Exam $exam) + { + $queryBuilder = $this->entityManager->createQueryBuilder(); + + return $queryBuilder->select('examQuestion') + ->from(ExamQuestion::class, 'examQuestion') + ->where('examQuestion.exam = :examId') + ->setParameter('examId', $exam->getId()) + ->getQuery() + ->getResult(); + } +} \ No newline at end of file diff --git a/app/Repositorys/ExamRepository.php b/app/Repositorys/ExamRepository.php new file mode 100644 index 0000000..85cff24 --- /dev/null +++ b/app/Repositorys/ExamRepository.php @@ -0,0 +1,33 @@ +entityManager = $entityManager; + } + + public function create(Exam $exam): Exam + { + $this->entityManager->persist($exam); +// $this->entityManager->flush(); + + return $exam; + } + + public function getById(string $id) + { + return $this->entityManager->find( + Exam::class, + $id + ); + } +} \ No newline at end of file diff --git a/app/Repositorys/Interfaces/IQuestion.php b/app/Repositorys/Interfaces/IQuestion.php deleted file mode 100644 index 5d3825e..0000000 --- a/app/Repositorys/Interfaces/IQuestion.php +++ /dev/null @@ -1,9 +0,0 @@ -entityManager = $entityManager; + } + + public function create(Question $question): Question + { + $this->entityManager->persist($question); + $this->entityManager->flush(); + + return $question; + } + + public function getById(string $id) + { + return $this->entityManager->find( + Question::class, + $id + ); + } + + public function getAllQuestionsBySubject($subjectId) + { + $queryBuilder = $this->entityManager->createQueryBuilder(); + + return $queryBuilder->select('question') + ->from(Question::class, 'question') + ->where('question.subject = :subject') + ->setParameter('subject', $subjectId) + ->getQuery() + ->getResult(); + } + + public function countQuestionsBySubject($subjectId) + { + return $this->entityManager->getRepository(Question::class)->count(['subject' => $subjectId]); + } } \ No newline at end of file diff --git a/app/Repositorys/StudentRepository.php b/app/Repositorys/StudentRepository.php index 8aedff2..22d0b48 100644 --- a/app/Repositorys/StudentRepository.php +++ b/app/Repositorys/StudentRepository.php @@ -4,11 +4,9 @@ use App\Models\Student; -use App\Repositorys\Interfaces\IStudent; use Doctrine\ORM\EntityManager; -use Illuminate\Http\Request; -class StudentRepository implements IStudent +class StudentRepository { private EntityManager $entityManager; @@ -17,42 +15,16 @@ public function __construct(EntityManager $entityManager) $this->entityManager = $entityManager; } - public function create(Request $request) + public function create(Student $student): Student { - $student = $this->prepareData($request); - $this->entityManager->persist($student); $this->entityManager->flush(); - } - - public function remove(Student $student) - { - try { - $this->entityManager->remove($student); - - $this->entityManager->flush(); - }catch (\Exception $e) { - throw new \Exception($e->getMessage()); - } - } - - public function getAll() : array - { - return $this->entityManager->getRepository( - Student::class ) - ->findAll(); - } - - private function prepareData(Request $request) - { - return new Student($request); + return $student; } - public function getById(string $id) + public function getById($id): Student { - return $this->entityManager->getRepository( - Student::class) - ->findOneBy(['id' => $id]); + return $this->entityManager->find(Student::class, $id); } } \ No newline at end of file diff --git a/app/Repositorys/SubjectRepository.php b/app/Repositorys/SubjectRepository.php index 940c06e..bc15cdb 100644 --- a/app/Repositorys/SubjectRepository.php +++ b/app/Repositorys/SubjectRepository.php @@ -2,13 +2,10 @@ namespace App\Repositorys; -use App\Models\Student; use App\Models\Subject; -use App\Repositorys\Interfaces\ISubject; use Doctrine\ORM\EntityManager; -use Illuminate\Http\Request; -class SubjectRepository implements ISubject +class SubjectRepository { private EntityManager $entityManager; @@ -17,35 +14,19 @@ public function __construct(EntityManager $entityManager) $this->entityManager = $entityManager; } - public function create(Subject $subject) + public function create(Subject $subject) : Subject { $this->entityManager->persist($subject); $this->entityManager->flush(); - } - - public function remove(Subject $subject) - { - try { - $this->entityManager->remove($subject); - - $this->entityManager->flush(); - }catch (\Exception $e) { - throw new \Exception($e->getMessage()); - } - } - - public function getAll() : array - { - return $this->entityManager->getRepository( - Student::class ) - ->findAll(); + return $subject; } public function getById(string $id) { - return $this->entityManager - ->getRepository(Student::class) - ->findOneBy(['id' => $id]); + return $this->entityManager->find( + Subject::class, + $id + ); } } \ No newline at end of file diff --git a/app/Services/AnswerService.php b/app/Services/AnswerService.php new file mode 100644 index 0000000..3674bc0 --- /dev/null +++ b/app/Services/AnswerService.php @@ -0,0 +1,64 @@ +answerRepository = $answerRepository; + $this->questionRepository = $questionRepository; + } + + public function create( + $answer, + $questionId, + $isCorrect + ) : Answer + { + + $this->validateAnswerRequest( + [ + 'answer' => $answer, + 'questionId' => $questionId, + 'isCorrect' => $isCorrect + ] + ); + + return $this->answerRepository->create( + new Answer( + $answer, + $isCorrect, + $this->questionRepository->getById($questionId) + ) + ); + } + + private function validateAnswerRequest($request) + { + foreach ($request as $key => $value) { + if (!isset($value)) { + throw new \Exception("the $key value not can be empty!"); + } + } + + if ($this->questionRepository->getById($request['questionId']) === null) { + throw new \Exception('The answer not have a question'); + } + + if (!is_bool($request['isCorrect'])) { + throw new \Exception('The isCorrect value not is a boolean'); + } + } +} \ No newline at end of file diff --git a/app/Services/ExamAnswersService.php b/app/Services/ExamAnswersService.php new file mode 100644 index 0000000..22f840c --- /dev/null +++ b/app/Services/ExamAnswersService.php @@ -0,0 +1,42 @@ +examAnswersRepository = $examAnswersRepository; + $this->answerRepository = $answerRepository; + $this->examQuestionsRepository = $examQuestionsRepository; + } + + public function create(Exam $exam) + { + $examQuestions = $this->examQuestionsRepository->findQuestionsByExam($exam); + + + foreach ($examQuestions as $examQuestion) { + $correctAnswer = $this->answerRepository->getCorrectAnswer($examQuestion); + + $this->examAnswersRepository->create( + new ExamAnswer($examQuestion, $correctAnswer) + ); + } + } +} \ No newline at end of file diff --git a/app/Services/ExamQuestionsService.php b/app/Services/ExamQuestionsService.php new file mode 100644 index 0000000..3cea906 --- /dev/null +++ b/app/Services/ExamQuestionsService.php @@ -0,0 +1,45 @@ +questionRepository = $questionRepository; + $this->examQuestionsRepository = $examQuestionsRepository; + } + + public function create(Exam $exam) + { + $examQuestions = $this->pickExamQuestions($exam); + + foreach ($examQuestions as $examQuestion) { + $this->examQuestionsRepository->create(new ExamQuestion($examQuestion, $exam)); + } + } + + private function pickExamQuestions(Exam $exam) + { + $allQuestions = $this->questionRepository->getAllQuestionsBySubject($exam->getSubject()); + + shuffle($allQuestions); + + return array_slice( + $allQuestions, + 0, + $exam->getQuestionQuantity() + ); + } +} \ No newline at end of file diff --git a/app/Services/ExamService.php b/app/Services/ExamService.php new file mode 100644 index 0000000..c41c782 --- /dev/null +++ b/app/Services/ExamService.php @@ -0,0 +1,64 @@ +subjectRepository = $subjectRepository; + $this->examRepository = $examRepository; + $this->studentRepository = $studentRepository; + $this->questionRepository = $questionRepository; + } + + public function create($studentId, $subjectId, $questionQuantity) + { + $this->validateExamRequest( + [ + 'studentId' => $studentId, + 'subjectId' => $subjectId, + 'questionQuantity' => $questionQuantity + ] + ); + + return $this->examRepository->create( + new Exam( + $this->studentRepository->getById($studentId), + $this->subjectRepository->getById($subjectId), + $questionQuantity + ) + ); + } + + private function validateExamRequest($request) + { + foreach ($request as $key => $value) { + if (!isset($value)) { + throw new \Exception("the $key value not can be empty!"); + } + } + + if($this->questionRepository->countQuestionsBySubject($request['subjectId']) < $request['questionQuantity']){ + throw new \Exception("the quantity of questions is less than the requested quantity"); + } + } +} \ No newline at end of file diff --git a/app/Services/QuestionService.php b/app/Services/QuestionService.php new file mode 100644 index 0000000..975a57b --- /dev/null +++ b/app/Services/QuestionService.php @@ -0,0 +1,42 @@ +subjectRepository = $subjectRepository; + $this->questionRepository = $questionRepository; + } + + public function create($question, $subjectId): Question + { + $this->validateQuestionRequest($question, $subjectId); + + return $this->questionRepository->create( + new Question($question, $this->subjectRepository->getById($subjectId)) + ); + } + + private function validateQuestionRequest($question, $subjectId) + { + if (empty($question)) { + throw new \Exception('The question is empty'); + } + + if ($this->subjectRepository->getById($subjectId) === null) { + throw new \Exception('The question not have a subject'); + } + } +} diff --git a/app/Services/StudentService.php b/app/Services/StudentService.php new file mode 100644 index 0000000..2913654 --- /dev/null +++ b/app/Services/StudentService.php @@ -0,0 +1,32 @@ +studentRepository = $studentRepository; + } + + public function create($name) : Student + { + $this->validateStudentName($name); + + return $this->studentRepository->create(new Student($name)); + } + + private function validateStudentName($name) + { + if(!$name || strlen($name) < 3) { + throw new \Exception('The student has to be a valid name'); + } + } +} \ No newline at end of file diff --git a/app/Services/SubjectService.php b/app/Services/SubjectService.php new file mode 100644 index 0000000..36087f1 --- /dev/null +++ b/app/Services/SubjectService.php @@ -0,0 +1,37 @@ +subjectRepository = $subjectRepository; + + } + + public function create($subjectName): Subject + { + $this->validateSubjectRequest($subjectName); + + return $this->subjectRepository->create(new Subject($subjectName)); + } + + private function validateSubjectRequest($subject) + { + if (empty($subject)) { + throw new \Exception('The subject is empty'); + } + + if (strlen($subject) < 3) { + throw new \Exception('The subject name is too short'); + } + } +} \ No newline at end of file diff --git a/routes/api.php b/routes/api.php index eb6fa48..8046c00 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,6 +1,10 @@ get('/user', function (Request $request) { - return $request->user(); -}); +Route::post('/subject/create', [SubjectController::class, 'store']); + +Route::post('/student/create', [StudentController::class, 'store']); + +Route::post('/question/create', [QuestionController::class, 'store']); + +Route::post('/answer/create', [AnswerController::class, 'store']); + +Route::post('/exam/create', [ExamController::class, 'store']); diff --git a/routes/web.php b/routes/web.php index c4fbfc6..c37c1f6 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,5 +1,6 @@ Date: Thu, 22 Sep 2022 07:53:26 -0300 Subject: [PATCH 10/54] antes do pivot para usar uma tabela de examAndAnswer --- app/Http/Controllers/ExamController.php | 33 ++---------------- app/Models/Exam.php | 4 +-- app/Models/ExamAnswer.php | 11 +++--- app/Models/ExamQuestion.php | 15 ++++++-- app/Repositorys/AnswerRepository.php | 2 +- app/Repositorys/ExamAnswersRepository.php | 2 +- app/Repositorys/ExamRepository.php | 1 - app/Services/ExamAnswersService.php | 6 +--- app/Services/ExamQuestionsService.php | 12 +++++-- app/Services/ExamService.php | 42 ++++++++++++++++++----- 10 files changed, 68 insertions(+), 60 deletions(-) diff --git a/app/Http/Controllers/ExamController.php b/app/Http/Controllers/ExamController.php index b7703a4..da427d5 100644 --- a/app/Http/Controllers/ExamController.php +++ b/app/Http/Controllers/ExamController.php @@ -14,24 +14,16 @@ class ExamController { protected ExamService $examService; - protected ExamQuestionsService $examQuestionsService; - protected ExamAnswersService $examAnswersService; - public function __construct( - ExamService $examService, - ExamQuestionsService $examQuestionsService, - ExamAnswersService $examAnswersService - ) + public function __construct(ExamService $examService) { $this->examService = $examService; - $this->examQuestionsService = $examQuestionsService; - $this->examAnswersService = $examAnswersService; } public function store(Request $request): JsonResponse { try{ - $exam = $this->createExam( + $exam = $this->examService->create( $request->get('student_id'), $request->get('subject_id'), $request->get('question_quantity') @@ -41,28 +33,9 @@ public function store(Request $request): JsonResponse 'message' => 'The exam ' . $exam->getId() . ' are created successfully' ]); + }catch (\Exception $e){ ErrorHandler::handleException($e); } } - - private function createExam($studentId, $subjectId, $questionQuantity): Exam - { - $exam = $this->examService->create($studentId, $subjectId, $questionQuantity); - - $this->createExamQuestions($exam); - $this->createExamAnswers($exam); - - return $exam; - } - - private function createExamQuestions(Exam $exam): void - { - $this->examQuestionsService->create($exam); - } - - private function createExamAnswers($exam) - { - $this->examAnswersService->create($exam); - } } \ No newline at end of file diff --git a/app/Models/Exam.php b/app/Models/Exam.php index e53046d..77f9262 100644 --- a/app/Models/Exam.php +++ b/app/Models/Exam.php @@ -33,13 +33,13 @@ public function __construct(Student $student, Subject $subject, $questionQuantit #[ManyToOne(targetEntity: Student::class, cascade: ["persist"], inversedBy: "student")] protected Student $student; - #[Column(type:"integer")] + #[Column(type:"integer", nullable: true)] protected int $score; #[Column(type:"integer")] protected int $question_quantity; - #[Column(type:"datetime")] + #[Column(type:"datetime", nullable: true)] protected string $finished_at; public function getId(): string diff --git a/app/Models/ExamAnswer.php b/app/Models/ExamAnswer.php index a4af251..e7c3946 100644 --- a/app/Models/ExamAnswer.php +++ b/app/Models/ExamAnswer.php @@ -7,7 +7,6 @@ use Doctrine\ORM\Mapping\Entity; use Doctrine\ORM\Mapping\GeneratedValue; use Doctrine\ORM\Mapping\Id; -use Doctrine\ORM\Mapping\ManyToOne; use Doctrine\ORM\Mapping\OneToOne; use Doctrine\ORM\Mapping\Table; @@ -15,7 +14,7 @@ #[Table(name:"exam_answer")] class ExamAnswer { - public function __construct(ExamQuestion $question, Answer $correctAnswer) + public function __construct(Question $question, Answer $correctAnswer) { $this->question = $question; $this->correct_answer = $correctAnswer; @@ -24,12 +23,12 @@ public function __construct(ExamQuestion $question, Answer $correctAnswer) #[Id, Column(type:"guid"), GeneratedValue(strategy: 'UUID')] protected string $id; - #[Column(type:"string")] + #[Column(type:"string", nullable: true)] protected string $student_answer; - #[OneToOne(targetEntity: Exam::class, cascade: ["persist"])] + #[OneToOne(targetEntity: Answer::class, cascade: ["persist"])] protected Answer $correct_answer; - #[OneToOne(inversedBy: "question", targetEntity: ExamQuestion::class)] - protected ExamQuestion $question; + #[Column(type:"string", nullable: true)] + protected string $question; } \ No newline at end of file diff --git a/app/Models/ExamQuestion.php b/app/Models/ExamQuestion.php index e4ba33c..9a7feaf 100644 --- a/app/Models/ExamQuestion.php +++ b/app/Models/ExamQuestion.php @@ -17,16 +17,25 @@ class ExamQuestion { public function __construct(Question $question, Exam $exam) { - $this->question = $question; + $this->question = $question->getQuestion(); $this->exam = $exam; } #[Id, Column(type:"guid"), GeneratedValue(strategy: 'UUID')] protected string $id; - #[OneToOne(targetEntity: Question::class, cascade: ["persist"])] - protected Question $question; + protected string $question; #[ManyToOne(targetEntity: Exam::class, cascade: ["persist"], inversedBy: "exam")] protected Exam $exam; + + public function getId() + { + return $this->id; + } + public function getQuestionId() + { + return $this->question; + } + } \ No newline at end of file diff --git a/app/Repositorys/AnswerRepository.php b/app/Repositorys/AnswerRepository.php index 4072dfc..aa09411 100644 --- a/app/Repositorys/AnswerRepository.php +++ b/app/Repositorys/AnswerRepository.php @@ -31,7 +31,7 @@ public function getCorrectAnswer(Question $question) { ->from(Answer::class, 'answer') ->where('answer.is_correct = true') ->andWhere('answer.question = :questionId') - ->setParameter('questionId', $question->getId()) + ->setParameter('questionId', $question->getQuestion()) ->getQuery() ->getOneOrNullResult(); } diff --git a/app/Repositorys/ExamAnswersRepository.php b/app/Repositorys/ExamAnswersRepository.php index 0797b52..63b5d70 100644 --- a/app/Repositorys/ExamAnswersRepository.php +++ b/app/Repositorys/ExamAnswersRepository.php @@ -18,6 +18,6 @@ public function __construct(EntityManager $entityManager) public function create(ExamAnswer $examAnswer) { $this->entityManager->persist($examAnswer); - dd($this->entityManager->flush()); + $this->entityManager->flush(); } } \ No newline at end of file diff --git a/app/Repositorys/ExamRepository.php b/app/Repositorys/ExamRepository.php index 85cff24..0f75f30 100644 --- a/app/Repositorys/ExamRepository.php +++ b/app/Repositorys/ExamRepository.php @@ -18,7 +18,6 @@ public function __construct(EntityManager $entityManager) public function create(Exam $exam): Exam { $this->entityManager->persist($exam); -// $this->entityManager->flush(); return $exam; } diff --git a/app/Services/ExamAnswersService.php b/app/Services/ExamAnswersService.php index 22f840c..08393c0 100644 --- a/app/Services/ExamAnswersService.php +++ b/app/Services/ExamAnswersService.php @@ -3,7 +3,6 @@ namespace App\Services; -use App\Models\Exam; use App\Models\ExamAnswer; use App\Repositorys\AnswerRepository; use App\Repositorys\ExamAnswersRepository; @@ -26,11 +25,8 @@ public function __construct( $this->examQuestionsRepository = $examQuestionsRepository; } - public function create(Exam $exam) + public function create($examQuestions) { - $examQuestions = $this->examQuestionsRepository->findQuestionsByExam($exam); - - foreach ($examQuestions as $examQuestion) { $correctAnswer = $this->answerRepository->getCorrectAnswer($examQuestion); diff --git a/app/Services/ExamQuestionsService.php b/app/Services/ExamQuestionsService.php index 3cea906..ea18c65 100644 --- a/app/Services/ExamQuestionsService.php +++ b/app/Services/ExamQuestionsService.php @@ -23,11 +23,17 @@ public function __construct( public function create(Exam $exam) { - $examQuestions = $this->pickExamQuestions($exam); + $questions = $this->pickExamQuestions($exam); + $examQuestions = []; - foreach ($examQuestions as $examQuestion) { - $this->examQuestionsRepository->create(new ExamQuestion($examQuestion, $exam)); + foreach ($questions as $examQuestion) { + $examQuestion = new ExamQuestion($examQuestion, $exam); + + $this->examQuestionsRepository->create($examQuestion); + $examQuestions[] = $examQuestion; } + + return $examQuestions; } private function pickExamQuestions(Exam $exam) diff --git a/app/Services/ExamService.php b/app/Services/ExamService.php index c41c782..63ac5ea 100644 --- a/app/Services/ExamService.php +++ b/app/Services/ExamService.php @@ -4,7 +4,6 @@ use App\Models\Exam; -use App\Repositorys\ExamQuestionsRepository; use App\Repositorys\ExamRepository; use App\Repositorys\QuestionRepository; use App\Repositorys\StudentRepository; @@ -17,17 +16,24 @@ class ExamService protected StudentRepository $studentRepository; protected QuestionRepository $questionRepository; + protected ExamQuestionsService $examQuestionsService; + protected ExamAnswersService $examAnswersService; + public function __construct( SubjectRepository $subjectRepository, ExamRepository $examRepository, StudentRepository $studentRepository, QuestionRepository $questionRepository, + ExamQuestionsService $examQuestionsService, + ExamAnswersService $examAnswersService ) { $this->subjectRepository = $subjectRepository; $this->examRepository = $examRepository; $this->studentRepository = $studentRepository; $this->questionRepository = $questionRepository; + $this->examQuestionsService = $examQuestionsService; + $this->examAnswersService = $examAnswersService; } public function create($studentId, $subjectId, $questionQuantity) @@ -40,13 +46,12 @@ public function create($studentId, $subjectId, $questionQuantity) ] ); - return $this->examRepository->create( - new Exam( - $this->studentRepository->getById($studentId), - $this->subjectRepository->getById($subjectId), - $questionQuantity - ) - ); + $exam = $this->createExam($studentId, $subjectId, $questionQuantity); + + $examQuestions = $this->createExamQuestions($exam); + $this->createExamAnswers($examQuestions); + + return $exam; } private function validateExamRequest($request) @@ -61,4 +66,25 @@ private function validateExamRequest($request) throw new \Exception("the quantity of questions is less than the requested quantity"); } } + + private function createExam($studentId, $subjectId, $questionQuantity) + { + return $this->examRepository->create( + new Exam( + $this->studentRepository->getById($studentId), + $this->subjectRepository->getById($subjectId), + $questionQuantity + ) + ); + } + + private function createExamQuestions(Exam $exam) + { + return $this->examQuestionsService->create($exam); + } + + private function createExamAnswers($examQuestions) + { + $this->examAnswersService->create($examQuestions); + } } \ No newline at end of file From 58f61e14a5777b74d20a56bcaec04821be613736 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Mon, 26 Sep 2022 07:48:45 -0300 Subject: [PATCH 11/54] antes de alterar para arrayCollection --- app/Http/Controllers/ExamController.php | 3 - app/Models/Answer.php | 2 +- app/Models/ExamAnswer.php | 34 ----------- app/Models/ExamQuestion.php | 41 ------------- app/Models/ExamQuestionAnswer.php | 50 ++++++++++++++++ app/Repositorys/AnswerRepository.php | 9 ++- .../ExamQuestionAnswerRepository.php | 25 ++++++++ app/Repositorys/QuestionRepository.php | 13 +++- app/Services/ExamAnswersService.php | 38 ------------ app/Services/ExamQuestionAnswerService.php | 59 +++++++++++++++++++ app/Services/ExamQuestionsService.php | 51 ---------------- app/Services/ExamService.php | 26 +++----- 12 files changed, 158 insertions(+), 193 deletions(-) delete mode 100644 app/Models/ExamAnswer.php delete mode 100644 app/Models/ExamQuestion.php create mode 100644 app/Models/ExamQuestionAnswer.php create mode 100644 app/Repositorys/ExamQuestionAnswerRepository.php delete mode 100644 app/Services/ExamAnswersService.php create mode 100644 app/Services/ExamQuestionAnswerService.php delete mode 100644 app/Services/ExamQuestionsService.php diff --git a/app/Http/Controllers/ExamController.php b/app/Http/Controllers/ExamController.php index da427d5..4b99030 100644 --- a/app/Http/Controllers/ExamController.php +++ b/app/Http/Controllers/ExamController.php @@ -4,9 +4,6 @@ use App\Http\Errors\ErrorHandler; -use App\Models\Exam; -use App\Services\ExamAnswersService; -use App\Services\ExamQuestionsService; use App\Services\ExamService; use Illuminate\Http\Request; use Illuminate\Http\JsonResponse; diff --git a/app/Models/Answer.php b/app/Models/Answer.php index f31c85d..5ca9505 100644 --- a/app/Models/Answer.php +++ b/app/Models/Answer.php @@ -25,7 +25,7 @@ class Answer #[ManyToOne(targetEntity: Question::class, cascade: ["persist"], inversedBy: "answer")] protected Question $question; - public function __construct($answer, bool $is_correct, Question $question,) + public function __construct($answer, bool $is_correct, Question $question) { $this->answer = $answer; $this->is_correct = $is_correct; diff --git a/app/Models/ExamAnswer.php b/app/Models/ExamAnswer.php deleted file mode 100644 index e7c3946..0000000 --- a/app/Models/ExamAnswer.php +++ /dev/null @@ -1,34 +0,0 @@ -question = $question; - $this->correct_answer = $correctAnswer; - } - - #[Id, Column(type:"guid"), GeneratedValue(strategy: 'UUID')] - protected string $id; - - #[Column(type:"string", nullable: true)] - protected string $student_answer; - - #[OneToOne(targetEntity: Answer::class, cascade: ["persist"])] - protected Answer $correct_answer; - - #[Column(type:"string", nullable: true)] - protected string $question; -} \ No newline at end of file diff --git a/app/Models/ExamQuestion.php b/app/Models/ExamQuestion.php deleted file mode 100644 index 9a7feaf..0000000 --- a/app/Models/ExamQuestion.php +++ /dev/null @@ -1,41 +0,0 @@ -question = $question->getQuestion(); - $this->exam = $exam; - } - - #[Id, Column(type:"guid"), GeneratedValue(strategy: 'UUID')] - protected string $id; - - protected string $question; - - #[ManyToOne(targetEntity: Exam::class, cascade: ["persist"], inversedBy: "exam")] - protected Exam $exam; - - public function getId() - { - return $this->id; - } - public function getQuestionId() - { - return $this->question; - } - -} \ No newline at end of file diff --git a/app/Models/ExamQuestionAnswer.php b/app/Models/ExamQuestionAnswer.php new file mode 100644 index 0000000..79db141 --- /dev/null +++ b/app/Models/ExamQuestionAnswer.php @@ -0,0 +1,50 @@ +exam = $exam; + $this->question = $question->getQuestion(); + $this->answer = $answer->getAnswer(); + $this->isCorrect = $answer->getIsCorrect(); + } + + #[Id, Column(type:"guid"), GeneratedValue(strategy: 'UUID')] + protected string $id; + + #[ManyToOne(targetEntity: Exam::class, cascade: ["persist"], inversedBy: "exam")] + private Exam $exam; + + #[Column(type:"string")] + private string $question; + + #[Column(type:"string")] + private string $answer; + + #[Column(type:"boolean")] + private string $isCorrect; + + #[Column(type:"string", nullable: true)] + protected string $student_answer; + + public function getQuestion() + { + return $this->question; + } +} \ No newline at end of file diff --git a/app/Repositorys/AnswerRepository.php b/app/Repositorys/AnswerRepository.php index aa09411..2353b9a 100644 --- a/app/Repositorys/AnswerRepository.php +++ b/app/Repositorys/AnswerRepository.php @@ -24,15 +24,14 @@ public function create(Answer $answer) : Answer return $answer; } - public function getCorrectAnswer(Question $question) { + public function getAnswersByQuestion($questionId) { $queryBuilder = $this->entityManager->createQueryBuilder(); return $queryBuilder->select('answer') ->from(Answer::class, 'answer') - ->where('answer.is_correct = true') - ->andWhere('answer.question = :questionId') - ->setParameter('questionId', $question->getQuestion()) + ->where('answer.question = :questionId') + ->setParameter('questionId', $questionId) ->getQuery() - ->getOneOrNullResult(); + ->getResult(); } } \ No newline at end of file diff --git a/app/Repositorys/ExamQuestionAnswerRepository.php b/app/Repositorys/ExamQuestionAnswerRepository.php new file mode 100644 index 0000000..e93f6c9 --- /dev/null +++ b/app/Repositorys/ExamQuestionAnswerRepository.php @@ -0,0 +1,25 @@ +entityManager = $entityManager; + } + + public function create(ExamQuestionAnswer $examQuestionAnswer) + { + $this->entityManager->persist($examQuestionAnswer); + $this->entityManager->flush(); + } +} \ No newline at end of file diff --git a/app/Repositorys/QuestionRepository.php b/app/Repositorys/QuestionRepository.php index 8c5d738..d8adf03 100644 --- a/app/Repositorys/QuestionRepository.php +++ b/app/Repositorys/QuestionRepository.php @@ -49,4 +49,15 @@ public function countQuestionsBySubject($subjectId) { return $this->entityManager->getRepository(Question::class)->count(['subject' => $subjectId]); } -} \ No newline at end of file +} + +// +//$queryBuilder = $this->entityManager->createQueryBuilder(); +// +//return $queryBuilder->select('question') +// ->from(Question::class, 'question') +// ->join(Answer::class, 'answer', 'WITH', 'question.id = answer.question') +// ->where('question.subject = :subject') +// ->setParameter('subject', $subjectId) +// ->getQuery() +// ->getArrayResult(); \ No newline at end of file diff --git a/app/Services/ExamAnswersService.php b/app/Services/ExamAnswersService.php deleted file mode 100644 index 08393c0..0000000 --- a/app/Services/ExamAnswersService.php +++ /dev/null @@ -1,38 +0,0 @@ -examAnswersRepository = $examAnswersRepository; - $this->answerRepository = $answerRepository; - $this->examQuestionsRepository = $examQuestionsRepository; - } - - public function create($examQuestions) - { - foreach ($examQuestions as $examQuestion) { - $correctAnswer = $this->answerRepository->getCorrectAnswer($examQuestion); - - $this->examAnswersRepository->create( - new ExamAnswer($examQuestion, $correctAnswer) - ); - } - } -} \ No newline at end of file diff --git a/app/Services/ExamQuestionAnswerService.php b/app/Services/ExamQuestionAnswerService.php new file mode 100644 index 0000000..7679920 --- /dev/null +++ b/app/Services/ExamQuestionAnswerService.php @@ -0,0 +1,59 @@ +questionRepository = $questionRepository; + $this->answerRepository = $answerRepository; + $this->examQuestionAnswerRepository = $examQuestionAnswerRepository; + } + + public function create(Exam $exam): void + { + $questions = $this->pickRandomQuestionsBySubject( + $exam->getSubject(), + $exam->getQuestionQuantity() + ); + + + foreach ($questions as $question) { + $answers = $this->answerRepository->getAnswersByQuestion($question->getId()); + + $examAnswerQuestion = new ExamQuestionAnswer( + $exam, + $question, + $answers + ); + + $this->examQuestionAnswerRepository->create($examAnswerQuestion); + } + } + + private function pickRandomQuestionsBySubject($subject, $questionsQuantity): array + { + $allQuestions = $this->questionRepository->getAllQuestionsBySubject($subject); + + shuffle($allQuestions); + + return array_slice($allQuestions, 0, $questionsQuantity); + } +} \ No newline at end of file diff --git a/app/Services/ExamQuestionsService.php b/app/Services/ExamQuestionsService.php deleted file mode 100644 index ea18c65..0000000 --- a/app/Services/ExamQuestionsService.php +++ /dev/null @@ -1,51 +0,0 @@ -questionRepository = $questionRepository; - $this->examQuestionsRepository = $examQuestionsRepository; - } - - public function create(Exam $exam) - { - $questions = $this->pickExamQuestions($exam); - $examQuestions = []; - - foreach ($questions as $examQuestion) { - $examQuestion = new ExamQuestion($examQuestion, $exam); - - $this->examQuestionsRepository->create($examQuestion); - $examQuestions[] = $examQuestion; - } - - return $examQuestions; - } - - private function pickExamQuestions(Exam $exam) - { - $allQuestions = $this->questionRepository->getAllQuestionsBySubject($exam->getSubject()); - - shuffle($allQuestions); - - return array_slice( - $allQuestions, - 0, - $exam->getQuestionQuantity() - ); - } -} \ No newline at end of file diff --git a/app/Services/ExamService.php b/app/Services/ExamService.php index 63ac5ea..08ee67c 100644 --- a/app/Services/ExamService.php +++ b/app/Services/ExamService.php @@ -16,27 +16,24 @@ class ExamService protected StudentRepository $studentRepository; protected QuestionRepository $questionRepository; - protected ExamQuestionsService $examQuestionsService; - protected ExamAnswersService $examAnswersService; + protected ExamQuestionAnswerService $examQuestionAnswerService; public function __construct( SubjectRepository $subjectRepository, ExamRepository $examRepository, StudentRepository $studentRepository, QuestionRepository $questionRepository, - ExamQuestionsService $examQuestionsService, - ExamAnswersService $examAnswersService + ExamQuestionAnswerService $examQuestionAnswerService ) { $this->subjectRepository = $subjectRepository; $this->examRepository = $examRepository; $this->studentRepository = $studentRepository; $this->questionRepository = $questionRepository; - $this->examQuestionsService = $examQuestionsService; - $this->examAnswersService = $examAnswersService; + $this->examQuestionAnswerService = $examQuestionAnswerService; } - public function create($studentId, $subjectId, $questionQuantity) + public function create($studentId, $subjectId, $questionQuantity): Exam { $this->validateExamRequest( [ @@ -47,11 +44,7 @@ public function create($studentId, $subjectId, $questionQuantity) ); $exam = $this->createExam($studentId, $subjectId, $questionQuantity); - - $examQuestions = $this->createExamQuestions($exam); - $this->createExamAnswers($examQuestions); - - return $exam; + $this->createExamQuestionAnswer($exam); } private function validateExamRequest($request) @@ -78,13 +71,8 @@ private function createExam($studentId, $subjectId, $questionQuantity) ); } - private function createExamQuestions(Exam $exam) - { - return $this->examQuestionsService->create($exam); - } - - private function createExamAnswers($examQuestions) + private function createExamQuestionAnswer(Exam $exam) { - $this->examAnswersService->create($examQuestions); + $this->examQuestionAnswerService->create($exam); } } \ No newline at end of file From 4bd10a79c117e495290775db178d566418b05abc Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Tue, 27 Sep 2022 16:55:11 -0300 Subject: [PATCH 12/54] cria rota de criacao e devolucao da prova --- Dockerfile | 2 +- app/Http/Controllers/ExamController.php | 4 +- app/Models/Answer.php | 2 +- app/Models/Exam.php | 3 + app/Models/Question.php | 12 ++++ .../{ExamQuestionAnswer.php => Snapshot.php} | 4 +- app/Models/Subject.php | 2 +- .../ExamQuestionAnswerRepository.php | 25 -------- app/Repositorys/SnapshotRepository.php | 36 +++++++++++ app/Services/ExamQuestionAnswerService.php | 59 ----------------- app/Services/ExamService.php | 28 ++++++-- app/Services/SnapshotService.php | 64 +++++++++++++++++++ 12 files changed, 142 insertions(+), 99 deletions(-) rename app/Models/{ExamQuestionAnswer.php => Snapshot.php} (95%) delete mode 100644 app/Repositorys/ExamQuestionAnswerRepository.php create mode 100644 app/Repositorys/SnapshotRepository.php delete mode 100644 app/Services/ExamQuestionAnswerService.php create mode 100644 app/Services/SnapshotService.php diff --git a/Dockerfile b/Dockerfile index 5256449..32ac93f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,7 +22,7 @@ COPY .docker/etc /etc RUN chmod -v +x /usr/sbin/entrypoint.local; \ chmod -v +x /usr/sbin/update-application; \ - mkdir /var/www/storage/proxies; \ +# mkdir /var/www/storage/proxies; \ chmod 777 /var/www/bootstrap -Rf; \ chmod 777 /var/www/storage -Rf; \ chown apache.apache /var/www -Rf; diff --git a/app/Http/Controllers/ExamController.php b/app/Http/Controllers/ExamController.php index 4b99030..405705d 100644 --- a/app/Http/Controllers/ExamController.php +++ b/app/Http/Controllers/ExamController.php @@ -26,9 +26,7 @@ public function store(Request $request): JsonResponse $request->get('question_quantity') ); - return response()->json([ - 'message' => 'The exam ' . $exam->getId() . ' are created successfully' - ]); + return response()->json($exam); }catch (\Exception $e){ diff --git a/app/Models/Answer.php b/app/Models/Answer.php index 5ca9505..8929d5f 100644 --- a/app/Models/Answer.php +++ b/app/Models/Answer.php @@ -22,7 +22,7 @@ class Answer #[Column(type:"boolean")] protected bool $is_correct; - #[ManyToOne(targetEntity: Question::class, cascade: ["persist"], inversedBy: "answer")] + #[ManyToOne(targetEntity: Question::class, cascade: ["persist"], inversedBy: "answers")] protected Question $question; public function __construct($answer, bool $is_correct, Question $question) diff --git a/app/Models/Exam.php b/app/Models/Exam.php index 77f9262..98422ea 100644 --- a/app/Models/Exam.php +++ b/app/Models/Exam.php @@ -42,6 +42,9 @@ public function __construct(Student $student, Subject $subject, $questionQuantit #[Column(type:"datetime", nullable: true)] protected string $finished_at; + #[OneToMany(mappedBy: "question", targetEntity: Answer::class, cascade: ["persist"], orphanRemoval: true)] + protected Collection $questions; + public function getId(): string { return $this->id; diff --git a/app/Models/Question.php b/app/Models/Question.php index 45f1434..311b86e 100644 --- a/app/Models/Question.php +++ b/app/Models/Question.php @@ -3,11 +3,14 @@ namespace App\Models; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\Entity; use Doctrine\ORM\Mapping\GeneratedValue; use Doctrine\ORM\Mapping\Id; use Doctrine\ORM\Mapping\ManyToOne; +use Doctrine\ORM\Mapping\OneToMany; use Doctrine\ORM\Mapping\Table; #[Entity] @@ -20,6 +23,9 @@ class Question #[ManyToOne(targetEntity: Subject::class, cascade: ["persist"], inversedBy: "question")] protected Subject $subject; + #[OneToMany(mappedBy: "question", targetEntity: Answer::class, cascade: ["persist"], orphanRemoval: true)] + protected Collection $answers; + #[Column(type:"string")] protected string $question; @@ -27,6 +33,7 @@ public function __construct(string $question, Subject $subject) { $this->question = $question; $this->subject = $subject; + $this->answers = new ArrayCollection(); } public function getId(): string @@ -43,4 +50,9 @@ public function getSubject(): string { return $this->subject; } + + public function getAnswers() + { + return $this->answers; + } } \ No newline at end of file diff --git a/app/Models/ExamQuestionAnswer.php b/app/Models/Snapshot.php similarity index 95% rename from app/Models/ExamQuestionAnswer.php rename to app/Models/Snapshot.php index 79db141..e63cf3d 100644 --- a/app/Models/ExamQuestionAnswer.php +++ b/app/Models/Snapshot.php @@ -11,7 +11,7 @@ #[Entity] #[Table(name:"exam_question_answer")] -class ExamQuestionAnswer +class Snapshot { public function __construct( Exam $exam, @@ -38,7 +38,7 @@ public function __construct( private string $answer; #[Column(type:"boolean")] - private string $isCorrect; + private bool $isCorrect; #[Column(type:"string", nullable: true)] protected string $student_answer; diff --git a/app/Models/Subject.php b/app/Models/Subject.php index ad871ea..d7b327a 100644 --- a/app/Models/Subject.php +++ b/app/Models/Subject.php @@ -33,7 +33,7 @@ public function getSubject(): string return $this->id; } - protected function getSubjectName(): string + public function getSubjectName(): string { return $this->name; } diff --git a/app/Repositorys/ExamQuestionAnswerRepository.php b/app/Repositorys/ExamQuestionAnswerRepository.php deleted file mode 100644 index e93f6c9..0000000 --- a/app/Repositorys/ExamQuestionAnswerRepository.php +++ /dev/null @@ -1,25 +0,0 @@ -entityManager = $entityManager; - } - - public function create(ExamQuestionAnswer $examQuestionAnswer) - { - $this->entityManager->persist($examQuestionAnswer); - $this->entityManager->flush(); - } -} \ No newline at end of file diff --git a/app/Repositorys/SnapshotRepository.php b/app/Repositorys/SnapshotRepository.php new file mode 100644 index 0000000..b4ba2cd --- /dev/null +++ b/app/Repositorys/SnapshotRepository.php @@ -0,0 +1,36 @@ +entityManager = $entityManager; + } + + public function create(Snapshot $snapshot) + { + $this->entityManager->persist($snapshot); + $this->entityManager->flush(); + } + + public function getByExamId($examId) + { + $queryBuilder = $this->entityManager->createQueryBuilder(); + + return $queryBuilder->select('snapshot') + ->from(Snapshot::class, 'snapshot') + ->where('snapshot.exam = :examSnapshot') + ->setParameter('examSnapshot', $examId) + ->getQuery() + ->getResult(); + } +} \ No newline at end of file diff --git a/app/Services/ExamQuestionAnswerService.php b/app/Services/ExamQuestionAnswerService.php deleted file mode 100644 index 7679920..0000000 --- a/app/Services/ExamQuestionAnswerService.php +++ /dev/null @@ -1,59 +0,0 @@ -questionRepository = $questionRepository; - $this->answerRepository = $answerRepository; - $this->examQuestionAnswerRepository = $examQuestionAnswerRepository; - } - - public function create(Exam $exam): void - { - $questions = $this->pickRandomQuestionsBySubject( - $exam->getSubject(), - $exam->getQuestionQuantity() - ); - - - foreach ($questions as $question) { - $answers = $this->answerRepository->getAnswersByQuestion($question->getId()); - - $examAnswerQuestion = new ExamQuestionAnswer( - $exam, - $question, - $answers - ); - - $this->examQuestionAnswerRepository->create($examAnswerQuestion); - } - } - - private function pickRandomQuestionsBySubject($subject, $questionsQuantity): array - { - $allQuestions = $this->questionRepository->getAllQuestionsBySubject($subject); - - shuffle($allQuestions); - - return array_slice($allQuestions, 0, $questionsQuantity); - } -} \ No newline at end of file diff --git a/app/Services/ExamService.php b/app/Services/ExamService.php index 08ee67c..dcbde68 100644 --- a/app/Services/ExamService.php +++ b/app/Services/ExamService.php @@ -4,6 +4,7 @@ use App\Models\Exam; +use App\Models\Question; use App\Repositorys\ExamRepository; use App\Repositorys\QuestionRepository; use App\Repositorys\StudentRepository; @@ -16,24 +17,24 @@ class ExamService protected StudentRepository $studentRepository; protected QuestionRepository $questionRepository; - protected ExamQuestionAnswerService $examQuestionAnswerService; + protected SnapshotService $snapshotService; public function __construct( SubjectRepository $subjectRepository, ExamRepository $examRepository, StudentRepository $studentRepository, QuestionRepository $questionRepository, - ExamQuestionAnswerService $examQuestionAnswerService + SnapshotService $snapshotService ) { $this->subjectRepository = $subjectRepository; $this->examRepository = $examRepository; $this->studentRepository = $studentRepository; $this->questionRepository = $questionRepository; - $this->examQuestionAnswerService = $examQuestionAnswerService; + $this->snapshotService = $snapshotService; } - public function create($studentId, $subjectId, $questionQuantity): Exam + public function create($studentId, $subjectId, $questionQuantity) { $this->validateExamRequest( [ @@ -44,7 +45,9 @@ public function create($studentId, $subjectId, $questionQuantity): Exam ); $exam = $this->createExam($studentId, $subjectId, $questionQuantity); - $this->createExamQuestionAnswer($exam); + $snapshot = $this->createExamSnapshot($exam); + + return $this->createResponse($exam, $snapshot); } private function validateExamRequest($request) @@ -71,8 +74,19 @@ private function createExam($studentId, $subjectId, $questionQuantity) ); } - private function createExamQuestionAnswer(Exam $exam) + private function createExamSnapshot(Exam $exam) + { + return $this->snapshotService->create($exam); + } + + private function createResponse(Exam $exam, $snapshot) { - $this->examQuestionAnswerService->create($exam); + return [ + 'exam' => $exam->getId(), + 'student' => $exam->getStudent()->getStudentName(), + 'subject' => $exam->getSubject()->getSubjectName(), + 'questionsAndAnswers' => $snapshot, + 'startedAt' => $exam->getCreatedAt()->format('Y-m-d H:i:s') + ]; } } \ No newline at end of file diff --git a/app/Services/SnapshotService.php b/app/Services/SnapshotService.php new file mode 100644 index 0000000..7eceb41 --- /dev/null +++ b/app/Services/SnapshotService.php @@ -0,0 +1,64 @@ +questionRepository = $questionRepository; + $this->answerRepository = $answerRepository; + $this->snapshotRepository = $snapshotRepository; + } + + public function create(Exam $exam): array + { + $questions = $this->pickRandomQuestionsBySubject( + $exam->getSubject(), + $exam->getQuestionQuantity() + ); + + foreach ($questions as $question) { + foreach ($question->getAnswers() as $answer) { + $snapshot = new Snapshot($exam, $question, $answer); + + $this->snapshotRepository->create($snapshot); + } + } + + $questionsAndAnswers = []; + + /** @var Question $question */ + foreach ($questions as $question) { + $questionsAndAnswers[$question->getQuestion()] = array_map(function ($answer) { + return $answer->getAnswer(); + }, $question->getAnswers()->toArray()); + } + + return $questionsAndAnswers; + } + + private function pickRandomQuestionsBySubject($subject, $questionsQuantity): array + { + $allQuestions = $this->questionRepository->getAllQuestionsBySubject($subject); + + + shuffle($allQuestions); + + return array_slice($allQuestions, 0, $questionsQuantity); + } +} \ No newline at end of file From cc987e79477e816269cf6af608becfd21996291b Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Tue, 27 Sep 2022 20:25:51 -0300 Subject: [PATCH 13/54] limpa arquivo de rotas web --- routes/web.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/routes/web.php b/routes/web.php index c37c1f6..9c8ba0b 100644 --- a/routes/web.php +++ b/routes/web.php @@ -17,19 +17,4 @@ */ -//Route::get('/subjects', [SubjectController::class, 'index']); -//Route::post('/subject/create', [SubjectController::class, 'store']); -//Route::delete('/subject/remove', [SubjectController::class, 'remove']); -// -//Route::get('/students', [StudentController::class, 'index']); -//Route::post('/student/create', [StudentController::class, 'store']); -//Route::delete('/student/remove', [StudentController::class, 'remove']); -// -//Route::get('/questions', [QuestionController::class, 'index']); -//Route::post('/question/create', [QuestionController::class, 'store']); -//Route::delete('/question/remove', [QuestionController::class, 'remove']); -// -//Route::get('/answers', [AnswerController::class, 'index']); -//Route::post('/answer/create', [AnswerController::class, 'store']); -//Route::delete('/answer/remove', [AnswerController::class, 'remove']); From 13e00438aedfd88967cc3ffd1f5b9d72dd44c2e0 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Tue, 27 Sep 2022 20:26:09 -0300 Subject: [PATCH 14/54] adiciona rota para receber respostas --- routes/api.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/routes/api.php b/routes/api.php index 8046c00..991f442 100644 --- a/routes/api.php +++ b/routes/api.php @@ -27,3 +27,5 @@ Route::post('/answer/create', [AnswerController::class, 'store']); Route::post('/exam/create', [ExamController::class, 'store']); + +Route::put('/exam/update/{exam}', [ExamController::class, 'update']); From 5ed5c440ed5bc90e560d66468e7139d9e92d6f04 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Tue, 27 Sep 2022 20:26:39 -0300 Subject: [PATCH 15/54] muda timezone da aplicacao para America/SP --- config/app.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/app.php b/config/app.php index 547e629..74443da 100644 --- a/config/app.php +++ b/config/app.php @@ -69,7 +69,7 @@ | */ - 'timezone' => 'UTC', + 'timezone' => 'America/Sao_Paulo', /* |-------------------------------------------------------------------------- From edfb76c6ebfb4dfbe0e0013c59a16c8489a1ba7b Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Tue, 27 Sep 2022 20:27:15 -0300 Subject: [PATCH 16/54] cria controller para receber respostas --- app/Http/Controllers/ExamController.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/Http/Controllers/ExamController.php b/app/Http/Controllers/ExamController.php index 405705d..11a04ce 100644 --- a/app/Http/Controllers/ExamController.php +++ b/app/Http/Controllers/ExamController.php @@ -33,4 +33,19 @@ public function store(Request $request): JsonResponse ErrorHandler::handleException($e); } } + + public function update(Request $request, $exam): JsonResponse + { + try{ + $examResult = $this->examService->update( + $exam, + $request->get('answers'), + $request->get('finishedAt'), + ); + + return response()->json($examResult); + }catch (\Exception $e){ + ErrorHandler::handleException($e); + } + } } \ No newline at end of file From 87e73297904e80787053c28155ed1e9374a7f881 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Tue, 27 Sep 2022 20:28:04 -0300 Subject: [PATCH 17/54] define retorno da funcao getExamById para um Exam --- app/Repositorys/ExamRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Repositorys/ExamRepository.php b/app/Repositorys/ExamRepository.php index 0f75f30..f5c91b0 100644 --- a/app/Repositorys/ExamRepository.php +++ b/app/Repositorys/ExamRepository.php @@ -22,7 +22,7 @@ public function create(Exam $exam): Exam return $exam; } - public function getById(string $id) + public function getById(string $id): Exam { return $this->entityManager->find( Exam::class, From abd73d278ee95fbe9efd061b0130b37a45d4fe0f Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Tue, 27 Sep 2022 20:28:54 -0300 Subject: [PATCH 18/54] cria validacao para nao processar provas com mais de uma hora de diferenca em relacao a data de criacao --- app/Services/ExamService.php | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/app/Services/ExamService.php b/app/Services/ExamService.php index dcbde68..7e7be77 100644 --- a/app/Services/ExamService.php +++ b/app/Services/ExamService.php @@ -9,6 +9,7 @@ use App\Repositorys\QuestionRepository; use App\Repositorys\StudentRepository; use App\Repositorys\SubjectRepository; +use Carbon\Carbon; class ExamService { @@ -20,11 +21,11 @@ class ExamService protected SnapshotService $snapshotService; public function __construct( - SubjectRepository $subjectRepository, - ExamRepository $examRepository, - StudentRepository $studentRepository, + SubjectRepository $subjectRepository, + ExamRepository $examRepository, + StudentRepository $studentRepository, QuestionRepository $questionRepository, - SnapshotService $snapshotService + SnapshotService $snapshotService ) { $this->subjectRepository = $subjectRepository; @@ -36,7 +37,7 @@ public function __construct( public function create($studentId, $subjectId, $questionQuantity) { - $this->validateExamRequest( + $this->validateExamCreation( [ 'studentId' => $studentId, 'subjectId' => $subjectId, @@ -47,10 +48,16 @@ public function create($studentId, $subjectId, $questionQuantity) $exam = $this->createExam($studentId, $subjectId, $questionQuantity); $snapshot = $this->createExamSnapshot($exam); - return $this->createResponse($exam, $snapshot); + return $this->createExamResponse($exam, $snapshot); } - private function validateExamRequest($request) + public function update($examId, $answers, $finishedAt) + { + $exam = $this->examRepository->getById($examId); + $this->validateExamUpdate($exam, $finishedAt); + } + + private function validateExamCreation($request) { foreach ($request as $key => $value) { if (!isset($value)) { @@ -58,11 +65,20 @@ private function validateExamRequest($request) } } - if($this->questionRepository->countQuestionsBySubject($request['subjectId']) < $request['questionQuantity']){ + if ($this->questionRepository->countQuestionsBySubject($request['subjectId']) < $request['questionQuantity']) { throw new \Exception("the quantity of questions is less than the requested quantity"); } } + private function validateExamUpdate(Exam $exam, $finishedAt) + { + $finishedAtToCarbon = Carbon::parse($finishedAt); + + if ($finishedAtToCarbon->diffInHours($exam->getCreatedAt()->format('Y-m-d H:i:s')) > 1) { + throw new \Exception("the exam has expired"); + } + } + private function createExam($studentId, $subjectId, $questionQuantity) { return $this->examRepository->create( @@ -79,7 +95,7 @@ private function createExamSnapshot(Exam $exam) return $this->snapshotService->create($exam); } - private function createResponse(Exam $exam, $snapshot) + private function createExamResponse(Exam $exam, $snapshot) { return [ 'exam' => $exam->getId(), From e6e9b6906059f27821f641d7aee58a5257301658 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 28 Sep 2022 00:03:24 -0300 Subject: [PATCH 19/54] modifica campo de score para float em vez de int --- app/Models/Exam.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/Exam.php b/app/Models/Exam.php index 98422ea..f8851ec 100644 --- a/app/Models/Exam.php +++ b/app/Models/Exam.php @@ -33,7 +33,7 @@ public function __construct(Student $student, Subject $subject, $questionQuantit #[ManyToOne(targetEntity: Student::class, cascade: ["persist"], inversedBy: "student")] protected Student $student; - #[Column(type:"integer", nullable: true)] + #[Column(type:"float", nullable: true)] protected int $score; #[Column(type:"integer")] From 580b444c9a2d4602db96f060318062f5b712df23 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 28 Sep 2022 00:04:58 -0300 Subject: [PATCH 20/54] cria metodo para finalizar exame --- app/Repositorys/ExamRepository.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/app/Repositorys/ExamRepository.php b/app/Repositorys/ExamRepository.php index f5c91b0..507153d 100644 --- a/app/Repositorys/ExamRepository.php +++ b/app/Repositorys/ExamRepository.php @@ -29,4 +29,21 @@ public function getById(string $id): Exam $id ); } + + public function finishExam(Exam $exam, $score, $finishedAt) + { + $queryBuilder = $this->entityManager->createQueryBuilder(); + + return $queryBuilder->update(Exam::class, 'exam') + ->set('exam.score', ':score') + ->set('exam.finished_at', ':finishedAt') + ->where('exam = :exam') + ->setParameters([ + 'exam' => $exam, + 'score' => $score, + 'finishedAt' => $finishedAt, + ]) + ->getQuery() + ->execute(); + } } \ No newline at end of file From 46c46d5ad3472b0bdf68cb8fbeb9130e6c7e4f24 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 28 Sep 2022 00:06:36 -0300 Subject: [PATCH 21/54] cria metodo que pega questoes corretas por exam --- app/Repositorys/SnapshotRepository.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/app/Repositorys/SnapshotRepository.php b/app/Repositorys/SnapshotRepository.php index b4ba2cd..9828abb 100644 --- a/app/Repositorys/SnapshotRepository.php +++ b/app/Repositorys/SnapshotRepository.php @@ -3,6 +3,7 @@ namespace App\Repositorys; +use App\Models\Exam; use App\Models\Snapshot; use Doctrine\ORM\EntityManager; @@ -26,11 +27,25 @@ public function getByExamId($examId) { $queryBuilder = $this->entityManager->createQueryBuilder(); - return $queryBuilder->select('snapshot') + return $queryBuilder->select('snapshot') ->from(Snapshot::class, 'snapshot') ->where('snapshot.exam = :examSnapshot') ->setParameter('examSnapshot', $examId) ->getQuery() ->getResult(); } + + public function getCorrectAnswersByExam(Exam $exam) + { + $queryBuilder = $this->entityManager->createQueryBuilder(); + + return $queryBuilder->select('snapshot.question, snapshot.answer') + ->from(Snapshot::class, 'snapshot') + ->where('snapshot.exam = :exam') + ->andWhere('snapshot.isCorrect = true') + ->indexBy('snapshot', 'snapshot.question') + ->setParameter('exam', $exam) + ->getQuery() + ->getResult(); + } } \ No newline at end of file From a0935faf51cb3244ccea8ea4038b71a945a77a8e Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 28 Sep 2022 00:07:10 -0300 Subject: [PATCH 22/54] cria metodo que pega registra resposta do aluno --- app/Repositorys/SnapshotRepository.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/app/Repositorys/SnapshotRepository.php b/app/Repositorys/SnapshotRepository.php index 9828abb..bfd9a9d 100644 --- a/app/Repositorys/SnapshotRepository.php +++ b/app/Repositorys/SnapshotRepository.php @@ -48,4 +48,21 @@ public function getCorrectAnswersByExam(Exam $exam) ->getQuery() ->getResult(); } + + public function setStudentAnswersByExamAndQuestion(Exam $exam, $question, $studentAnswer) + { + $queryBuilder = $this->entityManager->createQueryBuilder(); + + return $queryBuilder->update(Snapshot::class, 'snapshot') + ->set('snapshot.student_answer', ':studentAnswer') + ->where('snapshot.exam = :exam') + ->andWhere('snapshot.question = :question') + ->setParameters([ + 'exam' => $exam, + 'question' => $question, + 'studentAnswer' => $studentAnswer + ]) + ->getQuery() + ->execute(); + } } \ No newline at end of file From 1ce7390a190c721f1516976c50c19902e674e10d Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 28 Sep 2022 00:07:31 -0300 Subject: [PATCH 23/54] cria metodo que pega conta as respostas corretas do aluno --- app/Repositorys/SnapshotRepository.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/Repositorys/SnapshotRepository.php b/app/Repositorys/SnapshotRepository.php index bfd9a9d..6240e6c 100644 --- a/app/Repositorys/SnapshotRepository.php +++ b/app/Repositorys/SnapshotRepository.php @@ -65,4 +65,19 @@ public function setStudentAnswersByExamAndQuestion(Exam $exam, $question, $stude ->getQuery() ->execute(); } + + + public function getScoreByExam(Exam $exam) + { + $queryBuilder = $this->entityManager->createQueryBuilder(); + + return $queryBuilder->select('count(snapshot.id)') + ->from(Snapshot::class, 'snapshot') + ->where('snapshot.exam = :exam') + ->andWhere('snapshot.isCorrect = true') + ->andWhere('snapshot.student_answer = snapshot.answer') + ->setParameter('exam', $exam) + ->getQuery() + ->getSingleScalarResult(); + } } \ No newline at end of file From 5a1bbef572e8f99a4b18ba97dee8fbf810250b70 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 28 Sep 2022 00:10:58 -0300 Subject: [PATCH 24/54] registra resposta do studen --- app/Services/ExamService.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/app/Services/ExamService.php b/app/Services/ExamService.php index 7e7be77..d8314be 100644 --- a/app/Services/ExamService.php +++ b/app/Services/ExamService.php @@ -5,8 +5,10 @@ use App\Models\Exam; use App\Models\Question; +use App\Models\Snapshot; use App\Repositorys\ExamRepository; use App\Repositorys\QuestionRepository; +use App\Repositorys\SnapshotRepository; use App\Repositorys\StudentRepository; use App\Repositorys\SubjectRepository; use Carbon\Carbon; @@ -17,15 +19,19 @@ class ExamService protected ExamRepository $examRepository; protected StudentRepository $studentRepository; protected QuestionRepository $questionRepository; + protected SnapshotRepository $snapshotRepository; protected SnapshotService $snapshotService; + const BASE_NOTE = 10; + public function __construct( SubjectRepository $subjectRepository, ExamRepository $examRepository, StudentRepository $studentRepository, QuestionRepository $questionRepository, - SnapshotService $snapshotService + SnapshotService $snapshotService, + SnapshotRepository $snapshotRepository ) { $this->subjectRepository = $subjectRepository; @@ -33,6 +39,7 @@ public function __construct( $this->studentRepository = $studentRepository; $this->questionRepository = $questionRepository; $this->snapshotService = $snapshotService; + $this->snapshotRepository = $snapshotRepository; } public function create($studentId, $subjectId, $questionQuantity) @@ -54,7 +61,11 @@ public function create($studentId, $subjectId, $questionQuantity) public function update($examId, $answers, $finishedAt) { $exam = $this->examRepository->getById($examId); + $this->validateExamUpdate($exam, $finishedAt); + + $this->registerStudentAnswers($answers, $exam); + } private function validateExamCreation($request) @@ -105,4 +116,12 @@ private function createExamResponse(Exam $exam, $snapshot) 'startedAt' => $exam->getCreatedAt()->format('Y-m-d H:i:s') ]; } + + public function registerStudentAnswers($answers, Exam $exam): void + { + foreach ($answers as $question => $answer) { + $this->snapshotRepository + ->setStudentAnswersByExamAndQuestion($exam, $question, $answer); + } + } } \ No newline at end of file From 43c2bdcd387626535c76e7f9e5ad936e4c1b1eb2 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 28 Sep 2022 00:12:06 -0300 Subject: [PATCH 25/54] calcula resultado do exame --- app/Services/ExamService.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/Services/ExamService.php b/app/Services/ExamService.php index d8314be..c47daeb 100644 --- a/app/Services/ExamService.php +++ b/app/Services/ExamService.php @@ -66,6 +66,8 @@ public function update($examId, $answers, $finishedAt) $this->registerStudentAnswers($answers, $exam); + $score = $this->calculateExamResult($exam); + } private function validateExamCreation($request) @@ -124,4 +126,12 @@ public function registerStudentAnswers($answers, Exam $exam): void ->setStudentAnswersByExamAndQuestion($exam, $question, $answer); } } + + private function calculateExamResult(Exam $exam) + { + $score = $this->snapshotRepository->getScoreByExam($exam); + $questionValue = self::BASE_NOTE / $exam->getQuestionQuantity(); + + return sprintf("%.2f",$score * $questionValue); + } } \ No newline at end of file From ab5867a40aeaed8604a7582a0d47f58f213b264d Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 28 Sep 2022 00:12:18 -0300 Subject: [PATCH 26/54] encerra exame --- app/Services/ExamService.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Services/ExamService.php b/app/Services/ExamService.php index c47daeb..c197798 100644 --- a/app/Services/ExamService.php +++ b/app/Services/ExamService.php @@ -68,6 +68,7 @@ public function update($examId, $answers, $finishedAt) $score = $this->calculateExamResult($exam); + $this->examRepository->finishExam($exam, $score, $finishedAt); } private function validateExamCreation($request) From 760cbc7c11544f63ea4da9d1f4e342faddcc070d Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Thu, 29 Sep 2022 20:03:50 -0300 Subject: [PATCH 27/54] retorna snapshot da prova concluida --- app/Http/Controllers/AnswerController.php | 2 ++ app/Models/Exam.php | 2 +- app/Models/Snapshot.php | 4 ++-- app/Repositorys/SnapshotRepository.php | 19 +++---------------- app/Services/ExamService.php | 7 +++++++ 5 files changed, 15 insertions(+), 19 deletions(-) diff --git a/app/Http/Controllers/AnswerController.php b/app/Http/Controllers/AnswerController.php index c8af435..a6cf85a 100644 --- a/app/Http/Controllers/AnswerController.php +++ b/app/Http/Controllers/AnswerController.php @@ -20,6 +20,8 @@ public function __construct(AnswerService $answerService) public function store(Request $request): JsonResponse { try{ + + $answer = $this->answerService ->create( $request->get('answer'), diff --git a/app/Models/Exam.php b/app/Models/Exam.php index f8851ec..726c991 100644 --- a/app/Models/Exam.php +++ b/app/Models/Exam.php @@ -40,7 +40,7 @@ public function __construct(Student $student, Subject $subject, $questionQuantit protected int $question_quantity; #[Column(type:"datetime", nullable: true)] - protected string $finished_at; + protected \DateTime $finished_at; #[OneToMany(mappedBy: "question", targetEntity: Answer::class, cascade: ["persist"], orphanRemoval: true)] protected Collection $questions; diff --git a/app/Models/Snapshot.php b/app/Models/Snapshot.php index e63cf3d..2f02924 100644 --- a/app/Models/Snapshot.php +++ b/app/Models/Snapshot.php @@ -22,7 +22,7 @@ public function __construct( $this->exam = $exam; $this->question = $question->getQuestion(); $this->answer = $answer->getAnswer(); - $this->isCorrect = $answer->getIsCorrect(); + $this->answerIsCorrect = $answer->getIsCorrect(); } #[Id, Column(type:"guid"), GeneratedValue(strategy: 'UUID')] @@ -38,7 +38,7 @@ public function __construct( private string $answer; #[Column(type:"boolean")] - private bool $isCorrect; + private bool $answerIsCorrect; #[Column(type:"string", nullable: true)] protected string $student_answer; diff --git a/app/Repositorys/SnapshotRepository.php b/app/Repositorys/SnapshotRepository.php index 6240e6c..0a7bf32 100644 --- a/app/Repositorys/SnapshotRepository.php +++ b/app/Repositorys/SnapshotRepository.php @@ -23,27 +23,14 @@ public function create(Snapshot $snapshot) $this->entityManager->flush(); } - public function getByExamId($examId) - { - $queryBuilder = $this->entityManager->createQueryBuilder(); - - return $queryBuilder->select('snapshot') - ->from(Snapshot::class, 'snapshot') - ->where('snapshot.exam = :examSnapshot') - ->setParameter('examSnapshot', $examId) - ->getQuery() - ->getResult(); - } - public function getCorrectAnswersByExam(Exam $exam) { $queryBuilder = $this->entityManager->createQueryBuilder(); - return $queryBuilder->select('snapshot.question, snapshot.answer') + return $queryBuilder->select('snapshot.question, snapshot.student_answer, snapshot.answer correctAnswer') ->from(Snapshot::class, 'snapshot') ->where('snapshot.exam = :exam') - ->andWhere('snapshot.isCorrect = true') - ->indexBy('snapshot', 'snapshot.question') + ->andWhere('snapshot.answerIsCorrect = true') ->setParameter('exam', $exam) ->getQuery() ->getResult(); @@ -74,7 +61,7 @@ public function getScoreByExam(Exam $exam) return $queryBuilder->select('count(snapshot.id)') ->from(Snapshot::class, 'snapshot') ->where('snapshot.exam = :exam') - ->andWhere('snapshot.isCorrect = true') + ->andWhere('snapshot.answerIsCorrect = true') ->andWhere('snapshot.student_answer = snapshot.answer') ->setParameter('exam', $exam) ->getQuery() diff --git a/app/Services/ExamService.php b/app/Services/ExamService.php index c197798..a23d00f 100644 --- a/app/Services/ExamService.php +++ b/app/Services/ExamService.php @@ -69,6 +69,13 @@ public function update($examId, $answers, $finishedAt) $score = $this->calculateExamResult($exam); $this->examRepository->finishExam($exam, $score, $finishedAt); + + $finalSnapshot = $this->snapshotRepository->getCorrectAnswersByExam($exam); + + return [ + 'score' => $score, + 'Exam' => $finalSnapshot + ]; } private function validateExamCreation($request) From c5a402782b6d11735a92ed833036b0709f66be91 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Thu, 29 Sep 2022 20:18:56 -0300 Subject: [PATCH 28/54] evita que uma questao possa ter mais de uma resposta correta --- app/Http/Controllers/AnswerController.php | 24 +++++++++++++++++++++-- app/Models/Answer.php | 4 ++-- app/Models/Question.php | 10 +++++++--- app/Models/Snapshot.php | 2 +- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/app/Http/Controllers/AnswerController.php b/app/Http/Controllers/AnswerController.php index a6cf85a..333b23a 100644 --- a/app/Http/Controllers/AnswerController.php +++ b/app/Http/Controllers/AnswerController.php @@ -3,6 +3,8 @@ namespace App\Http\Controllers; +use App\Models\Question; +use App\Repositorys\QuestionRepository; use App\Services\AnswerService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -10,17 +12,19 @@ class AnswerController extends Controller { + protected QuestionRepository $questionRepository; protected AnswerService $answerService; - public function __construct(AnswerService $answerService) + public function __construct(AnswerService $answerService, QuestionRepository $questionRepository) { $this->answerService = $answerService; + $this->questionRepository = $questionRepository; } public function store(Request $request): JsonResponse { try{ - + $this->validateAnswerRequest($request->get('question_id'), $request->get('is_correct')); $answer = $this->answerService ->create( @@ -37,4 +41,20 @@ public function store(Request $request): JsonResponse ErrorHandler::handleException($e); } } + + private function validateAnswerRequest($questionId, $isCorrect) + { + /** + * @var Question $question + */ + $question = $this->questionRepository->getById($questionId); + + if(!$question){ + throw new \Exception("The question with id $questionId not exists"); + } + + if($isCorrect === true && $question->hasCorrectAnswer()){ + throw new \Exception("The question already have a correct answer. The max amount of correct answers is 1"); + } + } } \ No newline at end of file diff --git a/app/Models/Answer.php b/app/Models/Answer.php index 8929d5f..44d239a 100644 --- a/app/Models/Answer.php +++ b/app/Models/Answer.php @@ -42,9 +42,9 @@ public function getAnswer(): string return $this->answer; } - public function getIsCorrect(): string + public function isCorrect(): bool { - return $this->is_correct; + return (bool)$this->is_correct; } public function getQuestionId(): string diff --git a/app/Models/Question.php b/app/Models/Question.php index 311b86e..fd20f18 100644 --- a/app/Models/Question.php +++ b/app/Models/Question.php @@ -46,13 +46,17 @@ public function getQuestion(): string return $this->question; } - public function getSubject(): string + public function getSubject(): Subject { return $this->subject; } - public function getAnswers() + public function hasCorrectAnswer() { - return $this->answers; + foreach ($this->answers as $answer) { + if ($answer->isCorrect()) { + return true; + } + } } } \ No newline at end of file diff --git a/app/Models/Snapshot.php b/app/Models/Snapshot.php index 2f02924..cf97f12 100644 --- a/app/Models/Snapshot.php +++ b/app/Models/Snapshot.php @@ -22,7 +22,7 @@ public function __construct( $this->exam = $exam; $this->question = $question->getQuestion(); $this->answer = $answer->getAnswer(); - $this->answerIsCorrect = $answer->getIsCorrect(); + $this->answerIsCorrect = $answer->isCorrect(); } #[Id, Column(type:"guid"), GeneratedValue(strategy: 'UUID')] From 5c5c4e7a192d32edc661d217ab61d1da6669e2db Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 5 Oct 2022 15:56:17 -0300 Subject: [PATCH 29/54] add tests to studentService --- tests/Feature/ExampleTest.php | 21 -------- tests/Unit/ExampleTest.php | 18 ------- tests/Unit/Service/AnswerServiceTest.php | 9 ++++ tests/Unit/Service/ExamServiceTest.php | 9 ++++ tests/Unit/Service/QuestionServiceTest.php | 9 ++++ tests/Unit/Service/SnapshotServiceTest.php | 9 ++++ tests/Unit/Service/StudentServiceTest.php | 55 +++++++++++++++++++ tests/Unit/Service/SubjectServiceTest.php | 61 ++++++++++++++++++++++ 8 files changed, 152 insertions(+), 39 deletions(-) delete mode 100644 tests/Feature/ExampleTest.php delete mode 100644 tests/Unit/ExampleTest.php create mode 100644 tests/Unit/Service/AnswerServiceTest.php create mode 100644 tests/Unit/Service/ExamServiceTest.php create mode 100644 tests/Unit/Service/QuestionServiceTest.php create mode 100644 tests/Unit/Service/SnapshotServiceTest.php create mode 100644 tests/Unit/Service/StudentServiceTest.php create mode 100644 tests/Unit/Service/SubjectServiceTest.php diff --git a/tests/Feature/ExampleTest.php b/tests/Feature/ExampleTest.php deleted file mode 100644 index 1eafba6..0000000 --- a/tests/Feature/ExampleTest.php +++ /dev/null @@ -1,21 +0,0 @@ -get('/'); - - $response->assertStatus(200); - } -} diff --git a/tests/Unit/ExampleTest.php b/tests/Unit/ExampleTest.php deleted file mode 100644 index e5c5fef..0000000 --- a/tests/Unit/ExampleTest.php +++ /dev/null @@ -1,18 +0,0 @@ -assertTrue(true); - } -} diff --git a/tests/Unit/Service/AnswerServiceTest.php b/tests/Unit/Service/AnswerServiceTest.php new file mode 100644 index 0000000..44653fe --- /dev/null +++ b/tests/Unit/Service/AnswerServiceTest.php @@ -0,0 +1,9 @@ +createMock(Student::class); + + $studentRepositoryMock = $this->createMock(StudentRepository::class); + $studentRepositoryMock->method('create')->willReturn($studentMock); + + $studentService = new StudentService($studentRepositoryMock); + + // when + $result = $studentService->create('Luiz Henrique'); + + // then + $this->assertInstanceOf(Student::class, $result); + } + + public function testCreateFunctionShouldReturnAExceptionIfSubjectIsEmpty() + { + $this->expectException(\Exception::class); + + // given + $studentRepositoryMock = $this->createMock(StudentRepository::class); + + $studentService = new StudentService($studentRepositoryMock); + + // when + $studentService->create(null); + } + + public function testCreateFunctionShouldReturnAExceptionIfSubjectIsLesserThanThreeCaracters() + { + $this->expectException(\Exception::class); + + // given + $studentRepositoryMock = $this->createMock(StudentRepository::class); + + $studentService = new StudentService($studentRepositoryMock); + + // when + $studentService->create('an'); + } +} \ No newline at end of file diff --git a/tests/Unit/Service/SubjectServiceTest.php b/tests/Unit/Service/SubjectServiceTest.php new file mode 100644 index 0000000..d09c111 --- /dev/null +++ b/tests/Unit/Service/SubjectServiceTest.php @@ -0,0 +1,61 @@ +createMock(Subject::class); + + $subjectRepositoryMock = $this->createMock(SubjectRepository::class); + $subjectRepositoryMock->method('create')->willReturn($subjectMock); + + $subjectService = new SubjectService($subjectRepositoryMock); + + // when + $result = $subjectService->create('Matematica'); + + // then + $this->assertInstanceOf(Subject::class, $result); + } + + public function testCreateFunctionShouldReturnAExceptionIfSubjectIsEmpty() + { + $this->expectException(\Exception::class); + + // given + $subjectMock = $this->createMock(Subject::class); + + $subjectRepositoryMock = $this->createMock(SubjectRepository::class); + $subjectRepositoryMock->method('create')->willReturn($subjectMock); + + $subjectService = new SubjectService($subjectRepositoryMock); + + // when + $subjectService->create(null); + } + + public function testCreateFunctionShouldReturnAExceptionIfSubjectIsLesserThanThreeCaracters() + { + $this->expectException(\Exception::class); + + // given + $subjectMock = $this->createMock(Subject::class); + + $subjectRepositoryMock = $this->createMock(SubjectRepository::class); + $subjectRepositoryMock->method('create')->willReturn($subjectMock); + + $subjectService = new SubjectService($subjectRepositoryMock); + + // when + $subjectService->create('aa'); + } + +} From 7c8bcf27af7b462467ffd365eaac6ed52e9dfc8e Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 5 Oct 2022 15:56:58 -0300 Subject: [PATCH 30/54] add tests to subjectService --- tests/Unit/Service/SubjectServiceTest.php | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/tests/Unit/Service/SubjectServiceTest.php b/tests/Unit/Service/SubjectServiceTest.php index d09c111..7e38f8b 100644 --- a/tests/Unit/Service/SubjectServiceTest.php +++ b/tests/Unit/Service/SubjectServiceTest.php @@ -1,6 +1,6 @@ expectException(\Exception::class); // given - $subjectMock = $this->createMock(Subject::class); - $subjectRepositoryMock = $this->createMock(SubjectRepository::class); - $subjectRepositoryMock->method('create')->willReturn($subjectMock); - $subjectService = new SubjectService($subjectRepositoryMock); // when @@ -47,15 +43,10 @@ public function testCreateFunctionShouldReturnAExceptionIfSubjectIsLesserThanThr $this->expectException(\Exception::class); // given - $subjectMock = $this->createMock(Subject::class); - $subjectRepositoryMock = $this->createMock(SubjectRepository::class); - $subjectRepositoryMock->method('create')->willReturn($subjectMock); - $subjectService = new SubjectService($subjectRepositoryMock); // when - $subjectService->create('aa'); + $subjectService->create('ob'); } - } From a51cb373270c76ebd700c481e95e8a2536c795e7 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 5 Oct 2022 15:57:52 -0300 Subject: [PATCH 31/54] renomeia variavel --- app/Services/SubjectService.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Services/SubjectService.php b/app/Services/SubjectService.php index 36087f1..ccbd875 100644 --- a/app/Services/SubjectService.php +++ b/app/Services/SubjectService.php @@ -24,13 +24,13 @@ public function create($subjectName): Subject return $this->subjectRepository->create(new Subject($subjectName)); } - private function validateSubjectRequest($subject) + private function validateSubjectRequest($subjectName) { - if (empty($subject)) { + if (empty($subjectName)) { throw new \Exception('The subject is empty'); } - if (strlen($subject) < 3) { + if (strlen($subjectName) < 3) { throw new \Exception('The subject name is too short'); } } From 652096ee3ca12e8f84a3ccd99c761a9d94b313e7 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 5 Oct 2022 16:29:41 -0300 Subject: [PATCH 32/54] adiciona testes ao service de questions --- app/Services/QuestionService.php | 2 +- tests/Unit/Service/QuestionServiceTest.php | 60 +++++++++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/app/Services/QuestionService.php b/app/Services/QuestionService.php index 975a57b..7530256 100644 --- a/app/Services/QuestionService.php +++ b/app/Services/QuestionService.php @@ -36,7 +36,7 @@ private function validateQuestionRequest($question, $subjectId) } if ($this->subjectRepository->getById($subjectId) === null) { - throw new \Exception('The question not have a subject'); + throw new \Exception('This question not have a subject'); } } } diff --git a/tests/Unit/Service/QuestionServiceTest.php b/tests/Unit/Service/QuestionServiceTest.php index 1bea825..1773746 100644 --- a/tests/Unit/Service/QuestionServiceTest.php +++ b/tests/Unit/Service/QuestionServiceTest.php @@ -3,7 +3,65 @@ namespace Tests\Unit\Service; -class QuestionServiceTest +use App\Models\Question; +use App\Models\Subject; +use App\Repositorys\QuestionRepository; +use App\Repositorys\SubjectRepository; +use App\Services\QuestionService; +use Tests\TestCase; + +class QuestionServiceTest extends TestCase { + public function testCreateFunctionShouldReturnAQuestion() + { + // given + $questionMock = $this->createMock(Question::class); + $subjectMock = $this->createMock(Subject::class); + + $questionRepositoryMock = $this->createMock(QuestionRepository::class); + $questionRepositoryMock->method('create')->willReturn($questionMock); + + $subjectRepositoryMock = $this->createMock(SubjectRepository::class); + $subjectRepositoryMock->method('getById')->willReturn($subjectMock); + + $questionService = new QuestionService($subjectRepositoryMock, $questionRepositoryMock); + + // when + $result = $questionService->create('Quem descobriu o Brasil?', '001aeb1d-9671-b55a-287e-2afbb7d936b0'); + + // then + $this->assertInstanceOf(Question::class, $result); + } + + public function testCreateFunctionShouldReturnAExceptionIfQuestionIsEmpty() + { + $this->expectException(\Exception::class); +// $this->expectExceptionMessage('The question is em'); +// $this->expectExceptionMessage('The question is empty'); + + $questionRepositoryMock = $this->createMock(QuestionRepository::class); + $subjectRepositoryMock = $this->createMock(SubjectRepository::class); + + $questionService = new QuestionService($subjectRepositoryMock, $questionRepositoryMock); + + $questionService->create('', '001aeb1d-2569-a56d-287e-2afbb7d936b0'); + } + + public function testCreateFunctionShouldReturnAExceptionIfQuestionDoenstHaveSubject() + { + $this->expectException(\Exception::class); + $this->expectExceptionMessage('This question not have a subject'); + + $questionMock = $this->createMock(Question::class); + + $questionRepositoryMock = $this->createMock(QuestionRepository::class); + $questionRepositoryMock->method('create')->willReturn($questionMock); + + $subjectRepositoryMock = $this->createMock(SubjectRepository::class); + $subjectRepositoryMock->method('getById')->willReturn(null); + + $questionService = new QuestionService($subjectRepositoryMock, $questionRepositoryMock); + $questionService->create('Quem descobriu o Brasil?', '001aeb1d-2569-a56d-287e-2afbb7d936b0'); + } } \ No newline at end of file From 162661694b0cf115d9718a26226282991db1d97d Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 5 Oct 2022 16:32:42 -0300 Subject: [PATCH 33/54] muda nome de testes em studen e subject test --- tests/Unit/Service/StudentServiceTest.php | 4 ++-- tests/Unit/Service/SubjectServiceTest.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Unit/Service/StudentServiceTest.php b/tests/Unit/Service/StudentServiceTest.php index 7354bc6..618d327 100644 --- a/tests/Unit/Service/StudentServiceTest.php +++ b/tests/Unit/Service/StudentServiceTest.php @@ -27,7 +27,7 @@ public function testCreateFunctionShouldReturnAStudent() $this->assertInstanceOf(Student::class, $result); } - public function testCreateFunctionShouldReturnAExceptionIfSubjectIsEmpty() + public function testCreateFunctionShouldReturnAExceptionIfStudentNameIsEmpty() { $this->expectException(\Exception::class); @@ -40,7 +40,7 @@ public function testCreateFunctionShouldReturnAExceptionIfSubjectIsEmpty() $studentService->create(null); } - public function testCreateFunctionShouldReturnAExceptionIfSubjectIsLesserThanThreeCaracters() + public function testCreateFunctionShouldReturnAExceptionIfStudentNameHasLessThanThreeCaracters() { $this->expectException(\Exception::class); diff --git a/tests/Unit/Service/SubjectServiceTest.php b/tests/Unit/Service/SubjectServiceTest.php index 7e38f8b..1a1cf83 100644 --- a/tests/Unit/Service/SubjectServiceTest.php +++ b/tests/Unit/Service/SubjectServiceTest.php @@ -38,7 +38,7 @@ public function testCreateFunctionShouldReturnAExceptionIfSubjectIsEmpty() $subjectService->create(null); } - public function testCreateFunctionShouldReturnAExceptionIfSubjectIsLesserThanThreeCaracters() + public function testCreateFunctionShouldReturnAExceptionIfSubjectHasLessThanThreeCaracters() { $this->expectException(\Exception::class); From 384e73b1ad3bc1bc2e8b278ccd8e741c582f60b9 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 5 Oct 2022 18:56:06 -0300 Subject: [PATCH 34/54] retira import inutil de answerRepository --- app/Repositorys/AnswerRepository.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/Repositorys/AnswerRepository.php b/app/Repositorys/AnswerRepository.php index 2353b9a..dd4f583 100644 --- a/app/Repositorys/AnswerRepository.php +++ b/app/Repositorys/AnswerRepository.php @@ -4,7 +4,6 @@ use App\Models\Answer; -use App\Models\Question; use Doctrine\ORM\EntityManager; class AnswerRepository From 250dc9b29f076e5a4a34a8d777554e3795c4d75c Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 5 Oct 2022 18:58:03 -0300 Subject: [PATCH 35/54] modifica forma de validacao da request de answer --- app/Services/AnswerService.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/app/Services/AnswerService.php b/app/Services/AnswerService.php index 3674bc0..50afffc 100644 --- a/app/Services/AnswerService.php +++ b/app/Services/AnswerService.php @@ -21,11 +21,7 @@ public function __construct( $this->questionRepository = $questionRepository; } - public function create( - $answer, - $questionId, - $isCorrect - ) : Answer + public function create($answer, $questionId, $isCorrect) : Answer { $this->validateAnswerRequest( @@ -47,8 +43,8 @@ public function create( private function validateAnswerRequest($request) { - foreach ($request as $key => $value) { - if (!isset($value)) { + foreach ($request as $key) { + if (empty($key)) { throw new \Exception("the $key value not can be empty!"); } } From 9af67d4c8f260a7431ef8fba4f86d640c43263f5 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 5 Oct 2022 18:59:42 -0300 Subject: [PATCH 36/54] retira comentarios do test --- tests/Unit/Service/AnswerServiceTest.php | 87 +++++++++++++++++++++- tests/Unit/Service/QuestionServiceTest.php | 3 - 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/tests/Unit/Service/AnswerServiceTest.php b/tests/Unit/Service/AnswerServiceTest.php index 44653fe..6fdee55 100644 --- a/tests/Unit/Service/AnswerServiceTest.php +++ b/tests/Unit/Service/AnswerServiceTest.php @@ -3,7 +3,92 @@ namespace Tests\Unit\Service; -class AnswerServiceTest +use App\Models\Answer; +use App\Models\Question; +use App\Repositorys\AnswerRepository; +use App\Repositorys\QuestionRepository; +use App\Services\AnswerService; +use PHPUnit\Framework\TestCase; + + +class AnswerServiceTest extends TestCase { + public function testCreateFunctionShouldReturnAAnswer() + { + // given + $questionMock = $this->createMock(Question::class); + + $questionRepositoryMock = $this->createMock(QuestionRepository::class); + $questionRepositoryMock->method('getById')->willReturn($questionMock); + + $answerRepositoryMock = $this->createMock(AnswerRepository::class); + + $answerService = new AnswerService($answerRepositoryMock, $questionRepositoryMock); + + // when + $result = $answerService->create( + 'Neymar Jr', + '001aeb1d-2569-a56d-287e-2afbbc9637a6', + true + ); + + // then + $this->assertInstanceOf(Answer::class, $result); + } + + public function testCreateFunctionShouldReturnAExceptionIfAnswerIsEmpty() + { + $this->expectException(\Exception::class); + + // given + $questionRepositoryMock = $this->createMock(QuestionRepository::class); + $answerRepositoryMock = $this->createMock(AnswerRepository::class); + + $answerService = new AnswerService($answerRepositoryMock, $questionRepositoryMock); + + // when + $result = $answerService->create( + '', + '001aeb1d-2569-a56d-287e-2afbbc9637a6', + true + ); + } + + public function testCreateFunctionShouldReturnAExceptionIfQuestionIsEmpty() + { + $this->expectException(\Exception::class); + + // given + $questionRepositoryMock = $this->createMock(QuestionRepository::class); + $answerRepositoryMock = $this->createMock(AnswerRepository::class); + + $answerService = new AnswerService($answerRepositoryMock, $questionRepositoryMock); + + // when + $result = $answerService->create( + 'neymar jr', + '', + true + ); + } + + public function testCreateFunctionShouldReturnAExceptionIfIscorrectIsEmpty() + { + $this->expectException(\Exception::class); + + // given + $questionRepositoryMock = $this->createMock(QuestionRepository::class); + $answerRepositoryMock = $this->createMock(AnswerRepository::class); + + $answerService = new AnswerService($answerRepositoryMock, $questionRepositoryMock); + + // when + $result = $answerService->create( + 'neymar jr', + '001aeb1d-2569-a56d-287e-2afbbc9637a6', + '' + ); + } + } \ No newline at end of file diff --git a/tests/Unit/Service/QuestionServiceTest.php b/tests/Unit/Service/QuestionServiceTest.php index 1773746..5271641 100644 --- a/tests/Unit/Service/QuestionServiceTest.php +++ b/tests/Unit/Service/QuestionServiceTest.php @@ -36,8 +36,6 @@ public function testCreateFunctionShouldReturnAQuestion() public function testCreateFunctionShouldReturnAExceptionIfQuestionIsEmpty() { $this->expectException(\Exception::class); -// $this->expectExceptionMessage('The question is em'); -// $this->expectExceptionMessage('The question is empty'); $questionRepositoryMock = $this->createMock(QuestionRepository::class); $subjectRepositoryMock = $this->createMock(SubjectRepository::class); @@ -50,7 +48,6 @@ public function testCreateFunctionShouldReturnAExceptionIfQuestionIsEmpty() public function testCreateFunctionShouldReturnAExceptionIfQuestionDoenstHaveSubject() { $this->expectException(\Exception::class); - $this->expectExceptionMessage('This question not have a subject'); $questionMock = $this->createMock(Question::class); From 5e50f57b452e2745f8db15d849aa61f95e193679 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 5 Oct 2022 19:28:00 -0300 Subject: [PATCH 37/54] adiciona testes ao service de answer --- tests/Unit/Service/AnswerServiceTest.php | 52 ++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tests/Unit/Service/AnswerServiceTest.php b/tests/Unit/Service/AnswerServiceTest.php index 6fdee55..f9566d4 100644 --- a/tests/Unit/Service/AnswerServiceTest.php +++ b/tests/Unit/Service/AnswerServiceTest.php @@ -90,5 +90,57 @@ public function testCreateFunctionShouldReturnAExceptionIfIscorrectIsEmpty() ); } + public function testCreateFunctionShouldReturnAExceptionIfAnswerDoesNotHaveAExistentQuestion() + { + $this->expectException(\Exception::class); + + // given + $questionRepositoryMock = $this->createMock(QuestionRepository::class); + $questionRepositoryMock->method('getById')->willReturn(null); + + $answerRepositoryMock = $this->createMock(AnswerRepository::class); + + $answerService = new AnswerService($answerRepositoryMock, $questionRepositoryMock); + + // when + $result = $answerService->create( + 'neymar jr', + '001aeb1d-2569-a56d-287e-2afbbc9637a6', + true + ); + } + + public function isCorrectProvider() + { + return [ + 'inteiro' => [1], + 'string preenchida' => ['true'], + 'objeto' =>[new \DateTime()], + ]; + } + + /** + * @dataProvider isCorrectProvider + */ + public function testCreateFunctionShouldReturnAExceptionIfIscorrectHaveAValueDifferentThanABoolean($isCorrect) + { + $this->expectException(\Exception::class); + + // given + $questionMock = $this->createMock(Question::class); + + $questionRepositoryMock = $this->createMock(QuestionRepository::class); + $questionRepositoryMock->method('getById')->willReturn($questionMock); + $answerRepositoryMock = $this->createMock(AnswerRepository::class); + + $answerService = new AnswerService($answerRepositoryMock, $questionRepositoryMock); + + // when + $answerService->create( + 'neymar jr', + '001aeb1d-2569-a56d-287e-2afbbc9637a6', + $isCorrect + ); + } } \ No newline at end of file From 95abb858e238707f2fb86126c7e868421c249636 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 5 Oct 2022 22:36:52 -0300 Subject: [PATCH 38/54] muda forma de verificacao da request de examCreate --- app/Services/ExamService.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/Services/ExamService.php b/app/Services/ExamService.php index a23d00f..0962470 100644 --- a/app/Services/ExamService.php +++ b/app/Services/ExamService.php @@ -4,8 +4,6 @@ use App\Models\Exam; -use App\Models\Question; -use App\Models\Snapshot; use App\Repositorys\ExamRepository; use App\Repositorys\QuestionRepository; use App\Repositorys\SnapshotRepository; @@ -80,8 +78,8 @@ public function update($examId, $answers, $finishedAt) private function validateExamCreation($request) { - foreach ($request as $key => $value) { - if (!isset($value)) { + foreach ($request as $key) { + if (empty($key)) { throw new \Exception("the $key value not can be empty!"); } } From 7c5eb545ea9b13e0d94a4d6b6f84d7059623b162 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 5 Oct 2022 22:46:09 -0300 Subject: [PATCH 39/54] typa retorno da funcao getById --- app/Repositorys/SubjectRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Repositorys/SubjectRepository.php b/app/Repositorys/SubjectRepository.php index bc15cdb..de3d892 100644 --- a/app/Repositorys/SubjectRepository.php +++ b/app/Repositorys/SubjectRepository.php @@ -22,7 +22,7 @@ public function create(Subject $subject) : Subject return $subject; } - public function getById(string $id) + public function getById(string $id): Subject { return $this->entityManager->find( Subject::class, From 7dc3239bd93e0b27c24ff2bdf08c8cea7119e3b6 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Wed, 5 Oct 2022 22:53:11 -0300 Subject: [PATCH 40/54] retira funcao inutil --- app/Services/ExamService.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/app/Services/ExamService.php b/app/Services/ExamService.php index 0962470..cc0c3a0 100644 --- a/app/Services/ExamService.php +++ b/app/Services/ExamService.php @@ -51,7 +51,7 @@ public function create($studentId, $subjectId, $questionQuantity) ); $exam = $this->createExam($studentId, $subjectId, $questionQuantity); - $snapshot = $this->createExamSnapshot($exam); + $snapshot = $this->snapshotService->create($exam); return $this->createExamResponse($exam, $snapshot); } @@ -109,11 +109,6 @@ private function createExam($studentId, $subjectId, $questionQuantity) ); } - private function createExamSnapshot(Exam $exam) - { - return $this->snapshotService->create($exam); - } - private function createExamResponse(Exam $exam, $snapshot) { return [ From e63884a5b2c4ec1c1824f694045dbfb707616850 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Thu, 6 Oct 2022 15:15:59 -0300 Subject: [PATCH 41/54] assina retorno do metodo create Snapshot --- app/Repositorys/SnapshotRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Repositorys/SnapshotRepository.php b/app/Repositorys/SnapshotRepository.php index 0a7bf32..d38a433 100644 --- a/app/Repositorys/SnapshotRepository.php +++ b/app/Repositorys/SnapshotRepository.php @@ -17,7 +17,7 @@ public function __construct(EntityManager $entityManager) $this->entityManager = $entityManager; } - public function create(Snapshot $snapshot) + public function create(Snapshot $snapshot): Snapshot { $this->entityManager->persist($snapshot); $this->entityManager->flush(); From 9b0fcd572cd87e3813162244bb6454ffdfe0f26f Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Thu, 6 Oct 2022 17:03:34 -0300 Subject: [PATCH 42/54] retorna metodo getAnswers de Question --- app/Models/Question.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/Models/Question.php b/app/Models/Question.php index fd20f18..c8ccf34 100644 --- a/app/Models/Question.php +++ b/app/Models/Question.php @@ -51,6 +51,11 @@ public function getSubject(): Subject return $this->subject; } + public function getAnswers() + { + return $this->answers; + } + public function hasCorrectAnswer() { foreach ($this->answers as $answer) { From 7ce0074672edf235cc52fdbe12584e7f2a8a3522 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Thu, 6 Oct 2022 17:04:19 -0300 Subject: [PATCH 43/54] sobrepoe metodo createdAt para poder testalo --- app/Models/Exam.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/Models/Exam.php b/app/Models/Exam.php index 726c991..77aad6c 100644 --- a/app/Models/Exam.php +++ b/app/Models/Exam.php @@ -74,4 +74,9 @@ public function getQuestionQuantity() { return $this->question_quantity; } + + public function getCreatedAt(): \DateTime + { + return $this->createdAt; + } } \ No newline at end of file From 8c1bb933a7db3a41d2fab73f43c573a5606d0542 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Thu, 6 Oct 2022 17:38:59 -0300 Subject: [PATCH 44/54] litte bomb --- app/Repositorys/SnapshotRepository.php | 2 + app/Repositorys/SubjectRepository.php | 2 +- app/Services/SnapshotService.php | 11 +++-- tests/Unit/Service/ExamServiceTest.php | 54 +++++++++++++++++++++- tests/Unit/Service/SnapshotServiceTest.php | 4 +- 5 files changed, 65 insertions(+), 8 deletions(-) diff --git a/app/Repositorys/SnapshotRepository.php b/app/Repositorys/SnapshotRepository.php index d38a433..71b963c 100644 --- a/app/Repositorys/SnapshotRepository.php +++ b/app/Repositorys/SnapshotRepository.php @@ -21,6 +21,8 @@ public function create(Snapshot $snapshot): Snapshot { $this->entityManager->persist($snapshot); $this->entityManager->flush(); + + return $snapshot; } public function getCorrectAnswersByExam(Exam $exam) diff --git a/app/Repositorys/SubjectRepository.php b/app/Repositorys/SubjectRepository.php index de3d892..bc15cdb 100644 --- a/app/Repositorys/SubjectRepository.php +++ b/app/Repositorys/SubjectRepository.php @@ -22,7 +22,7 @@ public function create(Subject $subject) : Subject return $subject; } - public function getById(string $id): Subject + public function getById(string $id) { return $this->entityManager->find( Subject::class, diff --git a/app/Services/SnapshotService.php b/app/Services/SnapshotService.php index 7eceb41..4f00b68 100644 --- a/app/Services/SnapshotService.php +++ b/app/Services/SnapshotService.php @@ -4,6 +4,7 @@ use App\Models\Exam; +use App\Models\Question; use App\Models\Snapshot; use App\Repositorys\AnswerRepository; use App\Repositorys\SnapshotRepository; @@ -32,18 +33,18 @@ public function create(Exam $exam): array $exam->getQuestionQuantity() ); + $questionsAndAnswers = []; + + /** + * @var Question $question + */ foreach ($questions as $question) { foreach ($question->getAnswers() as $answer) { $snapshot = new Snapshot($exam, $question, $answer); $this->snapshotRepository->create($snapshot); } - } - $questionsAndAnswers = []; - - /** @var Question $question */ - foreach ($questions as $question) { $questionsAndAnswers[$question->getQuestion()] = array_map(function ($answer) { return $answer->getAnswer(); }, $question->getAnswers()->toArray()); diff --git a/tests/Unit/Service/ExamServiceTest.php b/tests/Unit/Service/ExamServiceTest.php index f79d70b..676fceb 100644 --- a/tests/Unit/Service/ExamServiceTest.php +++ b/tests/Unit/Service/ExamServiceTest.php @@ -3,7 +3,59 @@ namespace Tests\Unit\Service; -class ExamServiceTest +use App\Models\Exam; +use App\Models\Question; +use App\Models\Snapshot; +use App\Repositorys\AnswerRepository; +use App\Repositorys\ExamRepository; +use App\Repositorys\QuestionRepository; +use App\Repositorys\SnapshotRepository; +use App\Repositorys\StudentRepository; +use App\Repositorys\SubjectRepository; +use App\Services\ExamService; +use App\Services\SnapshotService; +use Tests\TestCase; + +class ExamServiceTest extends TestCase { + public function testCreateFunctionShouldReturnAExam() + { + // given + $questionMock = $this->createMock(Question::class); + $snapshotMock = $this->createMock(Snapshot::class); + + + $subjectRepositoryMock = $this->createMock(SubjectRepository::class); + $examRepositoryMock = $this->createMock(ExamRepository::class); + + $snapshotServiceMock = $this->createMock(SnapshotService::class); + $snapshotServiceMock->method('create')->willReturn([$snapshotMock, $snapshotMock, $snapshotMock, $snapshotMock]); + + $snapshotRepositoryMock = $this->createMock(SnapshotRepository::class); + + $questionRepositoryMock = $this->createMock(QuestionRepository::class); + $questionRepositoryMock->method('countQuestionsBySubject')->willReturn(10); + + $studentRepositoryMock = $this->createMock(StudentRepository::class); + + + $examService = new ExamService( + $subjectRepositoryMock, + $examRepositoryMock, + $studentRepositoryMock, + $questionRepositoryMock, + $snapshotServiceMock, + $snapshotRepositoryMock + ); + + // when + $result = $examService->create( + '05b6127c-bc7f-4d53-8e08-221e9cf593e7', + 'e913e8f0-bff2-4ec1-b15a-80568e430147', + 9 + ); + // then + $this->assertInstanceOf(Exam::class, $result); + } } \ No newline at end of file diff --git a/tests/Unit/Service/SnapshotServiceTest.php b/tests/Unit/Service/SnapshotServiceTest.php index 4601e65..323fb8a 100644 --- a/tests/Unit/Service/SnapshotServiceTest.php +++ b/tests/Unit/Service/SnapshotServiceTest.php @@ -3,7 +3,9 @@ namespace Tests\Unit\Service; -class SnapshotServiceTest +use Tests\TestCase; + +class SnapshotServiceTest extends TestCase { } \ No newline at end of file From d43e718d4f78239c64764beea0d78d11c6bda82a Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Thu, 6 Oct 2022 17:52:01 -0300 Subject: [PATCH 45/54] organiza cria testes para createExamService --- app/Services/ExamService.php | 58 +++++++++++++------------- tests/Unit/Service/ExamServiceTest.php | 16 +++++-- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/app/Services/ExamService.php b/app/Services/ExamService.php index cc0c3a0..c673733 100644 --- a/app/Services/ExamService.php +++ b/app/Services/ExamService.php @@ -56,26 +56,6 @@ public function create($studentId, $subjectId, $questionQuantity) return $this->createExamResponse($exam, $snapshot); } - public function update($examId, $answers, $finishedAt) - { - $exam = $this->examRepository->getById($examId); - - $this->validateExamUpdate($exam, $finishedAt); - - $this->registerStudentAnswers($answers, $exam); - - $score = $this->calculateExamResult($exam); - - $this->examRepository->finishExam($exam, $score, $finishedAt); - - $finalSnapshot = $this->snapshotRepository->getCorrectAnswersByExam($exam); - - return [ - 'score' => $score, - 'Exam' => $finalSnapshot - ]; - } - private function validateExamCreation($request) { foreach ($request as $key) { @@ -89,15 +69,6 @@ private function validateExamCreation($request) } } - private function validateExamUpdate(Exam $exam, $finishedAt) - { - $finishedAtToCarbon = Carbon::parse($finishedAt); - - if ($finishedAtToCarbon->diffInHours($exam->getCreatedAt()->format('Y-m-d H:i:s')) > 1) { - throw new \Exception("the exam has expired"); - } - } - private function createExam($studentId, $subjectId, $questionQuantity) { return $this->examRepository->create( @@ -120,6 +91,35 @@ private function createExamResponse(Exam $exam, $snapshot) ]; } + public function update($examId, $answers, $finishedAt) + { + $exam = $this->examRepository->getById($examId); + + $this->validateExamUpdate($exam, $finishedAt); + + $this->registerStudentAnswers($answers, $exam); + + $score = $this->calculateExamResult($exam); + + $this->examRepository->finishExam($exam, $score, $finishedAt); + + $finalSnapshot = $this->snapshotRepository->getCorrectAnswersByExam($exam); + + return [ + 'score' => $exam->getScore(), + 'Exam' => $finalSnapshot + ]; + } + + private function validateExamUpdate(Exam $exam, $finishedAt) + { + $finishedAtToCarbon = Carbon::parse($finishedAt); + + if ($finishedAtToCarbon->diffInHours($exam->getCreatedAt()->format('Y-m-d H:i:s')) > 1) { + throw new \Exception("the exam has expired"); + } + } + public function registerStudentAnswers($answers, Exam $exam): void { foreach ($answers as $question => $answer) { diff --git a/tests/Unit/Service/ExamServiceTest.php b/tests/Unit/Service/ExamServiceTest.php index 676fceb..7505132 100644 --- a/tests/Unit/Service/ExamServiceTest.php +++ b/tests/Unit/Service/ExamServiceTest.php @@ -6,6 +6,7 @@ use App\Models\Exam; use App\Models\Question; use App\Models\Snapshot; +use App\Models\Subject; use App\Repositorys\AnswerRepository; use App\Repositorys\ExamRepository; use App\Repositorys\QuestionRepository; @@ -18,18 +19,22 @@ class ExamServiceTest extends TestCase { - public function testCreateFunctionShouldReturnAExam() + public function testCreateFunctionShouldReturnAArrayWithExamKeys() { // given $questionMock = $this->createMock(Question::class); $snapshotMock = $this->createMock(Snapshot::class); + $subjectMock = $this->createMock(Subject::class); + $subjectRepositoryMock = $this->createMock(SubjectRepository::class); + $subjectRepositoryMock->method('getById')->willReturn($subjectMock); + $examRepositoryMock = $this->createMock(ExamRepository::class); $snapshotServiceMock = $this->createMock(SnapshotService::class); - $snapshotServiceMock->method('create')->willReturn([$snapshotMock, $snapshotMock, $snapshotMock, $snapshotMock]); + $snapshotServiceMock->method('create')->willReturn([$snapshotMock, $snapshotMock, $snapshotMock]); $snapshotRepositoryMock = $this->createMock(SnapshotRepository::class); @@ -56,6 +61,11 @@ public function testCreateFunctionShouldReturnAExam() ); // then - $this->assertInstanceOf(Exam::class, $result); + $this->assertIsArray($result); + $this->assertArrayHasKey('exam', $result); + $this->assertArrayHasKey('student', $result); + $this->assertArrayHasKey('subject', $result); + $this->assertArrayHasKey('questionsAndAnswers', $result); + $this->assertArrayHasKey('startedAt', $result); } } \ No newline at end of file From 7772d996a08066172cbf0380718d99b68bb597e5 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Thu, 6 Oct 2022 18:01:43 -0300 Subject: [PATCH 46/54] testa excecoes ao criar um exame --- app/Services/ExamService.php | 6 +- tests/Unit/Service/ExamServiceTest.php | 105 ++++++++++++++++++++----- 2 files changed, 92 insertions(+), 19 deletions(-) diff --git a/app/Services/ExamService.php b/app/Services/ExamService.php index c673733..37c4880 100644 --- a/app/Services/ExamService.php +++ b/app/Services/ExamService.php @@ -64,8 +64,12 @@ private function validateExamCreation($request) } } + if ($request['questionQuantity'] <= 0) { + throw new \Exception("The requested quantity shouldnt be lesser or equal a zero"); + } + if ($this->questionRepository->countQuestionsBySubject($request['subjectId']) < $request['questionQuantity']) { - throw new \Exception("the quantity of questions is less than the requested quantity"); + throw new \Exception("the total amount of questions is lesser than the requested quantity"); } } diff --git a/tests/Unit/Service/ExamServiceTest.php b/tests/Unit/Service/ExamServiceTest.php index 7505132..89894af 100644 --- a/tests/Unit/Service/ExamServiceTest.php +++ b/tests/Unit/Service/ExamServiceTest.php @@ -22,12 +22,96 @@ class ExamServiceTest extends TestCase public function testCreateFunctionShouldReturnAArrayWithExamKeys() { // given + $examService = $this->getExamService(); + + // when + $result = $examService->create( + '05b6127c-bc7f-4d53-8e08-221e9cf593e7', + 'e913e8f0-bff2-4ec1-b15a-80568e430147', + 9 + ); + + // then + $this->assertIsArray($result); + $this->assertArrayHasKey('exam', $result); + $this->assertArrayHasKey('student', $result); + $this->assertArrayHasKey('subject', $result); + $this->assertArrayHasKey('questionsAndAnswers', $result); + $this->assertArrayHasKey('startedAt', $result); + } + + public function testCreateFunctionShouldReturnAExceptionWhenQuestionQuantityIsGreatherThanStoredQuestions() + { + $this->expectException(\Exception::class); + + $examService = $this->getExamService(); + + $examService->create( + '05b6127c-bc7f-4d53-8e08-221e9cf593e7', + 'e913e8f0-bff2-4ec1-b15a-80568e430147', + 200000 + ); + } + + public function testCreateFunctionShouldReturnAExceptionWhenStudentIdIsEmpty() + { + $this->expectException(\Exception::class); + + $examService = $this->getExamService(); + + $examService->create( + '', + 'e913e8f0-bff2-4ec1-b15a-80568e430147', + 200000 + ); + } + + public function testCreateFunctionShouldReturnAExceptionWhenSubjectIdIsEmpty() + { + $this->expectException(\Exception::class); + + $examService = $this->getExamService(); + + $examService->create( + 'e913e8f0-bff2-4ec1-b15a-80568e430147', + '', + 200000 + ); + } + + public function testCreateFunctionShouldReturnAExceptionWhenQuestionQuantityIsEmpty() + { + $this->expectException(\Exception::class); + + $examService = $this->getExamService(); + + $examService->create( + 'e913e8f0-bff2-4ec1-b15a-80568e430147', + 'e913e8f0-bff2-4ec1-b15a-80568e430141', + '' + ); + } + + public function testCreateFunctionShouldReturnAExceptionWhenQuestionQuantityIsLesserOrEqualAZero() + { + $this->expectException(\Exception::class); + + $examService = $this->getExamService(); + + $examService->create( + 'e913e8f0-bff2-4ec1-b15a-80568e430147', + 'e913e8f0-bff2-4ec1-b15a-80568e430141', + 0 + ); + } + + + private function getExamService() + { $questionMock = $this->createMock(Question::class); $snapshotMock = $this->createMock(Snapshot::class); $subjectMock = $this->createMock(Subject::class); - - $subjectRepositoryMock = $this->createMock(SubjectRepository::class); $subjectRepositoryMock->method('getById')->willReturn($subjectMock); @@ -44,7 +128,7 @@ public function testCreateFunctionShouldReturnAArrayWithExamKeys() $studentRepositoryMock = $this->createMock(StudentRepository::class); - $examService = new ExamService( + return new ExamService( $subjectRepositoryMock, $examRepositoryMock, $studentRepositoryMock, @@ -52,20 +136,5 @@ public function testCreateFunctionShouldReturnAArrayWithExamKeys() $snapshotServiceMock, $snapshotRepositoryMock ); - - // when - $result = $examService->create( - '05b6127c-bc7f-4d53-8e08-221e9cf593e7', - 'e913e8f0-bff2-4ec1-b15a-80568e430147', - 9 - ); - - // then - $this->assertIsArray($result); - $this->assertArrayHasKey('exam', $result); - $this->assertArrayHasKey('student', $result); - $this->assertArrayHasKey('subject', $result); - $this->assertArrayHasKey('questionsAndAnswers', $result); - $this->assertArrayHasKey('startedAt', $result); } } \ No newline at end of file From d325648f929ea62a53b248b4824b6c4141f888b0 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Thu, 6 Oct 2022 18:04:11 -0300 Subject: [PATCH 47/54] cria arquivo de para testar updateExamServiceTest --- ...ceTest.php => CreateAnswerServiceTest.php} | 0 ...viceTest.php => CreateExamServiceTest.php} | 0 ...Test.php => CreateQuestionServiceTest.php} | 0 ...Test.php => CreateSnapshotServiceTest.php} | 0 ...eTest.php => CreateStudentServiceTest.php} | 0 ...eTest.php => CreateSubjectServiceTest.php} | 0 tests/Unit/Service/UpdateExamServiceTest.php | 139 ++++++++++++++++++ 7 files changed, 139 insertions(+) rename tests/Unit/Service/{AnswerServiceTest.php => CreateAnswerServiceTest.php} (100%) rename tests/Unit/Service/{ExamServiceTest.php => CreateExamServiceTest.php} (100%) rename tests/Unit/Service/{QuestionServiceTest.php => CreateQuestionServiceTest.php} (100%) rename tests/Unit/Service/{SnapshotServiceTest.php => CreateSnapshotServiceTest.php} (100%) rename tests/Unit/Service/{StudentServiceTest.php => CreateStudentServiceTest.php} (100%) rename tests/Unit/Service/{SubjectServiceTest.php => CreateSubjectServiceTest.php} (100%) create mode 100644 tests/Unit/Service/UpdateExamServiceTest.php diff --git a/tests/Unit/Service/AnswerServiceTest.php b/tests/Unit/Service/CreateAnswerServiceTest.php similarity index 100% rename from tests/Unit/Service/AnswerServiceTest.php rename to tests/Unit/Service/CreateAnswerServiceTest.php diff --git a/tests/Unit/Service/ExamServiceTest.php b/tests/Unit/Service/CreateExamServiceTest.php similarity index 100% rename from tests/Unit/Service/ExamServiceTest.php rename to tests/Unit/Service/CreateExamServiceTest.php diff --git a/tests/Unit/Service/QuestionServiceTest.php b/tests/Unit/Service/CreateQuestionServiceTest.php similarity index 100% rename from tests/Unit/Service/QuestionServiceTest.php rename to tests/Unit/Service/CreateQuestionServiceTest.php diff --git a/tests/Unit/Service/SnapshotServiceTest.php b/tests/Unit/Service/CreateSnapshotServiceTest.php similarity index 100% rename from tests/Unit/Service/SnapshotServiceTest.php rename to tests/Unit/Service/CreateSnapshotServiceTest.php diff --git a/tests/Unit/Service/StudentServiceTest.php b/tests/Unit/Service/CreateStudentServiceTest.php similarity index 100% rename from tests/Unit/Service/StudentServiceTest.php rename to tests/Unit/Service/CreateStudentServiceTest.php diff --git a/tests/Unit/Service/SubjectServiceTest.php b/tests/Unit/Service/CreateSubjectServiceTest.php similarity index 100% rename from tests/Unit/Service/SubjectServiceTest.php rename to tests/Unit/Service/CreateSubjectServiceTest.php diff --git a/tests/Unit/Service/UpdateExamServiceTest.php b/tests/Unit/Service/UpdateExamServiceTest.php new file mode 100644 index 0000000..dc878aa --- /dev/null +++ b/tests/Unit/Service/UpdateExamServiceTest.php @@ -0,0 +1,139 @@ +getExamService(); + + // when + $result = $examService->create( + '05b6127c-bc7f-4d53-8e08-221e9cf593e7', + 'e913e8f0-bff2-4ec1-b15a-80568e430147', + 9 + ); + + // then + $this->assertIsArray($result); + $this->assertArrayHasKey('exam', $result); + $this->assertArrayHasKey('student', $result); + $this->assertArrayHasKey('subject', $result); + $this->assertArrayHasKey('questionsAndAnswers', $result); + $this->assertArrayHasKey('startedAt', $result); + } + + public function testCreateFunctionShouldReturnAExceptionWhenQuestionQuantityIsGreatherThanStoredQuestions() + { + $this->expectException(\Exception::class); + + $examService = $this->getExamService(); + + $examService->create( + '05b6127c-bc7f-4d53-8e08-221e9cf593e7', + 'e913e8f0-bff2-4ec1-b15a-80568e430147', + 200000 + ); + } + + public function testCreateFunctionShouldReturnAExceptionWhenStudentIdIsEmpty() + { + $this->expectException(\Exception::class); + + $examService = $this->getExamService(); + + $examService->create( + '', + 'e913e8f0-bff2-4ec1-b15a-80568e430147', + 200000 + ); + } + + public function testCreateFunctionShouldReturnAExceptionWhenSubjectIdIsEmpty() + { + $this->expectException(\Exception::class); + + $examService = $this->getExamService(); + + $examService->create( + 'e913e8f0-bff2-4ec1-b15a-80568e430147', + '', + 200000 + ); + } + + public function testCreateFunctionShouldReturnAExceptionWhenQuestionQuantityIsEmpty() + { + $this->expectException(\Exception::class); + + $examService = $this->getExamService(); + + $examService->create( + 'e913e8f0-bff2-4ec1-b15a-80568e430147', + 'e913e8f0-bff2-4ec1-b15a-80568e430141', + '' + ); + } + + public function testCreateFunctionShouldReturnAExceptionWhenQuestionQuantityIsLesserOrEqualAZero() + { + $this->expectException(\Exception::class); + + $examService = $this->getExamService(); + + $examService->create( + 'e913e8f0-bff2-4ec1-b15a-80568e430147', + 'e913e8f0-bff2-4ec1-b15a-80568e430141', + 0 + ); + } + + private function getExamService() + { + $questionMock = $this->createMock(Question::class); + $snapshotMock = $this->createMock(Snapshot::class); + $subjectMock = $this->createMock(Subject::class); + + $subjectRepositoryMock = $this->createMock(SubjectRepository::class); + $subjectRepositoryMock->method('getById')->willReturn($subjectMock); + + $examRepositoryMock = $this->createMock(ExamRepository::class); + + $snapshotServiceMock = $this->createMock(SnapshotService::class); + $snapshotServiceMock->method('create')->willReturn([$snapshotMock, $snapshotMock, $snapshotMock]); + + $snapshotRepositoryMock = $this->createMock(SnapshotRepository::class); + + $questionRepositoryMock = $this->createMock(QuestionRepository::class); + $questionRepositoryMock->method('countQuestionsBySubject')->willReturn(10); + + $studentRepositoryMock = $this->createMock(StudentRepository::class); + + + return new ExamService( + $subjectRepositoryMock, + $examRepositoryMock, + $studentRepositoryMock, + $questionRepositoryMock, + $snapshotServiceMock, + $snapshotRepositoryMock + ); + } +} \ No newline at end of file From 52690c661c2da650c9323825027b5e24cc4588cb Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Thu, 6 Oct 2022 18:04:49 -0300 Subject: [PATCH 48/54] renomeia nomes das classes de teste para melhor compreensao --- tests/Unit/Service/CreateAnswerServiceTest.php | 2 +- tests/Unit/Service/CreateExamServiceTest.php | 3 +-- tests/Unit/Service/CreateQuestionServiceTest.php | 2 +- tests/Unit/Service/CreateSnapshotServiceTest.php | 2 +- tests/Unit/Service/CreateStudentServiceTest.php | 2 +- tests/Unit/Service/CreateSubjectServiceTest.php | 2 +- 6 files changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/Unit/Service/CreateAnswerServiceTest.php b/tests/Unit/Service/CreateAnswerServiceTest.php index f9566d4..e31edb1 100644 --- a/tests/Unit/Service/CreateAnswerServiceTest.php +++ b/tests/Unit/Service/CreateAnswerServiceTest.php @@ -11,7 +11,7 @@ use PHPUnit\Framework\TestCase; -class AnswerServiceTest extends TestCase +class CreateAnswerServiceTest extends TestCase { public function testCreateFunctionShouldReturnAAnswer() { diff --git a/tests/Unit/Service/CreateExamServiceTest.php b/tests/Unit/Service/CreateExamServiceTest.php index 89894af..dc878aa 100644 --- a/tests/Unit/Service/CreateExamServiceTest.php +++ b/tests/Unit/Service/CreateExamServiceTest.php @@ -17,7 +17,7 @@ use App\Services\SnapshotService; use Tests\TestCase; -class ExamServiceTest extends TestCase +class CreateExamServiceTest extends TestCase { public function testCreateFunctionShouldReturnAArrayWithExamKeys() { @@ -105,7 +105,6 @@ public function testCreateFunctionShouldReturnAExceptionWhenQuestionQuantityIsLe ); } - private function getExamService() { $questionMock = $this->createMock(Question::class); diff --git a/tests/Unit/Service/CreateQuestionServiceTest.php b/tests/Unit/Service/CreateQuestionServiceTest.php index 5271641..9440949 100644 --- a/tests/Unit/Service/CreateQuestionServiceTest.php +++ b/tests/Unit/Service/CreateQuestionServiceTest.php @@ -10,7 +10,7 @@ use App\Services\QuestionService; use Tests\TestCase; -class QuestionServiceTest extends TestCase +class CreateQuestionServiceTest extends TestCase { public function testCreateFunctionShouldReturnAQuestion() { diff --git a/tests/Unit/Service/CreateSnapshotServiceTest.php b/tests/Unit/Service/CreateSnapshotServiceTest.php index 323fb8a..92c7eaa 100644 --- a/tests/Unit/Service/CreateSnapshotServiceTest.php +++ b/tests/Unit/Service/CreateSnapshotServiceTest.php @@ -5,7 +5,7 @@ use Tests\TestCase; -class SnapshotServiceTest extends TestCase +class CreateSnapshotServiceTest extends TestCase { } \ No newline at end of file diff --git a/tests/Unit/Service/CreateStudentServiceTest.php b/tests/Unit/Service/CreateStudentServiceTest.php index 618d327..b3bd971 100644 --- a/tests/Unit/Service/CreateStudentServiceTest.php +++ b/tests/Unit/Service/CreateStudentServiceTest.php @@ -8,7 +8,7 @@ use App\Services\StudentService; use PHPUnit\Framework\TestCase; -class StudentServiceTest extends TestCase +class CreateStudentServiceTest extends TestCase { public function testCreateFunctionShouldReturnAStudent() { diff --git a/tests/Unit/Service/CreateSubjectServiceTest.php b/tests/Unit/Service/CreateSubjectServiceTest.php index 1a1cf83..119f69f 100644 --- a/tests/Unit/Service/CreateSubjectServiceTest.php +++ b/tests/Unit/Service/CreateSubjectServiceTest.php @@ -7,7 +7,7 @@ use App\Services\SubjectService; use PHPUnit\Framework\TestCase; -class SubjectServiceTest extends TestCase +class CreateSubjectServiceTest extends TestCase { public function testCreateFunctionShouldReturnASubject() { From d2242e9252fc294bf136800bf1d1caeb7f052c5f Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Fri, 7 Oct 2022 07:29:21 -0300 Subject: [PATCH 49/54] garante que score nao pode ser nulo ou menor que zero --- app/Services/ExamService.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/Services/ExamService.php b/app/Services/ExamService.php index 37c4880..937d095 100644 --- a/app/Services/ExamService.php +++ b/app/Services/ExamService.php @@ -95,15 +95,17 @@ private function createExamResponse(Exam $exam, $snapshot) ]; } - public function update($examId, $answers, $finishedAt) + public function update($examId, $studentAnswers, $finishedAt) { $exam = $this->examRepository->getById($examId); $this->validateExamUpdate($exam, $finishedAt); - $this->registerStudentAnswers($answers, $exam); + $this->registerStudentAnswers($studentAnswers, $exam); + $score = $this->calculateExamResult($exam); + dd('OIEE'); $this->examRepository->finishExam($exam, $score, $finishedAt); @@ -135,6 +137,11 @@ public function registerStudentAnswers($answers, Exam $exam): void private function calculateExamResult(Exam $exam) { $score = $this->snapshotRepository->getScoreByExam($exam); + + if ($score < 0 || $score === null){ + $score = 0; + } + $questionValue = self::BASE_NOTE / $exam->getQuestionQuantity(); return sprintf("%.2f",$score * $questionValue); From 5e121d2374b3eec6f77535945685bcb5858e6299 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Fri, 7 Oct 2022 07:44:53 -0300 Subject: [PATCH 50/54] testa caso de sucesso em update exam --- tests/Unit/Service/UpdateExamServiceTest.php | 125 +++++++------------ 1 file changed, 44 insertions(+), 81 deletions(-) diff --git a/tests/Unit/Service/UpdateExamServiceTest.php b/tests/Unit/Service/UpdateExamServiceTest.php index dc878aa..3467321 100644 --- a/tests/Unit/Service/UpdateExamServiceTest.php +++ b/tests/Unit/Service/UpdateExamServiceTest.php @@ -17,113 +17,46 @@ use App\Services\SnapshotService; use Tests\TestCase; -class CreateExamServiceTest extends TestCase +class UpdateExamServiceTest extends TestCase { - public function testCreateFunctionShouldReturnAArrayWithExamKeys() + public function testUpdateFunctionShouldReturnAArrayWithResultKeys() { // given $examService = $this->getExamService(); // when - $result = $examService->create( + $result = $examService->update( '05b6127c-bc7f-4d53-8e08-221e9cf593e7', - 'e913e8f0-bff2-4ec1-b15a-80568e430147', - 9 + $this->getStudentAnswers(), + new \DateTime('2022-10-10 16:00:00'), ); // then $this->assertIsArray($result); - $this->assertArrayHasKey('exam', $result); - $this->assertArrayHasKey('student', $result); - $this->assertArrayHasKey('subject', $result); - $this->assertArrayHasKey('questionsAndAnswers', $result); - $this->assertArrayHasKey('startedAt', $result); - } - - public function testCreateFunctionShouldReturnAExceptionWhenQuestionQuantityIsGreatherThanStoredQuestions() - { - $this->expectException(\Exception::class); - - $examService = $this->getExamService(); - - $examService->create( - '05b6127c-bc7f-4d53-8e08-221e9cf593e7', - 'e913e8f0-bff2-4ec1-b15a-80568e430147', - 200000 - ); - } - - public function testCreateFunctionShouldReturnAExceptionWhenStudentIdIsEmpty() - { - $this->expectException(\Exception::class); - - $examService = $this->getExamService(); - - $examService->create( - '', - 'e913e8f0-bff2-4ec1-b15a-80568e430147', - 200000 - ); - } - - public function testCreateFunctionShouldReturnAExceptionWhenSubjectIdIsEmpty() - { - $this->expectException(\Exception::class); - - $examService = $this->getExamService(); - - $examService->create( - 'e913e8f0-bff2-4ec1-b15a-80568e430147', - '', - 200000 - ); - } - - public function testCreateFunctionShouldReturnAExceptionWhenQuestionQuantityIsEmpty() - { - $this->expectException(\Exception::class); - - $examService = $this->getExamService(); - - $examService->create( - 'e913e8f0-bff2-4ec1-b15a-80568e430147', - 'e913e8f0-bff2-4ec1-b15a-80568e430141', - '' - ); - } - - public function testCreateFunctionShouldReturnAExceptionWhenQuestionQuantityIsLesserOrEqualAZero() - { - $this->expectException(\Exception::class); - - $examService = $this->getExamService(); - - $examService->create( - 'e913e8f0-bff2-4ec1-b15a-80568e430147', - 'e913e8f0-bff2-4ec1-b15a-80568e430141', - 0 - ); + $this->assertArrayHasKey('Exam', $result); + $this->assertArrayHasKey('score', $result); } private function getExamService() { - $questionMock = $this->createMock(Question::class); $snapshotMock = $this->createMock(Snapshot::class); - $subjectMock = $this->createMock(Subject::class); + + $examMock = $this->createMock(Exam::class); + $examMock->method('getCreatedAt')->willReturn(new \DateTime('2022-10-10 15:30:00')); + $examMock->method('getQuestionQuantity')->willReturn(3); $subjectRepositoryMock = $this->createMock(SubjectRepository::class); - $subjectRepositoryMock->method('getById')->willReturn($subjectMock); $examRepositoryMock = $this->createMock(ExamRepository::class); + $examRepositoryMock->method('getById')->willReturn($examMock); $snapshotServiceMock = $this->createMock(SnapshotService::class); - $snapshotServiceMock->method('create')->willReturn([$snapshotMock, $snapshotMock, $snapshotMock]); $snapshotRepositoryMock = $this->createMock(SnapshotRepository::class); + $snapshotRepositoryMock->method('getScoreByExam')->willReturn(2); + $snapshotRepositoryMock->method('getCorrectAnswersByExam')->willReturn($this->getCorrectAnswers()); $questionRepositoryMock = $this->createMock(QuestionRepository::class); - $questionRepositoryMock->method('countQuestionsBySubject')->willReturn(10); - $studentRepositoryMock = $this->createMock(StudentRepository::class); @@ -136,4 +69,34 @@ private function getExamService() $snapshotRepositoryMock ); } + + private function getStudentAnswers() + { + return[ + "quantos cantos um campo de futebol tem" => "true", + "Quantas cores a bandeira do SP tem?" => "três", + "marca de chuteira" => "nike" + ]; + } + + private function getCorrectAnswers() + { + return [ + [ + "question" => "quantos cantos um campo de futebol tem", + "student_answer" => "true", + "correctAnswer" => "quatro" + ], + [ + "question" => "Quantas cores a bandeira do SP tem?", + "student_answer" => "três", + "correctAnswer" => "três" + ], + [ + "question" => "marca de chuteira", + "student_answer" => "nike", + "correctAnswer" => "nike" + ], + ]; + } } \ No newline at end of file From 04c85a92c4a00b9571dab1f09415260c16d5c92b Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Fri, 7 Oct 2022 07:51:41 -0300 Subject: [PATCH 51/54] adiciona teste na exception de updateExamService --- app/Services/ExamService.php | 2 -- tests/Unit/Service/UpdateExamServiceTest.php | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/Services/ExamService.php b/app/Services/ExamService.php index 937d095..da82db7 100644 --- a/app/Services/ExamService.php +++ b/app/Services/ExamService.php @@ -103,9 +103,7 @@ public function update($examId, $studentAnswers, $finishedAt) $this->registerStudentAnswers($studentAnswers, $exam); - $score = $this->calculateExamResult($exam); - dd('OIEE'); $this->examRepository->finishExam($exam, $score, $finishedAt); diff --git a/tests/Unit/Service/UpdateExamServiceTest.php b/tests/Unit/Service/UpdateExamServiceTest.php index 3467321..8dccf1e 100644 --- a/tests/Unit/Service/UpdateExamServiceTest.php +++ b/tests/Unit/Service/UpdateExamServiceTest.php @@ -37,6 +37,20 @@ public function testUpdateFunctionShouldReturnAArrayWithResultKeys() $this->assertArrayHasKey('score', $result); } + public function testUpdateFunctionShouldReturnAExceptionWhenDifferenceBetweenCreatedAtAndFinishedAtIsSuperiorThanOneHour() + { + $this->expectException(\Exception::class); + + $examService = $this->getExamService(); + + // when + $examService->update( + '05b6127c-bc7f-4d53-8e08-221e9cf593e7', + $this->getStudentAnswers(), + new \DateTime('2022-10-10 18:00:00'), + ); + } + private function getExamService() { $snapshotMock = $this->createMock(Snapshot::class); From a5a0a946b2513ada52039e73cc6a0aa8c1992cbc Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Fri, 7 Oct 2022 08:56:47 -0300 Subject: [PATCH 52/54] adiciona teste de sucesso em SnapshotService --- app/Services/SnapshotService.php | 1 - tests/Unit/Service/CreateExamServiceTest.php | 2 - .../Service/CreateSnapshotServiceTest.php | 67 +++++++++++++++++++ 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/app/Services/SnapshotService.php b/app/Services/SnapshotService.php index 4f00b68..cb44b99 100644 --- a/app/Services/SnapshotService.php +++ b/app/Services/SnapshotService.php @@ -57,7 +57,6 @@ private function pickRandomQuestionsBySubject($subject, $questionsQuantity): arr { $allQuestions = $this->questionRepository->getAllQuestionsBySubject($subject); - shuffle($allQuestions); return array_slice($allQuestions, 0, $questionsQuantity); diff --git a/tests/Unit/Service/CreateExamServiceTest.php b/tests/Unit/Service/CreateExamServiceTest.php index dc878aa..0865da0 100644 --- a/tests/Unit/Service/CreateExamServiceTest.php +++ b/tests/Unit/Service/CreateExamServiceTest.php @@ -3,11 +3,9 @@ namespace Tests\Unit\Service; -use App\Models\Exam; use App\Models\Question; use App\Models\Snapshot; use App\Models\Subject; -use App\Repositorys\AnswerRepository; use App\Repositorys\ExamRepository; use App\Repositorys\QuestionRepository; use App\Repositorys\SnapshotRepository; diff --git a/tests/Unit/Service/CreateSnapshotServiceTest.php b/tests/Unit/Service/CreateSnapshotServiceTest.php index 92c7eaa..7f765de 100644 --- a/tests/Unit/Service/CreateSnapshotServiceTest.php +++ b/tests/Unit/Service/CreateSnapshotServiceTest.php @@ -3,9 +3,76 @@ namespace Tests\Unit\Service; +use App\Models\Answer; +use App\Models\Exam; +use App\Models\Question; +use App\Models\Subject; +use App\Repositorys\AnswerRepository; +use App\Repositorys\QuestionRepository; +use App\Repositorys\SnapshotRepository; +use App\Services\SnapshotService; +use Doctrine\Common\Collections\ArrayCollection; use Tests\TestCase; class CreateSnapshotServiceTest extends TestCase { + public function testCreateFunctionShouldReturnAArrayWithQuestionsAndAnswers() + { + // given + $snapshotService = $this->getSnapshotService(); + $examMock = $this->getExamMock(); + + + // when + $result = $snapshotService->create($examMock); + + // then + $this->assertIsArray($result); + } + + private function getSnapshotService() + { +// $snapshotMock = $this->createMock(Snapshot::class); + + $snapshotRepositoryMock = $this->createMock(SnapshotRepository::class); + + $answerRepositoryMock = $this->createMock(AnswerRepository::class); + + $questionRepositoryMock = $this->createMock(QuestionRepository::class); + $questionRepositoryMock->method('getAllQuestionsBySubject')->willReturn($this->getArrayQuestionsMock()); + + return new SnapshotService( + $questionRepositoryMock, + $answerRepositoryMock, + $snapshotRepositoryMock + ); + } + + public function getExamMock() + { + $subjectMock = $this->createMock(Subject::class); + + $examMock = $this->createMock(Exam::class); + $examMock->method('getSubject')->willReturn($subjectMock); + $examMock->method('getQuestionQuantity')->willReturn(2); + + return $examMock; + } + + public function getArrayQuestionsMock() + { + $questionMock = $this->createMock(Question::class); + + $answerMock1 = $this->createMock(Answer::class); + $answerMock1->method('getAnswer')->willReturn('5'); + + $answerMock2 = $this->createMock(Answer::class); + $answerMock2->method('getAnswer')->willReturn('1'); + + $questionMock->method('getQuestion')->willReturn('Quantas copas o Brasil ganhou?'); + $questionMock->method('getAnswers')->willReturn(new ArrayCollection([$answerMock1, $answerMock2])); + + return [$questionMock]; + } } \ No newline at end of file From 430928e3e0588df8a4214165b49f7de70358d577 Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Fri, 14 Oct 2022 08:19:32 -0300 Subject: [PATCH 53/54] retira mock inutilizado do teste --- tests/Unit/Service/CreateSnapshotServiceTest.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/Unit/Service/CreateSnapshotServiceTest.php b/tests/Unit/Service/CreateSnapshotServiceTest.php index 7f765de..f612e94 100644 --- a/tests/Unit/Service/CreateSnapshotServiceTest.php +++ b/tests/Unit/Service/CreateSnapshotServiceTest.php @@ -20,10 +20,8 @@ public function testCreateFunctionShouldReturnAArrayWithQuestionsAndAnswers() { // given $snapshotService = $this->getSnapshotService(); - $examMock = $this->getExamMock(); - // when $result = $snapshotService->create($examMock); @@ -33,8 +31,6 @@ public function testCreateFunctionShouldReturnAArrayWithQuestionsAndAnswers() private function getSnapshotService() { -// $snapshotMock = $this->createMock(Snapshot::class); - $snapshotRepositoryMock = $this->createMock(SnapshotRepository::class); $answerRepositoryMock = $this->createMock(AnswerRepository::class); From 7eba1344f576828b5029715d96f986b533b5ff7e Mon Sep 17 00:00:00 2001 From: eng-luiz Date: Fri, 14 Oct 2022 08:24:59 -0300 Subject: [PATCH 54/54] muda funcao de ordenacao para publica para poder testar --- app/Services/SnapshotService.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/Services/SnapshotService.php b/app/Services/SnapshotService.php index cb44b99..75ad8e6 100644 --- a/app/Services/SnapshotService.php +++ b/app/Services/SnapshotService.php @@ -53,12 +53,11 @@ public function create(Exam $exam): array return $questionsAndAnswers; } - private function pickRandomQuestionsBySubject($subject, $questionsQuantity): array + public function pickRandomQuestionsBySubject($subject, $questionsQuantity): array { $allQuestions = $this->questionRepository->getAllQuestionsBySubject($subject); shuffle($allQuestions); - return array_slice($allQuestions, 0, $questionsQuantity); } } \ No newline at end of file