diff --git a/.env.dist b/.env.dist
index 2dc37bd9..a70e97b9 100644
--- a/.env.dist
+++ b/.env.dist
@@ -23,3 +23,6 @@ DATABASE_URL=sqlite:///%kernel.project_dir%/var/data/blog.sqlite
# Delivery is disabled by default via "null://localhost"
MAILER_URL=null://localhost
###< symfony/swiftmailer-bundle ###
+
+# hostname to use when running the acceptance tests
+ACCEPTANCE_TESTS_HOST="localhost"
diff --git a/.php_cs.dist b/.php_cs.dist
index ecd127eb..cec5ec9a 100644
--- a/.php_cs.dist
+++ b/.php_cs.dist
@@ -1,5 +1,7 @@
exclude('var')
->exclude('public/bundles')
->exclude('public/build')
+ ->exclude('tests/_support/_generated')
;
return PhpCsFixer\Config::create()
diff --git a/.scrutinizer.yml b/.scrutinizer.yml
index 68908b97..732afa99 100644
--- a/.scrutinizer.yml
+++ b/.scrutinizer.yml
@@ -3,6 +3,7 @@ build:
environment:
variables:
ENV: 'ci'
+ ACCEPTANCE_TESTS_PORT: 80
mysql: false
postgresql: false
redis: false
@@ -18,12 +19,9 @@ build:
- 'php:7.1-alpine'
- 'hgraca/explicit-architecture:app.sfn.base'
- dependencies:
- override:
- - true # so scrutinizer does't install the dependencies, which we don't need because they are inside the container
-
tests:
override:
+ - command: export ACCEPTANCE_TESTS_HOST=$DOCKER_IP
- command: make test-ci
coverage:
file: var/coverage.clover.xml
diff --git a/Makefile b/Makefile
index fe7ed62f..ba2fc401 100755
--- a/Makefile
+++ b/Makefile
@@ -105,18 +105,33 @@ test:
- ENV='tst' ./bin/stop # Just in case some container is left over stopped, as is the case after PHPStorm runs tests
ENV='tst' ./bin/run
ENV='tst' ./bin/run make db-setup-guest
- ENV='tst' ./bin/run php vendor/bin/phpunit
$(MAKE) cs-fix
+ ENV='tst' ./bin/run php vendor/bin/phpunit
ENV='tst' ./bin/stop
+ $(MAKE) test-acc
+
+test-acc:
+ - ENV='tst' ./bin/stop # Just in case some container is left over stopped, as is the case after PHPStorm runs tests
+ ENV='tst' ./bin/run make db-setup-guest
+ ENV='tst' docker-compose -f build/container/tst/docker-compose.yml up -d -t 0
+ php vendor/bin/codecept run acceptance
+ ENV='tst' ./bin/stop
+
+test-acc-ci:
+ - ENV='prd' ./bin/stop # Just in case some container is left over stopped, as is the case after PHPStorm runs tests
+ ENV='prd' docker-compose -f build/container/prd/docker-compose.yml up -d -t 0
+ php vendor/bin/codecept run acceptance
+ ENV='prd' ./bin/stop
test-ci:
$(MAKE) box-build-prd
$(MAKE) box-build-ci # This is always run by default in the Ci, but having it here makes it possible to run in dev
ENV='ci' ./bin/run
ENV='ci' ./bin/run make db-setup-guest
+ ENV='ci' ./bin/run php vendor/bin/php-cs-fixer fix --verbose --dry-run
ENV='ci' ./bin/run make test_cov-guest
docker exec -it app.sfn.ci cat ${COVERAGE_REPORT_PATH} > ${COVERAGE_REPORT_PATH}
- ENV='ci' ./bin/run php vendor/bin/php-cs-fixer fix --verbose --dry-run
+ $(MAKE) test-acc-ci
test_cov:
ENV='tst' ./bin/run make test_cov-guest
diff --git a/build/container/dev/docker-compose.yml b/build/container/dev/docker-compose.yml
index e0c195ac..97a1ed3a 100644
--- a/build/container/dev/docker-compose.yml
+++ b/build/container/dev/docker-compose.yml
@@ -10,7 +10,8 @@ services:
dockerfile: ./build/container/dev/app.dockerfile
tty: true # fix for symfony saying: "proc_open(/dev/tty): failed to open stream: No such device or address"
ports:
- - '80:8000' # This way we can run the application locally at http://localhost
+ # This way we can run the application locally at http://localhost:8000, and run ACC tests against PRD in port 80
+ - '80:8000'
volumes:
- ../../../:/opt/app
- ~/.composer:/.composer # so we can use the host composer cache
diff --git a/build/container/tst/docker-compose.yml b/build/container/tst/docker-compose.yml
index 0f34c8bf..f6d55f84 100644
--- a/build/container/tst/docker-compose.yml
+++ b/build/container/tst/docker-compose.yml
@@ -14,6 +14,8 @@ services:
- ~/.composer:/.composer # so we can use the host composer cache
- ./php.ini:/usr/local/etc/php/php.ini # so we can easily change php config
- ./xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini # so we can easily change xdebug config
+ ports:
+ - '8000:8000'
environment:
PHP_IDE_CONFIG: 'serverName=docker' # This is needed to debug from CLI (ie. while running tests)
ENV: 'tst'
diff --git a/codeception.yml b/codeception.yml
new file mode 100644
index 00000000..f79d9053
--- /dev/null
+++ b/codeception.yml
@@ -0,0 +1,13 @@
+params:
+ - .env # load params from .env file
+ - env # load params from environment
+paths:
+ tests: tests
+ output: var/acc_tests/output
+ data: tests/Fixture
+ support: tests/_support
+ envs: tests/_envs
+actor_suffix: Tester
+extensions:
+ enabled:
+ - Codeception\Extension\RunFailed
diff --git a/composer.json b/composer.json
index 5c98ce67..147a83c2 100644
--- a/composer.json
+++ b/composer.json
@@ -32,6 +32,7 @@
"white-october/pagerfanta-bundle": "^1.1"
},
"require-dev": {
+ "codeception/codeception": "^2.4",
"dama/doctrine-test-bundle": "^5.0",
"friendsofphp/php-cs-fixer": "^2.7",
"phpunit/phpunit": "^7.0",
diff --git a/composer.lock b/composer.lock
index 02e21c31..15e077ff 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1,10 +1,10 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "7d5e747f1a25e640255e3d122fcc88a5",
+ "content-hash": "bd07267b81599befce5e1bfe6162e5f6",
"packages": [
{
"name": "composer/ca-bundle",
@@ -4588,6 +4588,232 @@
}
],
"packages-dev": [
+ {
+ "name": "behat/gherkin",
+ "version": "v4.5.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Behat/Gherkin.git",
+ "reference": "74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Behat/Gherkin/zipball/74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a",
+ "reference": "74ac03d52c5e23ad8abd5c5cce4ab0e8dc1b530a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.5|~5",
+ "symfony/phpunit-bridge": "~2.7|~3",
+ "symfony/yaml": "~2.3|~3"
+ },
+ "suggest": {
+ "symfony/yaml": "If you want to parse features, represented in YAML files"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Behat\\Gherkin": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ }
+ ],
+ "description": "Gherkin DSL parser for PHP 5.3",
+ "homepage": "http://behat.org/",
+ "keywords": [
+ "BDD",
+ "Behat",
+ "Cucumber",
+ "DSL",
+ "gherkin",
+ "parser"
+ ],
+ "time": "2017-08-30T11:04:43+00:00"
+ },
+ {
+ "name": "codeception/codeception",
+ "version": "2.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/Codeception.git",
+ "reference": "bca3547632556875f1cdd567d6057cc14fe472b8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/Codeception/zipball/bca3547632556875f1cdd567d6057cc14fe472b8",
+ "reference": "bca3547632556875f1cdd567d6057cc14fe472b8",
+ "shasum": ""
+ },
+ "require": {
+ "behat/gherkin": "^4.4.0",
+ "codeception/phpunit-wrapper": "^6.0.9|^7.0.6",
+ "codeception/stub": "^1.0",
+ "ext-json": "*",
+ "ext-mbstring": "*",
+ "facebook/webdriver": ">=1.1.3 <2.0",
+ "guzzlehttp/guzzle": ">=4.1.4 <7.0",
+ "guzzlehttp/psr7": "~1.0",
+ "php": ">=5.4.0 <8.0",
+ "symfony/browser-kit": ">=2.7 <5.0",
+ "symfony/console": ">=2.7 <5.0",
+ "symfony/css-selector": ">=2.7 <5.0",
+ "symfony/dom-crawler": ">=2.7 <5.0",
+ "symfony/event-dispatcher": ">=2.7 <5.0",
+ "symfony/finder": ">=2.7 <5.0",
+ "symfony/yaml": ">=2.7 <5.0"
+ },
+ "require-dev": {
+ "codeception/specify": "~0.3",
+ "facebook/graph-sdk": "~5.3",
+ "flow/jsonpath": "~0.2",
+ "monolog/monolog": "~1.8",
+ "pda/pheanstalk": "~3.0",
+ "php-amqplib/php-amqplib": "~2.4",
+ "predis/predis": "^1.0",
+ "squizlabs/php_codesniffer": "~2.0",
+ "symfony/process": ">=2.7 <5.0",
+ "vlucas/phpdotenv": "^2.4.0"
+ },
+ "suggest": {
+ "aws/aws-sdk-php": "For using AWS Auth in REST module and Queue module",
+ "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests",
+ "codeception/specify": "BDD-style code blocks",
+ "codeception/verify": "BDD-style assertions",
+ "flow/jsonpath": "For using JSONPath in REST module",
+ "league/factory-muffin": "For DataFactory module",
+ "league/factory-muffin-faker": "For Faker support in DataFactory module",
+ "phpseclib/phpseclib": "for SFTP option in FTP Module",
+ "stecman/symfony-console-completion": "For BASH autocompletion",
+ "symfony/phpunit-bridge": "For phpunit-bridge support"
+ },
+ "bin": [
+ "codecept"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": []
+ },
+ "autoload": {
+ "psr-4": {
+ "Codeception\\": "src\\Codeception",
+ "Codeception\\Extension\\": "ext"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Bodnarchuk",
+ "email": "davert@mail.ua",
+ "homepage": "http://codegyre.com"
+ }
+ ],
+ "description": "BDD-style testing framework",
+ "homepage": "http://codeception.com/",
+ "keywords": [
+ "BDD",
+ "TDD",
+ "acceptance testing",
+ "functional testing",
+ "unit testing"
+ ],
+ "time": "2018-03-31T22:30:43+00:00"
+ },
+ {
+ "name": "codeception/phpunit-wrapper",
+ "version": "7.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/phpunit-wrapper.git",
+ "reference": "e8528cb777cf5a5ccea1cf57a3522b142625d1b5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/e8528cb777cf5a5ccea1cf57a3522b142625d1b5",
+ "reference": "e8528cb777cf5a5ccea1cf57a3522b142625d1b5",
+ "shasum": ""
+ },
+ "require": {
+ "phpunit/php-code-coverage": "^6.0",
+ "phpunit/phpunit": "^7.0",
+ "sebastian/comparator": "^2.0",
+ "sebastian/diff": "^3.0"
+ },
+ "require-dev": {
+ "codeception/specify": "*",
+ "vlucas/phpdotenv": "^2.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Codeception\\PHPUnit\\": "src\\"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Davert",
+ "email": "davert.php@resend.cc"
+ }
+ ],
+ "description": "PHPUnit classes used by Codeception",
+ "time": "2018-03-31T18:49:51+00:00"
+ },
+ {
+ "name": "codeception/stub",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/Stub.git",
+ "reference": "95fb7a36b81890dd2e5163e7ab31310df6f1bb99"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/Stub/zipball/95fb7a36b81890dd2e5163e7ab31310df6f1bb99",
+ "reference": "95fb7a36b81890dd2e5163e7ab31310df6f1bb99",
+ "shasum": ""
+ },
+ "require": {
+ "phpunit/phpunit-mock-objects": ">2.3 <7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": ">=4.8 <8.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Codeception\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Flexible Stub wrapper for PHPUnit's Mock Builder",
+ "time": "2018-02-18T13:56:56+00:00"
+ },
{
"name": "composer/semver",
"version": "1.4.2",
@@ -4707,6 +4933,61 @@
],
"time": "2018-02-25T14:57:01+00:00"
},
+ {
+ "name": "facebook/webdriver",
+ "version": "1.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/facebook/php-webdriver.git",
+ "reference": "86b5ca2f67173c9d34340845dd690149c886a605"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/86b5ca2f67173c9d34340845dd690149c886a605",
+ "reference": "86b5ca2f67173c9d34340845dd690149c886a605",
+ "shasum": ""
+ },
+ "require": {
+ "ext-curl": "*",
+ "ext-zip": "*",
+ "php": "^5.6 || ~7.0",
+ "symfony/process": "^2.8 || ^3.1 || ^4.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^2.0",
+ "guzzle/guzzle": "^3.4.1",
+ "php-coveralls/php-coveralls": "^1.0.2",
+ "php-mock/php-mock-phpunit": "^1.1",
+ "phpunit/phpunit": "^5.7",
+ "sebastian/environment": "^1.3.4 || ^2.0 || ^3.0",
+ "squizlabs/php_codesniffer": "^2.6",
+ "symfony/var-dumper": "^3.3 || ^4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-community": "1.5-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Facebook\\WebDriver\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "description": "A PHP client for Selenium WebDriver",
+ "homepage": "https://github.com/facebook/php-webdriver",
+ "keywords": [
+ "facebook",
+ "php",
+ "selenium",
+ "webdriver"
+ ],
+ "time": "2017-11-15T11:08:09+00:00"
+ },
{
"name": "friendsofphp/php-cs-fixer",
"version": "v2.11.1",
@@ -4801,6 +5082,187 @@
"description": "A tool to automatically fix PHP code style",
"time": "2018-03-21T17:41:26+00:00"
},
+ {
+ "name": "guzzlehttp/guzzle",
+ "version": "6.3.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/guzzle.git",
+ "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba",
+ "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/promises": "^1.0",
+ "guzzlehttp/psr7": "^1.4",
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "ext-curl": "*",
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
+ "psr/log": "^1.0"
+ },
+ "suggest": {
+ "psr/log": "Required for using the Log middleware"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "6.3-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions_include.php"
+ ],
+ "psr-4": {
+ "GuzzleHttp\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Guzzle is a PHP HTTP client library",
+ "homepage": "http://guzzlephp.org/",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "rest",
+ "web service"
+ ],
+ "time": "2018-04-22T15:46:56+00:00"
+ },
+ {
+ "name": "guzzlehttp/promises",
+ "version": "v1.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/promises.git",
+ "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+ "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Promise\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Guzzle promises library",
+ "keywords": [
+ "promise"
+ ],
+ "time": "2016-12-20T10:07:11+00:00"
+ },
+ {
+ "name": "guzzlehttp/psr7",
+ "version": "1.4.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/psr7.git",
+ "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
+ "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0",
+ "psr/http-message": "~1.0"
+ },
+ "provide": {
+ "psr/http-message-implementation": "1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Psr7\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Tobias Schultze",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "description": "PSR-7 message implementation that also provides common utility methods",
+ "keywords": [
+ "http",
+ "message",
+ "request",
+ "response",
+ "stream",
+ "uri",
+ "url"
+ ],
+ "time": "2017-03-20T17:10:46+00:00"
+ },
{
"name": "myclabs/deep-copy",
"version": "1.7.0",
@@ -5647,6 +6109,56 @@
],
"time": "2018-02-15T05:27:38+00:00"
},
+ {
+ "name": "psr/http-message",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "time": "2016-08-06T14:39:51+00:00"
+ },
{
"name": "roave/security-advisories",
"version": "dev-master",
diff --git a/src/DataFixtures/AppFixtures.php b/src/DataFixtures/AppFixtures.php
index 055e98dc..9983e5a3 100644
--- a/src/DataFixtures/AppFixtures.php
+++ b/src/DataFixtures/AppFixtures.php
@@ -22,6 +22,8 @@
class AppFixtures extends Fixture
{
+ public const JANE_ADMIN_NUM_POSTS = 25;
+
/**
* @var UserPasswordEncoderInterface
*/
@@ -133,7 +135,7 @@ private function getPostData(): array
$this->getPostContent(),
new \DateTime('now - '.$i.'days'),
// Ensure that the first post is written by Jane Doe to simplify tests
- $this->getReference(['jane_admin', 'tom_admin'][0 === $i ? 0 : random_int(0, 1)]),
+ $this->getReference(['jane_admin', 'tom_admin'][$i < self::JANE_ADMIN_NUM_POSTS ? 0 : 1]),
$this->getRandomTags(),
];
}
diff --git a/symfony.lock b/symfony.lock
index 6b7edb6f..283d6e81 100644
--- a/symfony.lock
+++ b/symfony.lock
@@ -1,4 +1,16 @@
{
+ "behat/gherkin": {
+ "version": "v4.5.1"
+ },
+ "codeception/codeception": {
+ "version": "2.4.1"
+ },
+ "codeception/phpunit-wrapper": {
+ "version": "7.0.6"
+ },
+ "codeception/stub": {
+ "version": "1.0.2"
+ },
"composer/ca-bundle": {
"version": "1.0.8"
},
diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php
new file mode 100644
index 00000000..33d88ad9
--- /dev/null
+++ b/tests/_support/AcceptanceTester.php
@@ -0,0 +1,21 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class AcceptanceTester extends \Codeception\Actor
+{
+ use _generated\AcceptanceTesterActions;
+
+ /*
+ * Define custom actions here
+ */
+}
diff --git a/tests/_support/Helper/Acceptance.php b/tests/_support/Helper/Acceptance.php
new file mode 100644
index 00000000..f8304205
--- /dev/null
+++ b/tests/_support/Helper/Acceptance.php
@@ -0,0 +1,21 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Helper;
+
+// here you can define custom actions
+// all public methods declared in helper class will be available in $I
+
+class Acceptance extends \Codeception\Module
+{
+}
diff --git a/tests/_support/_generated/AcceptanceTesterActions.php b/tests/_support/_generated/AcceptanceTesterActions.php
new file mode 100644
index 00000000..9961a451
--- /dev/null
+++ b/tests/_support/_generated/AcceptanceTesterActions.php
@@ -0,0 +1,2442 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace _generated;
+
+// This class was automatically generated by build task
+// You should not change it manually as it will be overwritten on next build
+// @codingStandardsIgnoreFile
+
+trait AcceptanceTesterActions
+{
+ /**
+ * @return \Codeception\Scenario
+ */
+ abstract protected function getScenario();
+
+ /**
+ * [!] Method is generated. Documentation taken from corresponding module.
+ *
+ * Alias to `haveHttpHeader`
+ *
+ * @param $name
+ * @param $value
+ *
+ * @see \Codeception\Module\PhpBrowser::setHeader()
+ */
+ public function setHeader($name, $value)
+ {
+ return $this->getScenario()->runStep(new \Codeception\Step\Action('setHeader', func_get_args()));
+ }
+
+ /**
+ * [!] Method is generated. Documentation taken from corresponding module.
+ *
+ * Authenticates user for HTTP_AUTH
+ *
+ * @param $username
+ * @param $password
+ *
+ * @see \Codeception\Module\PhpBrowser::amHttpAuthenticated()
+ */
+ public function amHttpAuthenticated($username, $password)
+ {
+ return $this->getScenario()->runStep(new \Codeception\Step\Condition('amHttpAuthenticated', func_get_args()));
+ }
+
+ /**
+ * [!] Method is generated. Documentation taken from corresponding module.
+ *
+ * Open web page at the given absolute URL and sets its hostname as the base host.
+ *
+ * ``` php
+ * amOnUrl('http://codeception.com');
+ * $I->amOnPage('/quickstart'); // moves to http://codeception.com/quickstart
+ * ?>
+ * ```
+ *
+ * @see \Codeception\Module\PhpBrowser::amOnUrl()
+ */
+ public function amOnUrl($url)
+ {
+ return $this->getScenario()->runStep(new \Codeception\Step\Condition('amOnUrl', func_get_args()));
+ }
+
+ /**
+ * [!] Method is generated. Documentation taken from corresponding module.
+ *
+ * Changes the subdomain for the 'url' configuration parameter.
+ * Does not open a page; use `amOnPage` for that.
+ *
+ * ``` php
+ * amOnSubdomain('user');
+ * $I->amOnPage('/');
+ * // moves to http://user.mysite.com/
+ * ?>
+ * ```
+ *
+ * @param $subdomain
+ *
+ * @return mixed
+ *
+ * @see \Codeception\Module\PhpBrowser::amOnSubdomain()
+ */
+ public function amOnSubdomain($subdomain)
+ {
+ return $this->getScenario()->runStep(new \Codeception\Step\Condition('amOnSubdomain', func_get_args()));
+ }
+
+ /**
+ * [!] Method is generated. Documentation taken from corresponding module.
+ *
+ * Low-level API method.
+ * If Codeception commands are not enough, use [Guzzle HTTP Client](http://guzzlephp.org/) methods directly
+ *
+ * Example:
+ *
+ * ``` php
+ * executeInGuzzle(function (\GuzzleHttp\Client $client) {
+ * $client->get('/get', ['query' => ['foo' => 'bar']]);
+ * });
+ * ?>
+ * ```
+ *
+ * It is not recommended to use this command on a regular basis.
+ * If Codeception lacks important Guzzle Client methods, implement them and submit patches.
+ *
+ * @param callable $function
+ *
+ * @see \Codeception\Module\PhpBrowser::executeInGuzzle()
+ */
+ public function executeInGuzzle($function)
+ {
+ return $this->getScenario()->runStep(new \Codeception\Step\Action('executeInGuzzle', func_get_args()));
+ }
+
+ /**
+ * [!] Method is generated. Documentation taken from corresponding module.
+ *
+ * Sets the HTTP header to the passed value - which is used on
+ * subsequent HTTP requests through PhpBrowser.
+ *
+ * Example:
+ * ```php
+ * haveHttpHeader('X-Requested-With', 'Codeception');
+ * $I->amOnPage('test-headers.php');
+ * ?>
+ * ```
+ *
+ * To use special chars in Header Key use HTML Character Entities:
+ * Example:
+ * Header with underscore - 'Client_Id'
+ * should be represented as - 'Client_Id' or 'Client_Id'
+ *
+ * ```php
+ * haveHttpHeader('Client_Id', 'Codeception');
+ * ?>
+ * ```
+ *
+ * @param string $name the name of the request header
+ * @param string $value the value to set it to for subsequent
+ * requests
+ *
+ * @see \Codeception\Lib\InnerBrowser::haveHttpHeader()
+ */
+ public function haveHttpHeader($name, $value)
+ {
+ return $this->getScenario()->runStep(new \Codeception\Step\Action('haveHttpHeader', func_get_args()));
+ }
+
+ /**
+ * [!] Method is generated. Documentation taken from corresponding module.
+ *
+ * Deletes the header with the passed name. Subsequent requests
+ * will not have the deleted header in its request.
+ *
+ * Example:
+ * ```php
+ * haveHttpHeader('X-Requested-With', 'Codeception');
+ * $I->amOnPage('test-headers.php');
+ * // ...
+ * $I->deleteHeader('X-Requested-With');
+ * $I->amOnPage('some-other-page.php');
+ * ?>
+ * ```
+ *
+ * @param string $name the name of the header to delete
+ *
+ * @see \Codeception\Lib\InnerBrowser::deleteHeader()
+ */
+ public function deleteHeader($name)
+ {
+ return $this->getScenario()->runStep(new \Codeception\Step\Action('deleteHeader', func_get_args()));
+ }
+
+ /**
+ * [!] Method is generated. Documentation taken from corresponding module.
+ *
+ * Opens the page for the given relative URI.
+ *
+ * ``` php
+ * amOnPage('/');
+ * // opens /register page
+ * $I->amOnPage('/register');
+ * ```
+ *
+ * @param string $page
+ *
+ * @see \Codeception\Lib\InnerBrowser::amOnPage()
+ */
+ public function amOnPage($page)
+ {
+ return $this->getScenario()->runStep(new \Codeception\Step\Condition('amOnPage', func_get_args()));
+ }
+
+ /**
+ * [!] Method is generated. Documentation taken from corresponding module.
+ *
+ * Perform a click on a link or a button, given by a locator.
+ * If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
+ * For buttons, the "value" attribute, "name" attribute, and inner text are searched.
+ * For links, the link text is searched.
+ * For images, the "alt" attribute and inner text of any parent links are searched.
+ *
+ * The second parameter is a context (CSS or XPath locator) to narrow the search.
+ *
+ * Note that if the locator matches a button of type `submit`, the form will be submitted.
+ *
+ * ``` php
+ * click('Logout');
+ * // button of form
+ * $I->click('Submit');
+ * // CSS button
+ * $I->click('#form input[type=submit]');
+ * // XPath
+ * $I->click('//form/*[@type=submit]');
+ * // link in context
+ * $I->click('Logout', '#nav');
+ * // using strict locator
+ * $I->click(['link' => 'Login']);
+ * ?>
+ * ```
+ *
+ * @param $link
+ * @param $context
+ *
+ * @see \Codeception\Lib\InnerBrowser::click()
+ */
+ public function click($link, $context = null)
+ {
+ return $this->getScenario()->runStep(new \Codeception\Step\Action('click', func_get_args()));
+ }
+
+ /**
+ * [!] Method is generated. Documentation taken from corresponding module.
+ *
+ * Checks that the current page contains the given string (case insensitive).
+ *
+ * You can specify a specific HTML element (via CSS or XPath) as the second
+ * parameter to only search within that element.
+ *
+ * ``` php
+ * see('Logout'); // I can suppose user is logged in
+ * $I->see('Sign Up', 'h1'); // I can suppose it's a signup page
+ * $I->see('Sign Up', '//body/h1'); // with XPath
+ * $I->see('Sign Up', ['css' => 'body h1']); // with strict CSS locator
+ * ```
+ *
+ * Note that the search is done after stripping all HTML tags from the body,
+ * so `$I->see('strong')` will return true for strings like:
+ *
+ * - `
I am Stronger than thou
`
+ * - ``
+ *
+ * But will *not* be true for strings like:
+ *
+ * - `Home`
+ * - `
Home`
+ * - ``
+ *
+ * For checking the raw source code, use `seeInSource()`.
+ *
+ * @param string $text
+ * @param string $selector optional
+ * Conditional Assertion: Test won't be stopped on fail
+ *
+ * @see \Codeception\Lib\InnerBrowser::see()
+ */
+ public function canSee($text, $selector = null)
+ {
+ return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('see', func_get_args()));
+ }
+
+ /**
+ * [!] Method is generated. Documentation taken from corresponding module.
+ *
+ * Checks that the current page contains the given string (case insensitive).
+ *
+ * You can specify a specific HTML element (via CSS or XPath) as the second
+ * parameter to only search within that element.
+ *
+ * ``` php
+ * see('Logout'); // I can suppose user is logged in
+ * $I->see('Sign Up', 'h1'); // I can suppose it's a signup page
+ * $I->see('Sign Up', '//body/h1'); // with XPath
+ * $I->see('Sign Up', ['css' => 'body h1']); // with strict CSS locator
+ * ```
+ *
+ * Note that the search is done after stripping all HTML tags from the body,
+ * so `$I->see('strong')` will return true for strings like:
+ *
+ * - `
I am Stronger than thou
`
+ * - ``
+ *
+ * But will *not* be true for strings like:
+ *
+ * - `Home`
+ * - `
Home`
+ * - ``
+ *
+ * For checking the raw source code, use `seeInSource()`.
+ *
+ * @param string $text
+ * @param string $selector optional
+ *
+ * @see \Codeception\Lib\InnerBrowser::see()
+ */
+ public function see($text, $selector = null)
+ {
+ return $this->getScenario()->runStep(new \Codeception\Step\Assertion('see', func_get_args()));
+ }
+
+ /**
+ * [!] Method is generated. Documentation taken from corresponding module.
+ *
+ * Checks that the current page doesn't contain the text specified (case insensitive).
+ * Give a locator as the second parameter to match a specific region.
+ *
+ * ```php
+ * dontSee('Login'); // I can suppose user is already logged in
+ * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page
+ * $I->dontSee('Sign Up','//body/h1'); // with XPath
+ * $I->dontSee('Sign Up', ['css' => 'body h1']); // with strict CSS locator
+ * ```
+ *
+ * Note that the search is done after stripping all HTML tags from the body,
+ * so `$I->dontSee('strong')` will fail on strings like:
+ *
+ * - `
Home`
+ * - ``
+ *
+ * For checking the raw source code, use `seeInSource()`.
+ *
+ * @param string $text
+ * @param string $selector optional
+ * Conditional Assertion: Test won't be stopped on fail
+ *
+ * @see \Codeception\Lib\InnerBrowser::dontSee()
+ */
+ public function cantSee($text, $selector = null)
+ {
+ return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSee', func_get_args()));
+ }
+
+ /**
+ * [!] Method is generated. Documentation taken from corresponding module.
+ *
+ * Checks that the current page doesn't contain the text specified (case insensitive).
+ * Give a locator as the second parameter to match a specific region.
+ *
+ * ```php
+ * dontSee('Login'); // I can suppose user is already logged in
+ * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page
+ * $I->dontSee('Sign Up','//body/h1'); // with XPath
+ * $I->dontSee('Sign Up', ['css' => 'body h1']); // with strict CSS locator
+ * ```
+ *
+ * Note that the search is done after stripping all HTML tags from the body,
+ * so `$I->dontSee('strong')` will fail on strings like:
+ *
+ * - `