From 58dfa93e9f54f8aaab211df516c39c7f6ddfab16 Mon Sep 17 00:00:00 2001 From: Victor Ventura Date: Fri, 2 Jun 2017 15:19:14 -0300 Subject: [PATCH] Beta version for Checklistable [features] - checklist crud - Questions crud and fill with array - Answer start and respond [test] - Unit test for evreryone [fix] - Uses --- .gitignore | 5 ++ .styleci.yml | 6 ++ CONTRIBUTING.md | 23 +++++ LICENSE | 20 +++++ composer.json | 46 ++++++++++ phpunit.xml | 28 ++++++ src/ChecklistableServiceProvider.php | 33 +++++++ src/Controllers/ChecklistableController.php | 32 +++++++ src/Models/Checklist.php | 13 +++ src/Models/ChecklistAnswer.php | 13 +++ src/Models/ChecklistQuestion.php | 13 +++ src/Services/ChecklistableAnswerService.php | 65 ++++++++++++++ src/Services/ChecklistableQuestionService.php | 63 ++++++++++++++ src/Services/ChecklistableService.php | 86 +++++++++++++++++++ src/Traits/ChecklistableTrait.php | 14 +++ ...7_05_30_160133_create_checklists_table.php | 34 ++++++++ ...60212_create_checklist_questions_table.php | 33 +++++++ ..._160235_create_checklist_answers_table.php | 35 ++++++++ src/routes.php | 5 ++ tests/ChecklistableAnswerTest.php | 73 ++++++++++++++++ tests/ChecklistableQuestionTest.php | 45 ++++++++++ tests/ChecklistableTest.php | 29 +++++++ tests/TestCase.php | 66 ++++++++++++++ 23 files changed, 780 insertions(+) create mode 100644 .gitignore create mode 100644 .styleci.yml create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 composer.json create mode 100644 phpunit.xml create mode 100644 src/ChecklistableServiceProvider.php create mode 100644 src/Controllers/ChecklistableController.php create mode 100644 src/Models/Checklist.php create mode 100644 src/Models/ChecklistAnswer.php create mode 100644 src/Models/ChecklistQuestion.php create mode 100644 src/Services/ChecklistableAnswerService.php create mode 100644 src/Services/ChecklistableQuestionService.php create mode 100644 src/Services/ChecklistableService.php create mode 100644 src/Traits/ChecklistableTrait.php create mode 100644 src/migrations/2017_05_30_160133_create_checklists_table.php create mode 100644 src/migrations/2017_05_30_160212_create_checklist_questions_table.php create mode 100644 src/migrations/2017_05_30_160235_create_checklist_answers_table.php create mode 100644 src/routes.php create mode 100644 tests/ChecklistableAnswerTest.php create mode 100644 tests/ChecklistableQuestionTest.php create mode 100644 tests/ChecklistableTest.php create mode 100644 tests/TestCase.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..527d0d5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/vendor/ +.bundle +composer.lock +/build/composer.lock +/build/ \ No newline at end of file diff --git a/.styleci.yml b/.styleci.yml new file mode 100644 index 0000000..0ee1176 --- /dev/null +++ b/.styleci.yml @@ -0,0 +1,6 @@ +preset: laravel +finder: + exclude: + - "tests" + name: + - "*.php" \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..39dff35 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,23 @@ +# Contributing + +Contributions are **welcome** and will be fully **credited**. We accept contributions via Pull Requests on [Github](https://github.com/convenia/revisionable). + +## Pull Requests + +- **[PSR-2 Coding Standard.](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** The easiest way to apply the conventions is to install [PHP CS Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer). +- **Add tests!** Your patch won't be accepted if it doesn't have tests. +- **Document any change in behaviour.** Make sure the `README.md` and any other relevant documentation are kept up-to-date. +- **Consider our release cycle.** We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option. +- **Create feature branches.** Don't ask us to pull from your master branch. +- **One pull request per feature.** If you want to do more than one thing, send multiple pull requests. +- **Send coherent history.** Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. + +## Running Tests + +```bash +$ phpunit +``` + + +*Happy coding!* +0 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7622188 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Davis Peixoto + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..2a85322 --- /dev/null +++ b/composer.json @@ -0,0 +1,46 @@ +{ + "name": "convenia/checklistable", + "license": "MIT", + "description": "Make any model checklistable with answer per ID", + "keywords": ["checklist", "laravel", "model"], + "homepage": "http://github.com/convenia/checklistable", + "authors": [ + { + "name": "Victor Ventura", + "email": "victor.ventura@convenia.com.br" + } + ], + "support": { + "issues": "https://github.com/convenia/checklistable/issues", + "source": "https://github.com/convenia/checklistable" + }, + "require": { + "php": ">=7", + "illuminate/support": "~5.2|~5.3|~5.4|~5.5" + }, + "require-dev": { + "codacy/coverage": "^1.0", + "friendsofphp/php-cs-fixer": "^1.13", + "mockery/mockery": "^0.9.4", + "orchestra/testbench": "~3.0", + "phpunit/phpunit": "^4.0|^5.0|^6.0" + }, + "autoload": { + "psr-4": { + "Convenia\\Checklistable\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Convenia\\Checklistable\\Tests\\": "tests" + } + }, + "scripts": { + "test": "./vendor/bin/phpunit", + "fixer": "./vendor/bin/php-cs-fixer fix --verbose" + }, + "config": { + "preferred-install": "dist", + "sort-packages": true + } +} diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..7cefbd3 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,28 @@ + + + + ./tests + + + + ./src/ + + + + + + + + + \ No newline at end of file diff --git a/src/ChecklistableServiceProvider.php b/src/ChecklistableServiceProvider.php new file mode 100644 index 0000000..2a29925 --- /dev/null +++ b/src/ChecklistableServiceProvider.php @@ -0,0 +1,33 @@ +publishes([ + __DIR__ . '/migrations' => $this->app->databasePath() . '/migrations' + ], 'migrations'); + + } + + /** + * Register the application services. + * + * @return void + */ + public function register() + { + // + } +} diff --git a/src/Controllers/ChecklistableController.php b/src/Controllers/ChecklistableController.php new file mode 100644 index 0000000..5d32f59 --- /dev/null +++ b/src/Controllers/ChecklistableController.php @@ -0,0 +1,32 @@ +checklist = $checklist; + } + + /** + * @param $answarableId + * @return Collection + */ + public function start($answarableId) : Collection + { + $checkQuestion = new ChecklistableQuestionService($this->checklist); + $questions = $checkQuestion->get(); + + $questions->transform(function($item) use($answarableId) { + $item['answerable_id'] = $answarableId; + return $item; + }); + + ChecklistAnswer::insert($questions->toArray()); + + return $this->get(1); + } + + public function answer($answarableId, $answerId, $answer = true) : bool + { + $answerMoldel = ChecklistAnswer::findOrFail($answerId); + $answerMoldel->answer = $answer; + return $answerMoldel->save(); + } + + public function get($answarableId) : Collection + { + $answers = ChecklistAnswer::query() + ->where('answerable_id', $answarableId) + ->where('checklist_id', $this->checklist->id) + ->get(); + + if ($answers->count() == 0) { + return $this->start($answarableId); + } + + return $answers; + } +} \ No newline at end of file diff --git a/src/Services/ChecklistableQuestionService.php b/src/Services/ChecklistableQuestionService.php new file mode 100644 index 0000000..7dcb48b --- /dev/null +++ b/src/Services/ChecklistableQuestionService.php @@ -0,0 +1,63 @@ +checklist = $checklist; + } + + public function get() + { + $this->questions = ChecklistQuestion::query() + ->where('checklist_id', $this->checklist->id) + ->get(); + + return $this->questions; + } + + + public function fill(Array $questions) + { + $oldQuestions = $this->get(); + + if ($oldQuestions->count() > 0) { + return $oldQuestions; + } + + $questions = collect($questions)->transform(function ($item) { + $item['checklist_id'] = $this->checklist->id; + return $item; + })->toArray(); + + + ChecklistQuestion::insert($questions); + + return $this->get(); + } + + public function add(Array $question) + { + $question['checklist_id'] = $this->checklist->id; + + ChecklistQuestion::insert($question); + + return $this->get(); + } + + public function delete($questionId) + { + return ChecklistQuestion::query()->delete($questionId); + } + + +} \ No newline at end of file diff --git a/src/Services/ChecklistableService.php b/src/Services/ChecklistableService.php new file mode 100644 index 0000000..ab5c611 --- /dev/null +++ b/src/Services/ChecklistableService.php @@ -0,0 +1,86 @@ +type = $type; + $this->checklistableClass = $checklistableClass; + } + + + public function get($companyId) : Checklist + { + $this->checklist = Checklist::query() + ->where('checklistable', $this->checklistableClass) + ->where('type', $this->type) + ->where('company_id', $companyId) + ->first(); + + if ($this->checklist === null) { + $this->checklist = Checklist::create([ + 'answerable' => $this->checklistableClass, + 'type' => $this->type, + 'company_id' => $companyId + ]); + } + + return $this->checklist; + + } + + public function questions($companyId = null) : ChecklistableQuestionService + { + + if ($this->checklist === null && $companyId === null ) { + throw new DefaultException('Company ID is needed'); + } + + $this->getChecklistIfNot($companyId); + return new ChecklistableQuestionService($this->checklist); + } + + public function answers($companyId) : ChecklistableAnswerService + { + $this->getChecklistIfNot($companyId); + return new ChecklistableAnswerService($this->checklist); + } + + protected function getChecklistIfNot($companyId) + { + if ($this->checklist === null) { + $this->get($companyId); + } + } + + +} \ No newline at end of file diff --git a/src/Traits/ChecklistableTrait.php b/src/Traits/ChecklistableTrait.php new file mode 100644 index 0000000..9c3bcbf --- /dev/null +++ b/src/Traits/ChecklistableTrait.php @@ -0,0 +1,14 @@ +increments('id'); + $table->integer('company_id'); + $table->string('type'); + $table->string('answerable'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('checklists'); + } +} diff --git a/src/migrations/2017_05_30_160212_create_checklist_questions_table.php b/src/migrations/2017_05_30_160212_create_checklist_questions_table.php new file mode 100644 index 0000000..9f48746 --- /dev/null +++ b/src/migrations/2017_05_30_160212_create_checklist_questions_table.php @@ -0,0 +1,33 @@ +increments('id'); + $table->integer('checklist_id'); + $table->string('question'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('checklist_questions'); + } +} diff --git a/src/migrations/2017_05_30_160235_create_checklist_answers_table.php b/src/migrations/2017_05_30_160235_create_checklist_answers_table.php new file mode 100644 index 0000000..00b4052 --- /dev/null +++ b/src/migrations/2017_05_30_160235_create_checklist_answers_table.php @@ -0,0 +1,35 @@ +increments('id'); + $table->integer('checklist_id'); + $table->integer('question'); + $table->boolean('answer')->default(false); + $table->integer('answerable_id'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('checklist_answers'); + } +} diff --git a/src/routes.php b/src/routes.php new file mode 100644 index 0000000..3622491 --- /dev/null +++ b/src/routes.php @@ -0,0 +1,5 @@ +checklistable + ->questions(1) + ->fill([ + ['question' => 'aassdd1'], + ['question' => 'aassdd2'], + ['question' => 'aassdd3'], + ['question' => 'aassdd4'], + ]); + + $response = $this + ->checklistable + ->answers(1) + ->start(1); + + + $this->assertInstanceOf(\Illuminate\Support\Collection::class, $response); + } + + public function test_answer() + { + $test = $this + ->checklistable + ->questions(1) + ->fill([ + ['question' => 'aassdd1'], + ['question' => 'aassdd2'], + ['question' => 'aassdd3'], + ['question' => 'aassdd4'], + ]); + + $response = $this + ->checklistable + ->answers(1) + ->start(1); + + $response = $this + ->checklistable + ->answers(1) + ->answer(1, 1, true); + + $this->assertEquals(true, $response); + } + + public function test_get() + { + $test = $this + ->checklistable + ->questions(1) + ->fill([ + ['question' => 'aassdd1'], + ['question' => 'aassdd2'], + ['question' => 'aassdd3'], + ['question' => 'aassdd4'], + ]); + + $response = $this + ->checklistable + ->answers(1) + ->get(1); + + $this->assertInstanceOf(\Illuminate\Support\Collection::class, $response); + } +} \ No newline at end of file diff --git a/tests/ChecklistableQuestionTest.php b/tests/ChecklistableQuestionTest.php new file mode 100644 index 0000000..7402907 --- /dev/null +++ b/tests/ChecklistableQuestionTest.php @@ -0,0 +1,45 @@ +checklistable->questions(1)->get(); + $this->assertInstanceOf(\Illuminate\Support\Collection::class, $response); + } + + public function test_fill() + { + $response = $this->checklistable->questions(1)->fill([['question' => 'test']]); + + $this->assertInstanceOf(\Illuminate\Support\Collection::class, $response); + } + + + public function test_add() + { + $response = $this->checklistable + ->questions(1) + ->add(['question' => 'test']); + + $this->assertInstanceOf(\Illuminate\Support\Collection::class, $response); + } + + public function test_del() + { + $this->checklistable + ->questions(1) + ->add(['question' => 'test']); + + $response = $this->checklistable + ->questions(1) + ->delete(1); + + $this->assertEquals(true, $response); + } +} \ No newline at end of file diff --git a/tests/ChecklistableTest.php b/tests/ChecklistableTest.php new file mode 100644 index 0000000..c4b66b6 --- /dev/null +++ b/tests/ChecklistableTest.php @@ -0,0 +1,29 @@ +checklistable->get(1); + + $this->assertInstanceOf(Checklist::class, $response); + } + + + public function test_questions() + { + $response = $this->checklistable->questions(1); + $this->assertInstanceOf(\Convenia\Checklistable\Services\ChecklistableQuestionService::class, $response); + } + + public function test_answers() + { + $response = $this->checklistable->answers(1); + $this->assertInstanceOf(\Convenia\Checklistable\Services\ChecklistableAnswerService::class, $response); + } +} \ No newline at end of file diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 0000000..34a4df5 --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,66 @@ +setUpDatabase(); + $this->checklistable = new ChecklistableService('Model\\Class', 'default'); + } + + + protected function setUpDatabase() + { + include_once __DIR__.'/../src/migrations/2017_05_30_160133_create_checklists_table.php'; + include_once __DIR__.'/../src/migrations/2017_05_30_160212_create_checklist_questions_table.php'; + include_once __DIR__.'/../src/migrations/2017_05_30_160235_create_checklist_answers_table.php'; + + (new \CreateChecklistsTable())->up(); + (new \CreateChecklistQuestionsTable())->up(); + (new \CreateChecklistAnswersTable())->up(); + + } + + /** + * @param \Illuminate\Foundation\Application $app + * + * @return array + */ + protected function getPackageProviders($app) + { + return [ + ChecklistableServiceProvider::class, + ]; + } + + /** + * @param \Illuminate\Foundation\Application $app + */ + protected function getEnvironmentSetUp($app) + { + $app['config']->set('database.default', 'sqlite'); + $app['config']->set('database.connections.sqlite', [ + 'driver' => 'sqlite', + 'database' => ':memory:', + 'prefix' => '', + ]); + + $app['config']->set('app.key', '6rE9Nz59bGRbeMATftriyQjrpF7DcOQm'); + } + +} \ No newline at end of file