diff --git a/.env.test b/.env.test new file mode 100644 index 0000000..d048686 --- /dev/null +++ b/.env.test @@ -0,0 +1,5 @@ +# define your env variables for the test env here +KERNEL_CLASS='App\Kernel' +APP_SECRET='$ecretf0rt3st' +SYMFONY_DEPRECATIONS_HELPER=999999 +PANTHER_APP_ENV=panther diff --git a/.gitignore b/.gitignore index 465493f..177f5d1 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,9 @@ npm-debug.log yarn-error.log ###< symfony/webpack-encore-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/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/framework-bundle": "^4.4|^5.0", + "symfony/http-kernel": "^4.4|^5.0" + }, + "conflict": { + "doctrine/doctrine-cache-bundle": "<1.3.1" + }, + "require-dev": { + "doctrine/doctrine-bundle": "^1.11|^2.0", + "doctrine/orm": "^2.5", + "nyholm/psr7": "^1.1", + "symfony/browser-kit": "^4.4|^5.0", + "symfony/dom-crawler": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/finder": "^4.4|^5.0", + "symfony/monolog-bridge": "^4.0|^5.0", + "symfony/monolog-bundle": "^3.2", + "symfony/phpunit-bridge": "^4.3.5|^5.0", + "symfony/psr-http-message-bridge": "^1.1", + "symfony/security-bundle": "^4.4|^5.0", + "symfony/twig-bundle": "^4.4|^5.0", + "symfony/yaml": "^4.4|^5.0", + "twig/twig": "^1.34|^2.4|^3.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "5.5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Sensio\\Bundle\\FrameworkExtraBundle\\": "src/" + }, + "exclude-from-classmap": [ + "/tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "This bundle provides a way to configure your controllers with annotations", + "keywords": [ + "annotations", + "controllers" + ], + "time": "2020-06-15T20:28:02+00:00" + }, { "name": "symfony/asset", "version": "v5.0.7", @@ -1565,6 +1638,79 @@ "homepage": "https://symfony.com", "time": "2020-03-27T16:56:45+00:00" }, + { + "name": "symfony/browser-kit", + "version": "v5.0.10", + "source": { + "type": "git", + "url": "https://github.com/symfony/browser-kit.git", + "reference": "16141bce671d4ee12cf45927e3ce6cd2f343c442" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/16141bce671d4ee12cf45927e3ce6cd2f343c442", + "reference": "16141bce671d4ee12cf45927e3ce6cd2f343c442", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/dom-crawler": "^4.4|^5.0" + }, + "require-dev": { + "symfony/css-selector": "^4.4|^5.0", + "symfony/http-client": "^4.4|^5.0", + "symfony/mime": "^4.4|^5.0", + "symfony/process": "^4.4|^5.0" + }, + "suggest": { + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-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-05-23T13:12:54+00:00" + }, { "name": "symfony/cache", "version": "v5.0.7", @@ -1842,6 +1988,73 @@ "homepage": "https://symfony.com", "time": "2020-03-30T11:42:42+00:00" }, + { + "name": "symfony/css-selector", + "version": "v5.0.10", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "79c224cdbfae58d54b257a8c684ad445042c90f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/79c224cdbfae58d54b257a8c684ad445042c90f2", + "reference": "79c224cdbfae58d54b257a8c684ad445042c90f2", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-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-05-20T17:38:26+00:00" + }, { "name": "symfony/dependency-injection", "version": "v5.0.7", @@ -2011,6 +2224,81 @@ "homepage": "https://symfony.com", "time": "2020-03-27T16:56:45+00:00" }, + { + "name": "symfony/dom-crawler", + "version": "v5.0.10", + "source": { + "type": "git", + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "9d86e7382e7fe96889440e29c1965e4e4f6f4aec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/9d86e7382e7fe96889440e29c1965e4e4f6f4aec", + "reference": "9d86e7382e7fe96889440e29c1965e4e4f6f4aec", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "masterminds/html5": "<2.6" + }, + "require-dev": { + "masterminds/html5": "^2.6", + "symfony/css-selector": "^4.4|^5.0" + }, + "suggest": { + "symfony/css-selector": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-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-05-23T12:58:59+00:00" + }, { "name": "symfony/dotenv", "version": "v5.0.7", @@ -3041,35 +3329,50 @@ "time": "2020-02-10T18:03:48+00:00" }, { - "name": "symfony/polyfill-intl-icu", - "version": "v1.15.0", + "name": "symfony/phpunit-bridge", + "version": "v5.1.2", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-icu.git", - "reference": "9c281272735eb66476e0fa7381e03fb0d4b60197" + "url": "https://github.com/symfony/phpunit-bridge.git", + "reference": "de5f0fec631a0cbfe98630b053be1fad7b75aece" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/9c281272735eb66476e0fa7381e03fb0d4b60197", - "reference": "9c281272735eb66476e0fa7381e03fb0d4b60197", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/de5f0fec631a0cbfe98630b053be1fad7b75aece", + "reference": "de5f0fec631a0cbfe98630b053be1fad7b75aece", "shasum": "" }, "require": { - "php": ">=5.3.3", - "symfony/intl": "~2.3|~3.0|~4.0|~5.0" + "php": ">=5.5.9" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0|<6.4,>=6.0|9.1.2" }, "suggest": { - "ext-intl": "For best performance" + "symfony/error-handler": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" }, - "type": "library", + "bin": [ + "bin/simple-phpunit" + ], + "type": "symfony-bridge", "extra": { "branch-alias": { - "dev-master": "1.15-dev" + "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/", @@ -3086,36 +3389,100 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's ICU-related data and classes", + "description": "Symfony PHPUnit Bridge", "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "icu", - "intl", - "polyfill", - "portable", - "shim" + "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-02-27T09:26:54+00:00" + "time": "2020-06-09T09:56:30+00:00" }, { - "name": "symfony/polyfill-intl-idn", + "name": "symfony/polyfill-intl-icu", "version": "v1.15.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf" + "url": "https://github.com/symfony/polyfill-intl-icu.git", + "reference": "9c281272735eb66476e0fa7381e03fb0d4b60197" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf", - "reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/9c281272735eb66476e0fa7381e03fb0d4b60197", + "reference": "9c281272735eb66476e0fa7381e03fb0d4b60197", "shasum": "" }, "require": { "php": ">=5.3.3", - "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php72": "^1.10" + "symfony/intl": "~2.3|~3.0|~4.0|~5.0" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.15-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "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 polyfill for intl's ICU-related data and classes", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "icu", + "intl", + "polyfill", + "portable", + "shim" + ], + "time": "2020-02-27T09:26:54+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.15.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf", + "reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php72": "^1.10" }, "suggest": { "ext-intl": "For best performance" @@ -3660,6 +4027,34 @@ "homepage": "https://symfony.com", "time": "2020-03-27T16:56:45+00:00" }, + { + "name": "symfony/test-pack", + "version": "v1.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/test-pack.git", + "reference": "ff87e800a67d06c423389f77b8209bc9dc469def" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/test-pack/zipball/ff87e800a67d06c423389f77b8209bc9dc469def", + "reference": "ff87e800a67d06c423389f77b8209bc9dc469def", + "shasum": "" + }, + "require": { + "php": "^7.0", + "symfony/browser-kit": "*", + "symfony/css-selector": "*", + "symfony/phpunit-bridge": "*" + }, + "type": "symfony-pack", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A pack for functional and end-to-end testing within a Symfony app", + "time": "2019-06-21T06:27:32+00:00" + }, { "name": "symfony/translation-contracts", "version": "v2.0.1", @@ -4498,103 +4893,123 @@ ], "packages-dev": [ { - "name": "nikic/php-parser", - "version": "v4.4.0", + "name": "doctrine/data-fixtures", + "version": "1.4.3", "source": { "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "bd43ec7152eaaab3bd8c6d0aa95ceeb1df8ee120" + "url": "https://github.com/doctrine/data-fixtures.git", + "reference": "7ebac50901eb4516816ac39100dba1759d843943" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bd43ec7152eaaab3bd8c6d0aa95ceeb1df8ee120", - "reference": "bd43ec7152eaaab3bd8c6d0aa95ceeb1df8ee120", + "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/7ebac50901eb4516816ac39100dba1759d843943", + "reference": "7ebac50901eb4516816ac39100dba1759d843943", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": ">=7.0" + "doctrine/common": "^2.11", + "doctrine/persistence": "^1.3.3", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "doctrine/phpcr-odm": "<1.3.0" }, "require-dev": { - "ircmaxell/php-yacc": "0.0.5", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0" + "alcaeus/mongo-php-adapter": "^1.1", + "doctrine/coding-standard": "^6.0", + "doctrine/dbal": "^2.5.4", + "doctrine/mongodb-odm": "^1.3.0", + "doctrine/orm": "^2.7.0", + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "alcaeus/mongo-php-adapter": "For using MongoDB ODM with PHP 7", + "doctrine/mongodb-odm": "For loading MongoDB ODM fixtures", + "doctrine/orm": "For loading ORM fixtures", + "doctrine/phpcr-odm": "For loading PHPCR ODM fixtures" }, - "bin": [ - "bin/php-parse" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "1.4.x-dev" } }, "autoload": { "psr-4": { - "PhpParser\\": "lib/PhpParser" + "Doctrine\\Common\\DataFixtures\\": "lib/Doctrine/Common/DataFixtures" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Nikita Popov" + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" } ], - "description": "A PHP parser written in PHP", + "description": "Data Fixtures for all Doctrine Object Managers", + "homepage": "http://www.doctrine-project.org", "keywords": [ - "parser", - "php" + "database" ], - "time": "2020-04-10T16:34:50+00:00" + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdata-fixtures", + "type": "tidelift" + } + ], + "time": "2020-05-25T19:45:03+00:00" }, { - "name": "symfony/maker-bundle", - "version": "v1.15.0", + "name": "doctrine/doctrine-fixtures-bundle", + "version": "3.3.1", "source": { "type": "git", - "url": "https://github.com/symfony/maker-bundle.git", - "reference": "31396f2e61803f0e2debbb43ba5aa21acbc6e15a" + "url": "https://github.com/doctrine/DoctrineFixturesBundle.git", + "reference": "39defca57ee0949e1475c46177b30b6d1b732e8f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/31396f2e61803f0e2debbb43ba5aa21acbc6e15a", - "reference": "31396f2e61803f0e2debbb43ba5aa21acbc6e15a", + "url": "https://api.github.com/repos/doctrine/DoctrineFixturesBundle/zipball/39defca57ee0949e1475c46177b30b6d1b732e8f", + "reference": "39defca57ee0949e1475c46177b30b6d1b732e8f", "shasum": "" }, "require": { - "doctrine/inflector": "^1.2", - "nikic/php-parser": "^4.0", - "php": "^7.0.8", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/console": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/filesystem": "^3.4|^4.0|^5.0", - "symfony/finder": "^3.4|^4.0|^5.0", - "symfony/framework-bundle": "^3.4|^4.0|^5.0", - "symfony/http-kernel": "^3.4|^4.0|^5.0" + "doctrine/data-fixtures": "^1.3", + "doctrine/doctrine-bundle": "^1.11|^2.0", + "doctrine/orm": "^2.6.0", + "doctrine/persistence": "^1.3", + "php": "^7.1", + "symfony/config": "^3.4|^4.3|^5.0", + "symfony/console": "^3.4|^4.3|^5.0", + "symfony/dependency-injection": "^3.4|^4.3|^5.0", + "symfony/doctrine-bridge": "^3.4|^4.1|^5.0", + "symfony/http-kernel": "^3.4|^4.3|^5.0" }, "require-dev": { - "doctrine/doctrine-bundle": "^1.8|^2.0", - "doctrine/orm": "^2.3", - "friendsofphp/php-cs-fixer": "^2.8", - "friendsoftwig/twigcs": "^3.1.2", - "symfony/http-client": "^4.3|^5.0", - "symfony/phpunit-bridge": "^4.3|^5.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/security-core": "^3.4|^4.0|^5.0", - "symfony/yaml": "^3.4|^4.0|^5.0" + "doctrine/coding-standard": "^6.0", + "phpunit/phpunit": "^7.4", + "symfony/phpunit-bridge": "^4.1|^5.0" }, "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "3.3.x-dev" } }, "autoload": { "psr-4": { - "Symfony\\Bundle\\MakerBundle\\": "src/" + "Doctrine\\Bundle\\FixturesBundle\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -4602,20 +5017,771 @@ "MIT" ], "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Doctrine Project", + "homepage": "http://www.doctrine-project.org" + }, { "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "homepage": "http://symfony.com/contributors" } ], - "description": "Symfony Maker helps you create empty commands, controllers, form classes, tests and more so you can forget about writing boilerplate code.", - "homepage": "https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html", + "description": "Symfony DoctrineFixturesBundle", + "homepage": "http://www.doctrine-project.org", "keywords": [ - "code generator", - "generator", - "scaffold", - "scaffolding" + "Fixture", + "persistence" ], - "time": "2020-04-05T10:50:59+00:00" + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdoctrine-fixtures-bundle", + "type": "tidelift" + } + ], + "time": "2020-04-02T16:40:37+00:00" + }, + { + "name": "fzaninotto/faker", + "version": "v1.9.1", + "source": { + "type": "git", + "url": "https://github.com/fzaninotto/Faker.git", + "reference": "fc10d778e4b84d5bd315dad194661e091d307c6f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/fc10d778e4b84d5bd315dad194661e091d307c6f", + "reference": "fc10d778e4b84d5bd315dad194661e091d307c6f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "ext-intl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7", + "squizlabs/php_codesniffer": "^2.9.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "time": "2019-12-12T13:22:17+00:00" + }, + { + "name": "liip/test-fixtures-bundle", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/liip/LiipTestFixturesBundle.git", + "reference": "c8d4984f134e21c2b6e30b85dbd62e60fdf824dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/liip/LiipTestFixturesBundle/zipball/c8d4984f134e21c2b6e30b85dbd62e60fdf824dd", + "reference": "c8d4984f134e21c2b6e30b85dbd62e60fdf824dd", + "shasum": "" + }, + "require": { + "doctrine/common": "^2.0", + "php": "^7.1", + "symfony/framework-bundle": "^3.4 || ^4.1 || ^5.0" + }, + "require-dev": { + "doctrine/data-fixtures": "^1.3", + "doctrine/doctrine-bundle": "^1.8 | ^2.0", + "doctrine/doctrine-fixtures-bundle": "^3.0.2", + "doctrine/orm": "^2.6", + "monolog/monolog": "~1.11 | ^2.0", + "phpunit/phpunit": "^7.5 || ^8.0", + "symfony/monolog-bridge": ">=3", + "symfony/monolog-bundle": "^3.2", + "symfony/phpunit-bridge": "^3.4 || ^4.1 || ^5.0", + "theofidry/alice-data-fixtures": "^1.0.1" + }, + "suggest": { + "doctrine/dbal": "Required when using the fixture loading functionality with an ORM and SQLite", + "doctrine/doctrine-fixtures-bundle": "Required when using the fixture loading functionality", + "doctrine/orm": "Required when using the fixture loading functionality with an ORM and SQLite", + "hautelook/alice-bundle": "Required when using loadFixtureFiles functionality with custom providers", + "theofidry/alice-data-fixtures": "Required when using loadFixtureFiles functionality" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Liip\\TestFixturesBundle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Liip AG", + "homepage": "http://www.liip.ch/" + }, + { + "name": "Community contributions", + "homepage": "https://github.com/liip/LiipTestFixturesBundle/contributors" + } + ], + "description": "This bundles enables efficient loading of Doctrine fixtures in functional test-cases for Symfony applications", + "keywords": [ + "fixtures", + "symfony", + "testing" + ], + "time": "2020-05-15T16:02:44+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.10.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2020-06-29T13:22:24+00:00" + }, + { + "name": "nelmio/alice", + "version": "3.7.1", + "source": { + "type": "git", + "url": "https://github.com/nelmio/alice.git", + "reference": "d9a06e4b2e6ef274d4f572198e455cde993d87bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nelmio/alice/zipball/d9a06e4b2e6ef274d4f572198e455cde993d87bb", + "reference": "d9a06e4b2e6ef274d4f572198e455cde993d87bb", + "shasum": "" + }, + "require": { + "fzaninotto/faker": "^1.6", + "myclabs/deep-copy": "^1.5.2", + "php": "^7.3", + "sebastian/comparator": "^3.0 || ^4.0", + "symfony/property-access": "^2.8 || ^3.4 || ^4.0 || ^5.0", + "symfony/yaml": "^2.8 || ^3.4 || ^4.0 || ^5.0" + }, + "conflict": { + "symfony/framework-bundle": "<3.4" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.1.0", + "php-mock/php-mock": "^2.0", + "phpspec/prophecy": "^1.6", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^8.5.4 || ^9.0", + "symfony/phpunit-bridge": "^5.0", + "symfony/var-dumper": "^3.4 || ^4.0 || ^5.0" + }, + "suggest": { + "theofidry/alice-data-fixtures": "Wrapper for Alice to provide a persistence layer." + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": false + }, + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "files": [ + "src/deep_clone.php" + ], + "psr-4": { + "Nelmio\\Alice\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + }, + { + "name": "Tim Shelburne", + "email": "shelburt02@gmail.com" + }, + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Expressive fixtures generator", + "keywords": [ + "Fixture", + "data", + "faker", + "test" + ], + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2020-06-03T12:55:55+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.4.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "bd43ec7152eaaab3bd8c6d0aa95ceeb1df8ee120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bd43ec7152eaaab3bd8c6d0aa95ceeb1df8ee120", + "reference": "bd43ec7152eaaab3bd8c6d0aa95ceeb1df8ee120", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "0.0.5", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.3-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2020-04-10T16:34:50+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f", + "reference": "dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-26T12:05:46+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113", + "reference": "1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-30T04:46:02+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "571d721db4aec847a0e59690b954af33ebf9f023" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/571d721db4aec847a0e59690b954af33ebf9f023", + "reference": "571d721db4aec847a0e59690b954af33ebf9f023", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-26T12:08:55+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "062231bf61d2b9448c4fa5a7643b5e1829c11d63" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/062231bf61d2b9448c4fa5a7643b5e1829c11d63", + "reference": "062231bf61d2b9448c4fa5a7643b5e1829c11d63", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-26T12:14:17+00:00" + }, + { + "name": "symfony/maker-bundle", + "version": "v1.15.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/maker-bundle.git", + "reference": "31396f2e61803f0e2debbb43ba5aa21acbc6e15a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/31396f2e61803f0e2debbb43ba5aa21acbc6e15a", + "reference": "31396f2e61803f0e2debbb43ba5aa21acbc6e15a", + "shasum": "" + }, + "require": { + "doctrine/inflector": "^1.2", + "nikic/php-parser": "^4.0", + "php": "^7.0.8", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/console": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/filesystem": "^3.4|^4.0|^5.0", + "symfony/finder": "^3.4|^4.0|^5.0", + "symfony/framework-bundle": "^3.4|^4.0|^5.0", + "symfony/http-kernel": "^3.4|^4.0|^5.0" + }, + "require-dev": { + "doctrine/doctrine-bundle": "^1.8|^2.0", + "doctrine/orm": "^2.3", + "friendsofphp/php-cs-fixer": "^2.8", + "friendsoftwig/twigcs": "^3.1.2", + "symfony/http-client": "^4.3|^5.0", + "symfony/phpunit-bridge": "^4.3|^5.0", + "symfony/process": "^3.4|^4.0|^5.0", + "symfony/security-core": "^3.4|^4.0|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bundle\\MakerBundle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Maker helps you create empty commands, controllers, form classes, tests and more so you can forget about writing boilerplate code.", + "homepage": "https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html", + "keywords": [ + "code generator", + "generator", + "scaffold", + "scaffolding" + ], + "time": "2020-04-05T10:50:59+00:00" + }, + { + "name": "theofidry/alice-data-fixtures", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/AliceDataFixtures.git", + "reference": "f98ef1b7965f043a497a49e8221f3327f2835cea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/AliceDataFixtures/zipball/f98ef1b7965f043a497a49e8221f3327f2835cea", + "reference": "f98ef1b7965f043a497a49e8221f3327f2835cea", + "shasum": "" + }, + "require": { + "nelmio/alice": "^3.5", + "php": "^7.2", + "psr/log": "^1.0" + }, + "conflict": { + "doctrine/orm": "<2.5", + "illuminate/database": "<5.5", + "ocramius/proxy-manager": "<2.1", + "symfony/framework-bundle": "<3.4" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.1", + "phpspec/prophecy": "^1.7", + "phpunit/phpunit": "^8.5.4 || ^9.0", + "symfony/phpunit-bridge": "^3.4 || ^4.0 || ^5.0" + }, + "suggest": { + "alcaeus/mongo-php-adapter": "To use Doctrine with the MongoDB flavour", + "doctrine/data-fixtures": "To use Doctrine", + "doctrine/dbal": "To use Doctrine with the PHPCR flavour", + "doctrine/mongodb": "To use Doctrine with the MongoDB flavour", + "doctrine/mongodb-odm": "To use Doctrine with the MongoDB flavour", + "doctrine/orm": "To use Doctrine ORM", + "doctrine/phpcr-odm": "To use Doctrine with the PHPCR flavour", + "illuminate/database": "To use Eloquent", + "jackalope/jackalope-doctrine-dbal": "To use Doctrine with the PHPCR flavour", + "ocramius/proxy-manager": "To avoid database connection on kernel boot" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": false + }, + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Fidry\\AliceDataFixtures\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com", + "homepage": "https://github.com/theofidry" + } + ], + "description": "Nelmio alice extension to persist the loaded fixtures.", + "keywords": [ + "Fixture", + "alice", + "data", + "faker", + "orm", + "tests" + ], + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2020-06-19T13:54:56+00:00" } ], "aliases": [], @@ -4628,5 +5794,6 @@ "ext-ctype": "*", "ext-iconv": "*" }, - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "1.1.0" } diff --git a/config/bundles.php b/config/bundles.php index f702c9a..6c97571 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -8,4 +8,9 @@ Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true], Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], + Nelmio\Alice\Bridge\Symfony\NelmioAliceBundle::class => ['dev' => true, 'test' => true], + Fidry\AliceDataFixtures\Bridge\Symfony\FidryAliceDataFixturesBundle::class => ['dev' => true, 'test' => true], + Liip\TestFixturesBundle\LiipTestFixturesBundle::class => ['dev' => true, 'test' => true], + Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true], + Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true], ]; diff --git a/config/packages/dev/nelmio_alice.yaml b/config/packages/dev/nelmio_alice.yaml new file mode 100644 index 0000000..4cb9065 --- /dev/null +++ b/config/packages/dev/nelmio_alice.yaml @@ -0,0 +1,9 @@ +nelmio_alice: + functions_blacklist: + - 'current' + - 'shuffle' + - 'date' + - 'time' + - 'file' + - 'md5' + - 'sha1' diff --git a/config/packages/sensio_framework_extra.yaml b/config/packages/sensio_framework_extra.yaml new file mode 100644 index 0000000..1821ccc --- /dev/null +++ b/config/packages/sensio_framework_extra.yaml @@ -0,0 +1,3 @@ +sensio_framework_extra: + router: + annotations: false diff --git a/config/packages/test/nelmio_alice.yaml b/config/packages/test/nelmio_alice.yaml new file mode 100644 index 0000000..caec543 --- /dev/null +++ b/config/packages/test/nelmio_alice.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: ../dev/nelmio_alice.yaml } diff --git a/package.json b/package.json index cd34d96..bb1d0c3 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,5 @@ "watch": "encore dev --watch", "build": "encore production --progress" }, - "dependencies": { - } + "dependencies": {} } 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/Controller/ArticlesController.php b/src/Controller/ArticlesController.php index 9efa30c..673e703 100644 --- a/src/Controller/ArticlesController.php +++ b/src/Controller/ArticlesController.php @@ -6,8 +6,10 @@ use App\Entity\PostCount; use App\Form\ArticleType; use App\Repository\PostCountRepository; +use App\Service\UseCase\Article\RegisterUseCase; use DateTime; use Exception; +use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; @@ -16,53 +18,56 @@ class ArticlesController extends AbstractController { + /** + * @var RegisterUseCase + */ + private $registerUseCase; + + /** + * @param RegisterUseCase $registerUseCase + */ + public function __construct(RegisterUseCase $registerUseCase) + { + $this->registerUseCase = $registerUseCase; + } + /** * @Route("/articles", name="articles") + * @Template() + * @return array */ public function index() { $articleRepository = $this->getDoctrine()->getRepository(Article::class); $articles = $articleRepository->findAll(); - return $this->render('articles/index.html.twig', [ + + return [ 'articles' => $articles, - ]); + ]; } /** * @Route("/articles/new", name="articles_new") + * @Template * @param Request $request - * @return RedirectResponse|Response + * @return RedirectResponse|array * @throws Exception */ public function new(Request $request) { - $article = new Article(); - $form = $this->createForm(ArticleType::class, $article); + $form = $this->createForm(ArticleType::class); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $article = $form->getData(); - $entityManager = $this->getDoctrine()->getManager(); - $entityManager->persist($article); - /** @var PostCountRepository $postCountRepository */ - $postCountRepository = $this->getDoctrine()->getRepository(PostCount::class); - $postCount = $postCountRepository->findOneBy([ - 'postDate' => new DateTime(), - ]); - if (empty($postCount)) { - $postCount = new PostCount(); - $postCount->setPostDate(new DateTime()); - $entityManager->persist($postCount); - } - $postCount->setPostCount($postCount->getPostCount() + 1); - $entityManager->flush(); + $this->registerUseCase->register($article); $this->addFlash('success', '登録しました'); return $this->redirectToRoute('articles'); } - return $this->render('articles/new.html.twig', [ + return [ 'form' => $form->createView(), - ]); + ]; } } diff --git a/src/DTO/Request/PostedArticle.php b/src/DTO/Request/PostedArticle.php new file mode 100644 index 0000000..9b61894 --- /dev/null +++ b/src/DTO/Request/PostedArticle.php @@ -0,0 +1,60 @@ +name; + } + + /** + * @param string|null $name + * @return PostedArticle + */ + public function setName($name) + { + $this->name = $name; + + return $this; + } + + /** + * @return string|null + */ + public function getBody(): ?string + { + return $this->body; + } + + /** + * @param string|null $body + * @return PostedArticle + */ + public function setBody($body) + { + $this->body = $body; + + return $this; + } +} diff --git a/src/Entity/Article.php b/src/Entity/Article.php index 50996b2..8925aa9 100644 --- a/src/Entity/Article.php +++ b/src/Entity/Article.php @@ -2,15 +2,15 @@ namespace App\Entity; +use App\Model\ArticleInterface; use DateTimeInterface as DateTimeInterfaceAlias; use Doctrine\ORM\Mapping as ORM; -use Symfony\Component\Validator\Constraints as Assert; /** * @ORM\Entity(repositoryClass="App\Repository\ArticleRepository") * @ORM\HasLifecycleCallbacks() */ -class Article +class Article implements ArticleInterface { /** * @ORM\Id() @@ -21,14 +21,11 @@ class Article /** * @ORM\Column(type="string", length=255) - * @Assert\NotBlank - * @Assert\Length(max=255) */ private $name; /** * @ORM\Column(type="text") - * @Assert\Length(max=1000) */ private $body; @@ -52,7 +49,7 @@ public function getName(): ?string return $this->name; } - public function setName(string $name): self + public function setName(string $name): ArticleInterface { $this->name = $name; @@ -64,7 +61,7 @@ public function getBody(): ?string return $this->body; } - public function setBody(string $body): self + public function setBody(string $body): ArticleInterface { $this->body = $body; diff --git a/src/Entity/PostCount.php b/src/Entity/PostCount.php index 4c141f1..e79f0b4 100644 --- a/src/Entity/PostCount.php +++ b/src/Entity/PostCount.php @@ -2,6 +2,7 @@ namespace App\Entity; +use App\Model\PostCountInterface; use Doctrine\ORM\Mapping as ORM; /** @@ -10,7 +11,7 @@ * @ORM\UniqueConstraint(columns={"post_date"} * )}) */ -class PostCount +class PostCount implements PostCountInterface { /** * @ORM\Id() @@ -57,4 +58,9 @@ public function setPostCount(int $postCount): self return $this; } + + public function countUp(): void + { + $this->postCount++; + } } diff --git a/src/Form/ArticleType.php b/src/Form/ArticleType.php index 591ad6e..a6a5ef2 100644 --- a/src/Form/ArticleType.php +++ b/src/Form/ArticleType.php @@ -2,7 +2,7 @@ namespace App\Form; -use App\Entity\Article; +use App\DTO\Request\PostedArticle; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; @@ -24,7 +24,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => Article::class, + 'data_class' => PostedArticle::class, ]); } } diff --git a/src/Model/ArticleCounterInterface.php b/src/Model/ArticleCounterInterface.php new file mode 100644 index 0000000..79a959b --- /dev/null +++ b/src/Model/ArticleCounterInterface.php @@ -0,0 +1,8 @@ +findOneBy([ + 'postDate' => $postedDate, + ]); + if (!$targetCount) { + $targetCount = new PostCount(); + $targetCount + ->setPostDate($postedDate) + ->setPostCount(0) + ; + } + + return $targetCount; + } + // /** // * @return PostCount[] Returns an array of PostCount objects // */ diff --git a/src/Service/ArticleCounter.php b/src/Service/ArticleCounter.php new file mode 100644 index 0000000..4d9a592 --- /dev/null +++ b/src/Service/ArticleCounter.php @@ -0,0 +1,43 @@ +postCountFinder = $postCountFinder; + $this->em = $em; + } + + public function count(ArticleInterface $article): void + { + /** @var Article $article */ + $postCount = $this->postCountFinder->findOneByPostDateOrCreate($article->getCreatedAt()); + $postCount->countUp(); + + $this->em->persist($postCount); + $this->em->flush(); + } + +} diff --git a/src/Service/ArticlePersister.php b/src/Service/ArticlePersister.php new file mode 100644 index 0000000..ca76da9 --- /dev/null +++ b/src/Service/ArticlePersister.php @@ -0,0 +1,42 @@ +em = $em; + } + + public function persist(PostedArticleInterface $postedArticle, ArticleInterface $saveArticle): ArticleInterface + { + /** @var PostedArticle $postedArticle */ + /** @var Article $saveArticle */ + $saveArticle + ->setName($postedArticle->getName()) + ->setBody($postedArticle->getBody()) + ; + + $this->em->persist($saveArticle); + $this->em->flush(); + + return $saveArticle; + } + +} diff --git a/src/Service/UseCase/Article/Exception/RegisterException.php b/src/Service/UseCase/Article/Exception/RegisterException.php new file mode 100644 index 0000000..1f524e0 --- /dev/null +++ b/src/Service/UseCase/Article/Exception/RegisterException.php @@ -0,0 +1,8 @@ +articlePersister = $articlePersister; + $this->articleCounter = $articleCounter; + } + + /** + * @param PostedArticle $postedArticle + * @throws RegisterException + */ + public function register(PostedArticle $postedArticle): void + { + try { + $savedArticle = $this->articlePersister->persist($postedArticle, new Article()); + } catch (\Exception $e) { + throw new RegisterException($e->getMessage(), $e->getCode(), $e); + } + + $this->articleCounter->count($savedArticle); + } +} diff --git a/symfony.lock b/symfony.lock index 92d3d45..57b4d8c 100644 --- a/symfony.lock +++ b/symfony.lock @@ -20,6 +20,9 @@ "doctrine/common": { "version": "2.12.0" }, + "doctrine/data-fixtures": { + "version": "1.4.3" + }, "doctrine/dbal": { "version": "v2.10.1" }, @@ -38,6 +41,18 @@ "src/Repository/.gitignore" ] }, + "doctrine/doctrine-fixtures-bundle": { + "version": "3.0", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "3.0", + "ref": "fc52d86631a6dfd9fdf3381d0b7e3df2069e51b3" + }, + "files": [ + "src/DataFixtures/AppFixtures.php" + ] + }, "doctrine/doctrine-migrations-bundle": { "version": "1.2", "recipe": { @@ -75,9 +90,31 @@ "doctrine/reflection": { "version": "1.2.1" }, + "fzaninotto/faker": { + "version": "v1.9.1" + }, "jdorn/sql-formatter": { "version": "v1.2.17" }, + "liip/test-fixtures-bundle": { + "version": "1.9.1" + }, + "myclabs/deep-copy": { + "version": "1.10.1" + }, + "nelmio/alice": { + "version": "3.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "3.2", + "ref": "0b9900ece737bec7752e4155c0164639dd9b0cb0" + }, + "files": [ + "config/packages/dev/nelmio_alice.yaml", + "config/packages/test/nelmio_alice.yaml" + ] + }, "nikic/php-parser": { "version": "v4.4.0" }, @@ -102,9 +139,36 @@ "psr/log": { "version": "1.1.3" }, + "sebastian/comparator": { + "version": "4.0.3" + }, + "sebastian/diff": { + "version": "4.0.2" + }, + "sebastian/exporter": { + "version": "4.0.2" + }, + "sebastian/recursion-context": { + "version": "4.0.2" + }, + "sensio/framework-extra-bundle": { + "version": "5.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "5.2", + "ref": "fb7e19da7f013d0d422fa9bce16f5c510e27609b" + }, + "files": [ + "config/packages/sensio_framework_extra.yaml" + ] + }, "symfony/asset": { "version": "v5.0.7" }, + "symfony/browser-kit": { + "version": "v5.0.10" + }, "symfony/cache": { "version": "v5.0.7" }, @@ -127,12 +191,18 @@ "config/bootstrap.php" ] }, + "symfony/css-selector": { + "version": "v5.0.10" + }, "symfony/dependency-injection": { "version": "v5.0.7" }, "symfony/doctrine-bridge": { "version": "v5.0.7" }, + "symfony/dom-crawler": { + "version": "v5.0.10" + }, "symfony/dotenv": { "version": "v5.0.7" }, @@ -216,6 +286,21 @@ "symfony/orm-pack": { "version": "v1.0.8" }, + "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-icu": { "version": "v1.15.0" }, @@ -257,6 +342,9 @@ "symfony/stopwatch": { "version": "v5.0.7" }, + "symfony/test-pack": { + "version": "v1.0.6" + }, "symfony/translation-contracts": { "version": "v2.0.1" }, @@ -321,6 +409,15 @@ "symfony/yaml": { "version": "v5.0.7" }, + "theofidry/alice-data-fixtures": { + "version": "1.0", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "1.0", + "ref": "fe5a50faf580eb58f08ada2abe8afbd2d4941e05" + } + }, "twig/extra-bundle": { "version": "v3.0.3" }, diff --git a/templates/articles/index.html.twig b/templates/articles/index.html.twig index d605356..3941cbd 100644 --- a/templates/articles/index.html.twig +++ b/templates/articles/index.html.twig @@ -34,7 +34,6 @@ {{ article.createdAt|date('Y/m/d') }} {% endfor %} - diff --git a/templates/articles/new.html.twig b/templates/articles/new.html.twig index 0743329..529eba2 100644 --- a/templates/articles/new.html.twig +++ b/templates/articles/new.html.twig @@ -6,6 +6,7 @@

