diff --git a/.env.test b/.env.test new file mode 100644 index 0000000..fb4a966 --- /dev/null +++ b/.env.test @@ -0,0 +1,9 @@ +# define your env variables for the test env here +APP_ENV=test + +KERNEL_CLASS='App\Kernel' +APP_SECRET='$ecretf0rt3st' +SYMFONY_DEPRECATIONS_HELPER=999999 +PANTHER_APP_ENV=panther + +DATA_PATH=var/data/test-data \ No newline at end of file diff --git a/.gitignore b/.gitignore index be98836..90789e4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ - ###> symfony/framework-bundle ### /.env.local /.env.local.php @@ -9,3 +8,9 @@ /var/ /vendor/ ###< symfony/framework-bundle ### + +###> symfony/phpunit-bridge ### +.phpunit +.phpunit.result.cache +/phpunit.xml +###< symfony/phpunit-bridge ### diff --git a/bin/phpunit b/bin/phpunit new file mode 100755 index 0000000..4d1ed05 --- /dev/null +++ b/bin/phpunit @@ -0,0 +1,13 @@ +#!/usr/bin/env php +=7.1.3", + "symfony/dom-crawler": "^3.4|^4.0|^5.0" + }, + "require-dev": { + "symfony/css-selector": "^3.4|^4.0|^5.0", + "symfony/http-client": "^4.3|^5.0", + "symfony/mime": "^4.3|^5.0", + "symfony/process": "^3.4|^4.0|^5.0" + }, + "suggest": { + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\BrowserKit\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony BrowserKit Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-02T08:38:15+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v4.4.15", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "bf17dc9f6ce144e41f786c32435feea4d8e11dcc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/bf17dc9f6ce144e41f786c32435feea4d8e11dcc", + "reference": "bf17dc9f6ce144e41f786c32435feea4d8e11dcc", + "shasum": "" + }, + "require": { + "php": ">=7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony CssSelector Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-07-05T09:39:30+00:00" + }, + { + "name": "symfony/dom-crawler", + "version": "v4.4.15", + "source": { + "type": "git", + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "bdcb7633a501770a0daefbf81d2e6b28c3864f2b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/bdcb7633a501770a0daefbf81d2e6b28c3864f2b", + "reference": "bdcb7633a501770a0daefbf81d2e6b28c3864f2b", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "masterminds/html5": "<2.6" + }, + "require-dev": { + "masterminds/html5": "^2.6", + "symfony/css-selector": "^3.4|^4.0|^5.0" + }, + "suggest": { + "symfony/css-selector": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DomCrawler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DomCrawler Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-02T07:34:48+00:00" + }, + { + "name": "symfony/phpunit-bridge", + "version": "v5.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/phpunit-bridge.git", + "reference": "150aeb91dd9dafe13ec8416abd62e435330ca12d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/150aeb91dd9dafe13ec8416abd62e435330ca12d", + "reference": "150aeb91dd9dafe13ec8416abd62e435330ca12d", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0|<6.4,>=6.0|9.1.2" + }, + "require-dev": { + "symfony/deprecation-contracts": "^2.1" + }, + "suggest": { + "symfony/error-handler": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" + }, + "bin": [ + "bin/simple-phpunit" + ], + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + }, + "thanks": { + "name": "phpunit/phpunit", + "url": "https://github.com/sebastianbergmann/phpunit" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Bridge\\PhpUnit\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony PHPUnit Bridge", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-02T12:57:56+00:00" + } + ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..d81f0c3 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + tests + + + + + + src + + + + + + + diff --git a/src/Repository/Question/QuestionRepository.php b/src/Repository/Question/QuestionRepository.php index 22be3c6..1f258e4 100644 --- a/src/Repository/Question/QuestionRepository.php +++ b/src/Repository/Question/QuestionRepository.php @@ -33,14 +33,18 @@ public function __construct(StorageInterface $storage, DataFormatterInterface $f public function getAll(): QuestionCollection { $questionsData = $this->storage->get(); - + if (null === $questionsData) { + return new QuestionCollection(); + } return $this->formatter->getCollectionFromStorageFormat($questionsData); } public function storeOne(AbstractQuestion $question): AbstractQuestion { $storedData = $this->storage->get(); - $questions = $storedData ? $this->formatter->getCollectionFromStorageFormat($storedData) : new QuestionCollection(); + $questions = $storedData ? $this->formatter->getCollectionFromStorageFormat( + $storedData + ) : new QuestionCollection(); $questions->add($question); diff --git a/symfony.lock b/symfony.lock index 8d37d98..689b23e 100644 --- a/symfony.lock +++ b/symfony.lock @@ -53,6 +53,9 @@ "stichoza/google-translate-php": { "version": "v4.1.1" }, + "symfony/browser-kit": { + "version": "v4.4.15" + }, "symfony/cache": { "version": "v4.4.13" }, @@ -75,12 +78,18 @@ "config/bootstrap.php" ] }, + "symfony/css-selector": { + "version": "v4.4.15" + }, "symfony/debug": { "version": "v4.4.13" }, "symfony/dependency-injection": { "version": "v4.4.13" }, + "symfony/dom-crawler": { + "version": "v4.4.15" + }, "symfony/dotenv": { "version": "v4.4.13" }, @@ -140,6 +149,21 @@ "symfony/mime": { "version": "v4.4.13" }, + "symfony/phpunit-bridge": { + "version": "4.3", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "4.3", + "ref": "6d0e35f749d5f4bfe1f011762875275cd3f9874f" + }, + "files": [ + ".env.test", + "bin/phpunit", + "phpunit.xml.dist", + "tests/bootstrap.php" + ] + }, "symfony/polyfill-intl-idn": { "version": "v1.18.1" }, @@ -178,6 +202,9 @@ "symfony/service-contracts": { "version": "v2.2.0" }, + "symfony/test-pack": { + "version": "v1.0.6" + }, "symfony/var-dumper": { "version": "v4.4.13" }, diff --git a/tests/Functional/Controller/QuestionsControllerTest.php b/tests/Functional/Controller/QuestionsControllerTest.php new file mode 100644 index 0000000..38937fb --- /dev/null +++ b/tests/Functional/Controller/QuestionsControllerTest.php @@ -0,0 +1,38 @@ +request('GET', '/questions'); + + $this->assertResponseStatusCodeSame(200); + $this->assertResponseHeaderSame('content-type', 'application/json'); + } + + public function testPostActionValidData() + { + /* Todo move it to parent class */ + $json = file_get_contents(__DIR__ . '/../../fixtures/questionValidPostData.json'); + $client = static::createClient(); + $client->request('POST', '/question', [], [], [], $json); + + $this->assertResponseStatusCodeSame(200); + $this->assertResponseHeaderSame('content-type', 'application/json'); + $this->assertJsonStringEqualsJsonString($client->getResponse()->getContent(), $json); + } + + public function testPostActionInvalidData() + { + $json = file_get_contents(__DIR__ . '/../../fixtures/questionInvalidPostData.json'); + $client = static::createClient(); + $client->request('POST', '/question', [], [], [], $json); + + $this->assertResponseStatusCodeSame(400); + } +} \ No newline at end of file diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..469dcce --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,11 @@ +bootEnv(dirname(__DIR__).'/.env'); +} diff --git a/tests/fixtures/questionInvalidPostData.json b/tests/fixtures/questionInvalidPostData.json new file mode 100644 index 0000000..f62e74c --- /dev/null +++ b/tests/fixtures/questionInvalidPostData.json @@ -0,0 +1,12 @@ +{ + "text": "What does mean O.A.T. ?", + "createdAt": "2019-06-02 00:00:00", + "choices": [ + { + "text": "Open Assessment Technologies" + }, + { + "text": "Open Acknowledgment Technologies" + } + ] +} \ No newline at end of file diff --git a/tests/fixtures/questionValidPostData.json b/tests/fixtures/questionValidPostData.json new file mode 100644 index 0000000..ee748ae --- /dev/null +++ b/tests/fixtures/questionValidPostData.json @@ -0,0 +1,15 @@ +{ + "text": "What does mean O.A.T. ?", + "createdAt": "2019-06-02 00:00:00", + "choices": [ + { + "text": "Open Assignment Technologies" + }, + { + "text": "Open Assessment Technologies" + }, + { + "text": "Open Acknowledgment Technologies" + } + ] +} \ No newline at end of file