フォーム

{{ form_start(form) }} {{ form_widget(form) }} + {{ form_end(form) }} {% endblock %} diff --git a/tests/Controller/Articles/IndexTest.php b/tests/Controller/Articles/IndexTest.php new file mode 100644 index 0000000..c916e90 --- /dev/null +++ b/tests/Controller/Articles/IndexTest.php @@ -0,0 +1,26 @@ +loadFixtureFiles([ + __DIR__.'/../../../var/fixtures/Controller/Articles/index.yaml', + ]); + + $crawler = $client->request('GET', '/articles'); + + $response = $client->getResponse(); + $this->assertTrue($response->isOk(), $response->getStatusCode()); + + $this->assertCount(2, $crawler->filter('table tbody tr')); + } +} diff --git a/tests/Controller/Articles/NewTest.php b/tests/Controller/Articles/NewTest.php new file mode 100644 index 0000000..135075c --- /dev/null +++ b/tests/Controller/Articles/NewTest.php @@ -0,0 +1,27 @@ +loadFixtureFiles([]); + + $crawler = $client->request('GET', '/articles/new'); + $form = $crawler->selectButton('投稿する')->form(); + + $form['article[name]'] = 'test-name'; + $form['article[body]'] = 'test-body'; + $client->submit($form); + + $response = $client->getResponse(); + $this->assertTrue($response->isRedirect('/articles'), $response->headers->get('Location')); + } +} diff --git a/tests/Form/ArticleTypeTest.php b/tests/Form/ArticleTypeTest.php new file mode 100644 index 0000000..fd8731e --- /dev/null +++ b/tests/Form/ArticleTypeTest.php @@ -0,0 +1,23 @@ +factory->create(ArticleType::class); + $form->submit([ + 'name' => 'aaa', + 'body' => 'bbb', + ]); + + $this->assertTrue($form->isSubmitted()); + $this->assertTrue($form->isValid()); + $this->assertInstanceOf(PostedArticle::class, $form->getData()); + } +} diff --git a/tests/Functional/Repository/PostCountRepositoryTest/FindOneByPostDateOrCreateTest.php b/tests/Functional/Repository/PostCountRepositoryTest/FindOneByPostDateOrCreateTest.php new file mode 100644 index 0000000..d3018d3 --- /dev/null +++ b/tests/Functional/Repository/PostCountRepositoryTest/FindOneByPostDateOrCreateTest.php @@ -0,0 +1,42 @@ +loadFixtureFiles([ + __DIR__.'/../../../../var/fixtures/Repository/PostCountRepository/find_one_by_post_date_or_create.yaml', + ]); + static::ensureKernelShutdown(); + } + + public function test_既存PostCountがある場合() + { + $actual = $this->getSUT()->findOneByPostDateOrCreate(new \DateTimeImmutable('2020-09-01')); + $this->assertEquals(1, $actual->getPostCount(), '保存されているエンティティが出てきている'); + } + + public function test_既存PostCountがない場合() + { + $actual = $this->getSUT()->findOneByPostDateOrCreate(new \DateTimeImmutable('2020-09-02')); + $this->assertNull($actual->getId()); + $this->assertNotNull($actual->getPostDate(), '日付はセット済'); + $this->assertEquals(null, $actual->getPostCount(), 'newされたばかりなのでnull'); + } + + private function getSUT(): PostCountRepository + { + static::bootKernel(); + + return self::$kernel->getContainer()->get('doctrine')->getManager()->getRepository(PostCount::class); + } +} diff --git a/tests/Service/ArticleCounterTest.php b/tests/Service/ArticleCounterTest.php new file mode 100644 index 0000000..0ffc6e6 --- /dev/null +++ b/tests/Service/ArticleCounterTest.php @@ -0,0 +1,38 @@ +prophesize(ArticleInterface::class); + $articleP->getCreatedAt()->willReturn($createdAt)->shouldBeCalled(); + $article = $articleP->reveal(); + + $postCountP = $this->prophesize(PostCountInterface::class); + $postCountP->countUp()->shouldBeCalled(); + $postCount = $postCountP->reveal(); + + $finderP = $this->prophesize(PostCountFinderInterface::class); + $emP = $this->prophesize(EntityManagerInterface::class); + + $finderP->findOneByPostDateOrCreate($createdAt)->willReturn($postCount)->shouldBeCalled(); + $emP->persist($postCount)->shouldBeCalled(); + $emP->flush()->shouldBeCalled(); + + $SUT = new ArticleCounter( + $finderP->reveal(), + $emP->reveal() + ); + $SUT->count($article); + } +} diff --git a/tests/Service/ArticlePersisterTest.php b/tests/Service/ArticlePersisterTest.php new file mode 100644 index 0000000..aa8873e --- /dev/null +++ b/tests/Service/ArticlePersisterTest.php @@ -0,0 +1,44 @@ +emP = $this->prophesize(EntityManagerInterface::class); + } + + public function test() + { + $dto = new PostedArticle(); + $dto + ->setName($name = 'dummy-name') + ->setBody($body = 'dummy-body') + ; + $ormEntity = new Article(); + + $this->emP->persist($ormEntity)->shouldBeCalled(); + $this->emP->flush()->shouldBeCalled(); + + $returned = $this->getSUT()->persist($dto, $ormEntity); + $this->assertSame($ormEntity, $returned); + $this->assertEquals($name, $returned->getName()); + $this->assertEquals($body, $returned->getBody()); + } + + private function getSUT(): ArticlePersister + { + return new ArticlePersister( + $this->emP->reveal() + ); + } +} diff --git a/tests/Service/UseCase/Article/RegisterUseCaseTest.php b/tests/Service/UseCase/Article/RegisterUseCaseTest.php new file mode 100644 index 0000000..6670090 --- /dev/null +++ b/tests/Service/UseCase/Article/RegisterUseCaseTest.php @@ -0,0 +1,67 @@ +articlePersisterP = $this->prophesize(ArticlePersisterInterface::class); + $this->articleCounterP = $this->prophesize(ArticleCounterInterface::class); + } + + protected function tearDown(): void + { + $this->articlePersisterP = null; + $this->articleCounterP = null; + } + + public function test() + { + $postedArticle = $this->prophesize(PostedArticle::class)->reveal(); + + $this->articlePersisterP->persist($postedArticle, new Article())->willReturnArgument(1)->shouldBeCalled(); + $this->articleCounterP->count(Argument::type(Article::class))->shouldBeCalled(); + + $this->getSUT()->register($postedArticle); + } + + public function test_保存でエラーが出たらcountは更新しない() + { + $this->expectException(RegisterException::class); + + $postedArticle = $this->prophesize(PostedArticle::class)->reveal(); + $this->articlePersisterP->persist($postedArticle, new Article())->willThrow( new \Exception('dummy-error'))->shouldBeCalled(); + $this->articleCounterP->count(Argument::any())->shouldNotBeCalled(); + + $this->getSUT()->register($postedArticle); + } + + private function getSUT(): RegisterUseCase + { + return new RegisterUseCase( + $this->articlePersisterP->reveal(), + $this->articleCounterP->reveal() + ); + } +} 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'); +}