diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a384886f..ee1dae49 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: DB_DATABASE: phplist DB_USERNAME: root DB_PASSWORD: phplist - BROADCAST_DRIVER: log + BROADCAST_DRIVER: log services: mysql: image: mysql:5.7 @@ -22,16 +22,21 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ['7.2', '7.3', '7.4', '8.0'] + php-versions: ['8.1'] steps: - name: Checkout uses: actions/checkout@v2 - name: Setup PHP, with composer and extensions - uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php + uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-versions }} extensions: mbstring, dom, fileinfo, mysql coverage: xdebug #optional + - name: Install Symfony CLI + run: | + curl -sS https://get.symfony.com/cli/installer | bash + mv $HOME/.symfony*/bin/symfony /usr/local/bin/symfony + symfony version - name: Start mysql service run: sudo /etc/init.d/mysql start - name: Verify MySQL connection on host @@ -45,40 +50,29 @@ jobs: uses: actions/cache@v2 with: path: ${{ steps.composer-cache.outputs.dir }} - # Use composer.json for key, if composer.lock is not committed. - # key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: ${{ runner.os }}-composer- - name: Install Composer dependencies run: composer install --no-progress --prefer-dist --optimize-autoloader - continue-on-error: ${{matrix.php-versions == '8.0' }} # Temporal until full support for php8 === [temp-php8] - name: Validating composer.json run: composer validate --no-check-all --no-check-lock --strict; - continue-on-error: ${{matrix.php-versions == '8.0' }} # [temp-php8] - name: Linting all php files run: find src/ tests/ public/ -name ''*.php'' -print0 | xargs -0 -n 1 -P 4 php -l; php -l bin/*; - continue-on-error: ${{matrix.php-versions == '8.0' }} # [temp-php8] - name: Run units tests with phpunit - run: vendor/bin/phpunit tests/Unit/ - continue-on-error: ${{matrix.php-versions == '8.0' }} # [temp-php8] + run: vendor/bin/phpunit tests/Unit/ - name: Run integration tests with phpunit - run: | + run: | export PHPLIST_DATABASE_NAME=${{ env.DB_DATABASE }} export PHPLIST_DATABASE_USER=${{ env.DB_USERNAME }} export PHPLIST_DATABASE_PASSWORD=${{ env.DB_PASSWORD }} export PHPLIST_DATABASE_PORT=${{ job.services.mysql.ports['3306'] }} export PHPLIST_DATABASE_HOST=127.0.0.1 vendor/bin/phpunit tests/Integration/ - continue-on-error: ${{matrix.php-versions == '8.0' }} # [temp-php8] - name: Running the system tests run: vendor/bin/phpunit tests/System/; - continue-on-error: ${{matrix.php-versions == '8.0' }} # [temp-php8] - name: Running static analysis run: vendor/bin/phpstan analyse -c phpstan.neon; - continue-on-error: ${{matrix.php-versions == '8.0' }} # [temp-php8] - name: Running PHPMD run: vendor/bin/phpmd src/ text config/PHPMD/rules.xml; - continue-on-error: ${{matrix.php-versions == '8.0' }} # [temp-php8] - name: Running PHP_CodeSniffer run: vendor/bin/phpcs --standard=config/PhpCodeSniffer/ bin/ src/ tests/ public/; - continue-on-error: ${{matrix.php-versions == '8.0' }} # [temp-php8] \ No newline at end of file diff --git a/.github/workflows/core-docs.yml b/.github/workflows/core-docs.yml index bbf31aed..a88fa4fe 100644 --- a/.github/workflows/core-docs.yml +++ b/.github/workflows/core-docs.yml @@ -1,4 +1,4 @@ -name: Publish Core Docs +name: Publish Core Docs on: [push, pull_request] jobs: make-restapi-docs: @@ -6,78 +6,84 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup PHP, with composer and extensions - uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php + uses: shivammathur/setup-php@v2 with: - php-version: 7.4 + php-version: 8.1 extensions: mbstring, dom, fileinfo, mysql - name: Get composer cache directory id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_ENV - name: Cache composer dependencies - uses: actions/cache@v2 + uses: actions/cache@v3 with: - path: ${{ steps.composer-cache.outputs.dir }} - # Use composer.json for key, if composer.lock is not committed. - # key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + path: ${{ env.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: ${{ runner.os }}-composer- - name: Install current dependencies from composer.lock run: composer install - - name: Install phpDocumentor + - name: Install phpDocumentor run: | wget https://phpdoc.org/phpDocumentor.phar chmod +x phpDocumentor.phar mv phpDocumentor.phar /usr/local/bin/phpDocumentor + - name: Verify phpDocumentor version + run: phpDocumentor --version - name: Generate documentation run: composer run-php-documentor - - name: zip phpdocumentor dir + - name: Zip phpDocumentor directory run: zip -r phpdocumentor.zip docs/phpdocumentor - name: Upload generated doc files - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: doc-files path: phpdocumentor.zip deploy-docs: - name: Deploy Core Docs. + name: Deploy Core Docs runs-on: ubuntu-20.04 needs: make-restapi-docs steps: - - name: Checkout phplist/core-docs - uses: actions/checkout@v2 - with: - repository: phpList/core-docs - fetch-depth: 0 - token: ${{ secrets.PUSH_CORE_DOCS }} - - name: Restore REST API Spec - uses: actions/download-artifact@v2 - with: - name: doc-files - - name: unzip phpdocumentor - run: | - unzip phpdocumentor.zip - rm phpdocumentor.zip - - name: List Files - run: ls - - name: Sync old files with newly generated ones. - run: rsync -av docs/phpdocumentor/* . - - name: Removed temp dirs - run: rm -rf docs - - name: Check if updates/changes. - run: git status --porcelain > repo-changes.txt - - name: Check changes file - run: cat repo-changes.txt - - name: Verify updates. - id: allow-deploy - run: | - if [ -s repo-changes.txt ]; then echo "Updates made to documentation"; echo '::set-output name=DEPLOY::true'; else echo "No updates made to documentation deployment would be skipped."; echo '::set-output name=DEPLOY::false'; fi - - name: Commit changes and deply - if: ${{ steps.allow-deploy.outputs.DEPLOY == 'true' }} - run: | - rm repo-changes.txt - git config user.name "github-actions" - git config user.email "github-actions@restapi-docs.workflow" - git add . - git commit -s -m "phplist/core docs deployment `date`" - git push \ No newline at end of file + - name: Checkout phplist/core-docs + uses: actions/checkout@v3 + with: + repository: phpList/core-docs + fetch-depth: 0 + token: ${{ secrets.PUSH_CORE_DOCS }} + - name: Restore REST API Spec + uses: actions/download-artifact@v4 + with: + name: doc-files + - name: Unzip phpDocumentor + run: | + unzip phpdocumentor.zip + rm phpdocumentor.zip + - name: List Files + run: ls + - name: Sync old files with newly generated ones + run: rsync -av docs/phpdocumentor/* . + - name: Remove temporary directories + run: rm -rf docs + - name: Check if updates/changes + run: git status --porcelain > repo-changes.txt + - name: Check changes file + run: cat repo-changes.txt + - name: Verify updates + id: allow-deploy + run: | + if [ -s repo-changes.txt ]; then + echo "Updates made to documentation"; + echo 'DEPLOY=true' >> $GITHUB_ENV; + else + echo "No updates made to documentation. Deployment would be skipped."; + echo 'DEPLOY=false' >> $GITHUB_ENV; + fi + - name: Commit changes and deploy + if: ${{ env.DEPLOY == 'true' }} + run: | + rm repo-changes.txt + git config user.name "github-actions" + git config user.email "github-actions@restapi-docs.workflow" + git add . + git commit -s -m "phplist/core docs deployment `date`" + git push origin main --force diff --git a/.gitignore b/.gitignore index 69fa774c..25db886b 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ /vendor/ /docs/phpdocumentor .vagrant -.phpdoc/ \ No newline at end of file +.phpdoc/ +.phpunit.result.cache diff --git a/bin/console b/bin/console index ef5b0cc9..ba36a420 100755 --- a/bin/console +++ b/bin/console @@ -7,7 +7,7 @@ use PhpList\Core\Core\Bootstrap; use PhpList\Core\Core\Environment; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\Debug\Debug; +use Symfony\Component\ErrorHandler\ErrorHandler; set_time_limit(0); @@ -19,7 +19,7 @@ $debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(['--no-d && $environment !== Environment::PRODUCTION; if ($debug) { - Debug::enable(); + ErrorHandler::register(); } Bootstrap::getInstance()->setEnvironment($environment)->configure(); diff --git a/composer.json b/composer.json index ff3f1748..bf931e41 100644 --- a/composer.json +++ b/composer.json @@ -34,35 +34,45 @@ "source": "https://github.com/phpList/core" }, "require": { - "php": "^7.2|^8.0", - "doctrine/orm": "^2.5.0", - "doctrine/common": "^2.6.0", - "doctrine/doctrine-bundle": "^1.8.0", - "symfony/symfony": "^3.4.37", - "symfony/monolog-bundle": "^3.1.0", - "symfony/dependency-injection": "^3.4.37", - "symfony/config": "^3.4.37", - "symfony/yaml": "^3.4.37", - "jms/serializer-bundle": "^3.8.0", - "sensio/framework-extra-bundle": "^5.1.0", - "sensio/distribution-bundle": "^5.0.6" + "php": "^8.1", + "symfony/dependency-injection": "^6.4", + "symfony/config": "^6.4", + "symfony/yaml": "^6.4", + "symfony/error-handler": "^6.4", + "symfony/serializer": "^6.4", + "symfony/monolog-bundle": "^3.10", + "symfony/serializer-pack": "^1.3", + "symfony/orm-pack": "^2.4", + "doctrine/orm": "^3.3", + "doctrine/cache": "^2.2", + "symfony/asset": "^6.4", + "symfony/security-csrf": "^6.4", + "symfony/form": "^6.4", + "symfony/validator": "^6.4", + "doctrine/doctrine-fixtures-bundle": "^3.7", + "doctrine/instantiator": "^2.0", + "masterminds/html5": "^2.9" }, "require-dev": { - "phpunit/phpunit": "^6.5.6", - "phpunit/phpunit-mock-objects": "^5.0.6", - "phpunit/dbunit": "^3.0.0", + "phpunit/phpunit": "^9.5", "guzzlehttp/guzzle": "^6.3.0", "squizlabs/php_codesniffer": "^3.2.0", - "phpstan/phpstan": "^0.7.0|0.12.57", - "nette/caching": "^2.5.0|^3.0.0", - "nikic/php-parser": "^3.1.0", + "phpstan/phpstan": "^1.10", + "nette/caching": "^3.0.0", + "nikic/php-parser": "^4.19.1", "phpmd/phpmd": "^2.6.0", - "composer/composer": "^1.6.0", - "doctrine/instantiator": "^1.0.5" + "symfony/test-pack": "^1.1", + "symfony/process": "^6.4", + "composer/composer": "^2.7", + "symfony/framework-bundle": "^6.4", + "symfony/http-kernel": "^6.4", + "symfony/http-foundation": "^6.4", + "symfony/routing": "^6.4", + "symfony/console": "^6.4" }, "suggest": { - "phplist/web-frontend": "4.0.x-dev", - "phplist/rest-api": "4.0.x-dev" + "phplist/web-frontend": "5.0.x-dev", + "phplist/rest-api": "5.0.x-dev" }, "autoload": { "psr-4": { @@ -83,7 +93,8 @@ "PhpList\\Core\\Composer\\ScriptHandler::createBundleConfiguration", "PhpList\\Core\\Composer\\ScriptHandler::createRoutesConfiguration", "PhpList\\Core\\Composer\\ScriptHandler::createParametersConfiguration", - "PhpList\\Core\\Composer\\ScriptHandler::clearAllCaches" + "php bin/console cache:clear", + "php bin/console cache:warmup" ], "post-install-cmd": [ "@update-configuration" @@ -97,7 +108,7 @@ }, "extra": { "branch-alias": { - "dev-master": "4.0.x-dev" + "dev-ISSUE-337": "5.0.x-dev" }, "symfony-app-dir": "", "symfony-bin-dir": "bin", @@ -107,16 +118,14 @@ "phplist/core": { "bundles": [ "Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle", - "Sensio\\Bundle\\FrameworkExtraBundle\\SensioFrameworkExtraBundle", "Symfony\\Bundle\\MonologBundle\\MonologBundle", - "JMS\\SerializerBundle\\JMSSerializerBundle", "Doctrine\\Bundle\\DoctrineBundle\\DoctrineBundle", - "PhpList\\Core\\EmptyStartPageBundle\\PhpListEmptyStartPageBundle" + "PhpList\\Core\\EmptyStartPageBundle\\EmptyStartPageBundle" ], "routes": { "homepage": { - "resource": "@PhpListEmptyStartPageBundle/Controller/", - "type": "annotation" + "resource": "@EmptyStartPageBundle/Controller/", + "type": "attribute" } } } diff --git a/config/config.yml b/config/config.yml index 0e8deaa5..7d4125b3 100644 --- a/config/config.yml +++ b/config/config.yml @@ -1,6 +1,7 @@ imports: - { resource: services.yml } - { resource: repositories.yml } + - { resource: doctrine.yml } # Put parameters here that don't need to change on each machine where the app is deployed # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration @@ -16,43 +17,26 @@ framework: strict_requirements: ~ form: ~ csrf_protection: ~ - validation: { enable_annotations: true } + validation: + enable_attributes: true + email_validation_mode: html5 #serializer: { enable_annotations: true } #templating: #engines: ['twig'] default_locale: '%locale%' trusted_hosts: ~ + handle_all_throwables: true session: # https://symfony.com/doc/current/reference/configuration/framework.html#handler-id handler_id: session.handler.native_file save_path: '%kernel.application_dir%/var/sessions/%kernel.environment%' + cookie_secure: auto + cookie_samesite: lax fragments: ~ http_method_override: true assets: ~ php_errors: log: true - -# Doctrine Configuration -doctrine: - dbal: - # These variables come from parameters.yml. There, the values are read from environment variables - # and can also be set directly in the parameters.yml file. - driver: '%database_driver%' - host: '%database_host%' - path: '%database_path%' - port: '%database_port%' - dbname: '%database_name%' - user: '%database_user%' - password: '%database_password%' - charset: UTF8 - - orm: - auto_generate_proxy_classes: '%kernel.debug%' - naming_strategy: doctrine.orm.naming_strategy.underscore - auto_mapping: true - mappings: - PhpList\Core\Domain\Model: - type: annotation - is_bundle: false - prefix: PhpList\Core\Domain\Model - dir: '%kernel.project_dir%/src/Domain/Model/' + serializer: + enabled: true + enable_attributes: true diff --git a/config/config_dev.yml b/config/config_dev.yml index 0e0dd414..2b30e97b 100644 --- a/config/config_dev.yml +++ b/config/config_dev.yml @@ -20,10 +20,10 @@ monolog: channels: ['!event', '!doctrine', '!console'] # To follow logs in real time, execute the following command: # `bin/console server:log -vv` - server_log: - type: server_log - process_psr_3_messages: false - host: 127.0.0.1:9911 +# server_log: +# type: server_log +# process_psr_3_messages: false +# host: 127.0.0.1:9911 # uncomment to get logging in your browser # you may have to allow bigger header sizes in your Web server configuration #firephp: diff --git a/config/config_test.yml b/config/config_test.yml index ec3dfbe5..17063377 100644 --- a/config/config_test.yml +++ b/config/config_test.yml @@ -4,6 +4,17 @@ imports: framework: test: ~ session: - storage_id: session.storage.mock_file + cookie_domain: session.storage.mock_file + handler_id: null profiler: collect: false + +doctrine: + dbal: + driver: 'pdo_sqlite' + memory: true + charset: UTF8 +# orm: +# entity_managers: +# default: +# report_fields_where_declared: true diff --git a/config/doctrine.yml b/config/doctrine.yml new file mode 100644 index 00000000..10f7e1c0 --- /dev/null +++ b/config/doctrine.yml @@ -0,0 +1,26 @@ +# Doctrine Configuration +doctrine: + dbal: + # These variables come from parameters.yml. There, the values are read from environment variables + # and can also be set directly in the parameters.yml file. + driver: '%database_driver%' + host: '%database_host%' + path: '%database_path%' + port: '%database_port%' + dbname: '%database_name%' + user: '%database_user%' + password: '%database_password%' + charset: UTF8 + + orm: + auto_generate_proxy_classes: '%kernel.debug%' + naming_strategy: doctrine.orm.naming_strategy.underscore + auto_mapping: true + mappings: + PhpList\Core\Domain\Model: + is_bundle: false + type: attribute + dir: '%kernel.project_dir%/src/Domain/Model/' + prefix: 'PhpList\Core\Domain\Model\' + controller_resolver: + auto_mapping: false diff --git a/config/parameters.yml.dist b/config/parameters.yml.dist index 346787c9..00ce9a48 100644 --- a/config/parameters.yml.dist +++ b/config/parameters.yml.dist @@ -14,13 +14,13 @@ parameters: database_host: '%%env(PHPLIST_DATABASE_HOST)%%' env(PHPLIST_DATABASE_HOST): '127.0.0.1' database_port: '%%env(PHPLIST_DATABASE_PORT)%%' - env(PHPLIST_DATABASE_PORT): null + env(PHPLIST_DATABASE_PORT): '3306' database_name: '%%env(PHPLIST_DATABASE_NAME)%%' - env(PHPLIST_DATABASE_NAME): 'phplist' + env(PHPLIST_DATABASE_NAME): 'phplistdb' database_user: '%%env(PHPLIST_DATABASE_USER)%%' - env(PHPLIST_DATABASE_USER): 'foo' + env(PHPLIST_DATABASE_USER): 'phplist' database_password: '%%env(PHPLIST_DATABASE_PASSWORD)%%' - env(PHPLIST_DATABASE_PASSWORD): 'correct horse battery staple' + env(PHPLIST_DATABASE_PASSWORD): 'phplist' # A secret key that's used to generate certain security-related tokens secret: '%%env(PHPLIST_SECRET)%%' diff --git a/config/repositories.yml b/config/repositories.yml index b1f3e978..47cdbd07 100644 --- a/config/repositories.yml +++ b/config/repositories.yml @@ -3,6 +3,8 @@ services: parent: PhpList\Core\Domain\Repository arguments: - PhpList\Core\Domain\Model\Identity\Administrator + - Doctrine\ORM\Mapping\ClassMetadata\ClassMetadata + - PhpList\Core\Security\HashGenerator PhpList\Core\Domain\Repository\Identity\AdministratorTokenRepository: parent: PhpList\Core\Domain\Repository diff --git a/config/services.yml b/config/services.yml index 09ef0d7c..d7982241 100644 --- a/config/services.yml +++ b/config/services.yml @@ -26,7 +26,7 @@ services: autowire: true autoconfigure: false public: true - factory: Doctrine\ORM\EntityManagerInterface:getRepository + factory: ['@doctrine.orm.entity_manager', getRepository] # controllers are imported separately to make sure they're public # and have a tag that allows actions to type-hint services @@ -34,3 +34,16 @@ services: resource: '../src/EmptyStartPageBundle/Controller' public: true tags: [controller.service_arguments] + + doctrine.orm.metadata.annotation_reader: + alias: doctrine.annotation_reader + + doctrine.annotation_reader: + class: Doctrine\Common\Annotations\AnnotationReader + autowire: true + + doctrine.orm.default_annotation_metadata_driver: + class: Doctrine\ORM\Mapping\Driver\AnnotationDriver + arguments: + - '@annotation_reader' + - '%kernel.project_dir%/src/Domain/Model/' diff --git a/phpdoc.xml b/phpdoc.xml index 2961910b..dc68e8c1 100644 --- a/phpdoc.xml +++ b/phpdoc.xml @@ -9,4 +9,4 @@ docs/phpdocumentor - \ No newline at end of file + diff --git a/phpstan.neon b/phpstan.neon index d85773de..3a51f9ec 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -5,6 +5,3 @@ parameters: - src - tests - public - ignoreErrors: - - '#Cannot call method (?:willReturn|shouldBeCalledOnce|shouldNotBeCalled|shouldBeCalled|shouldNotHaveBeenCalled)\(\) on .*\.#' - - '#Call to an undefined method [a-zA-Z0-9\\_]+::willReturn\(\)#' \ No newline at end of file diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 78ea4f9a..12e03eee 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -2,7 +2,7 @@ packageRepository = $repository; } @@ -38,7 +40,7 @@ public function injectPackageRepository(PackageRepository $repository) * @return string[][] class names of the bundles of all installed phpList modules: * ['module package name' => ['bundle class name 1', 'bundle class name 2']] * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public function findBundleClasses(): array { @@ -66,9 +68,9 @@ public function findBundleClasses(): array * * @return void * - * @throws \InvalidArgumentException if $extra has an invalid bundles configuration + * @throws InvalidArgumentException if $extra has an invalid bundles configuration */ - private function validateBundlesSectionInExtra(array $extra) + private function validateBundlesSectionInExtra(array $extra): void { if (!isset($extra['phplist/core'])) { return; @@ -79,7 +81,7 @@ private function validateBundlesSectionInExtra(array $extra) return; } if (!is_array($extra['phplist/core']['bundles'])) { - throw new \InvalidArgumentException( + throw new InvalidArgumentException( 'The extras.phplist/core.bundles section in the composer.json must be an array.', 1505411665 ); @@ -89,7 +91,7 @@ private function validateBundlesSectionInExtra(array $extra) $bundleExtras = $extra['phplist/core']['bundles']; foreach ($bundleExtras as $key => $bundleName) { if (!is_string($bundleName)) { - throw new \InvalidArgumentException( + throw new InvalidArgumentException( 'The extras.phplist/core.bundles. ' . $key . '" section in the composer.json must be a string.', 1505412184 ); @@ -104,12 +106,12 @@ private function validateBundlesSectionInExtra(array $extra) * * @return void * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ - private function validatePhpListSectionInExtra(array $extra) + private function validatePhpListSectionInExtra(array $extra): void { if (!is_array($extra['phplist/core'])) { - throw new \InvalidArgumentException( + throw new InvalidArgumentException( 'The extras.phplist/core" section in the composer.json must be an array.', 1505411436 ); @@ -125,7 +127,7 @@ private function validatePhpListSectionInExtra(array $extra) */ public function createBundleConfigurationYaml(): string { - return static::YAML_COMMENT . "\n" . Yaml::dump($this->findBundleClasses()); + return static::YAML_COMMENT . PHP_EOL . Yaml::dump($this->findBundleClasses()); } /** @@ -134,7 +136,7 @@ public function createBundleConfigurationYaml(): string * @return array[] class names of the routes of all installed phpList modules: * ['route name' => [route configuration] * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public function findRoutes(): array { @@ -167,9 +169,9 @@ public function findRoutes(): array * * @return void * - * @throws \InvalidArgumentException if $extra has an invalid routes configuration + * @throws InvalidArgumentException if $extra has an invalid routes configuration */ - private function validateRoutesSectionInExtra(array $extra) + private function validateRoutesSectionInExtra(array $extra): void { if (!isset($extra['phplist/core'])) { return; @@ -180,7 +182,7 @@ private function validateRoutesSectionInExtra(array $extra) return; } if (!is_array($extra['phplist/core']['routes'])) { - throw new \InvalidArgumentException( + throw new InvalidArgumentException( 'The extras.phplist/core.routes section in the composer.json must be an array.', 1506429004 ); @@ -190,7 +192,7 @@ private function validateRoutesSectionInExtra(array $extra) $bundleExtras = $extra['phplist/core']['routes']; foreach ($bundleExtras as $routeName => $routeConfiguration) { if (!is_array($routeConfiguration)) { - throw new \InvalidArgumentException( + throw new InvalidArgumentException( 'The extras.phplist/core.routes. ' . $routeName . '" section in the composer.json must be an array.', 1506429860 @@ -208,7 +210,7 @@ private function validateRoutesSectionInExtra(array $extra) */ public function createRouteConfigurationYaml(): string { - return static::YAML_COMMENT . "\n" . Yaml::dump($this->findRoutes()); + return static::YAML_COMMENT . PHP_EOL . Yaml::dump($this->findRoutes()); } /** @@ -216,7 +218,7 @@ public function createRouteConfigurationYaml(): string * * @return array configuration which can be dumped in a config_modules.yml file * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ public function findGeneralConfiguration(): array { @@ -244,9 +246,9 @@ public function findGeneralConfiguration(): array * * @return void * - * @throws \InvalidArgumentException if $extra has an invalid routes configuration + * @throws InvalidArgumentException if $extra has an invalid routes configuration */ - private function validateGeneralConfigurationSectionInExtra(array $extra) + private function validateGeneralConfigurationSectionInExtra(array $extra): void { if (!isset($extra['phplist/core'])) { return; @@ -257,7 +259,7 @@ private function validateGeneralConfigurationSectionInExtra(array $extra) return; } if (!is_array($extra['phplist/core']['configuration'])) { - throw new \InvalidArgumentException( + throw new InvalidArgumentException( 'The extras.phplist/core.configuration section in the composer.json must be an array.', 1508165934 ); @@ -273,6 +275,6 @@ private function validateGeneralConfigurationSectionInExtra(array $extra) */ public function createGeneralConfigurationYaml(): string { - return static::YAML_COMMENT . "\n" . Yaml::dump($this->findGeneralConfiguration()); + return static::YAML_COMMENT . PHP_EOL . Yaml::dump($this->findGeneralConfiguration()); } } diff --git a/src/Composer/PackageRepository.php b/src/Composer/PackageRepository.php index d2bd3312..a693ed90 100644 --- a/src/Composer/PackageRepository.php +++ b/src/Composer/PackageRepository.php @@ -58,7 +58,7 @@ private function removeDuplicates(array $packages): array /** @var bool[] $registeredPackages */ $registeredPackages = []; - $result = array_filter( + return array_filter( $packages, function (PackageInterface $package) use (&$registeredPackages) { $packageName = $package->getName(); @@ -70,8 +70,6 @@ function (PackageInterface $package) use (&$registeredPackages) { return true; } ); - - return $result; } /** diff --git a/src/Composer/ScriptHandler.php b/src/Composer/ScriptHandler.php index ac8d2587..55e23739 100644 --- a/src/Composer/ScriptHandler.php +++ b/src/Composer/ScriptHandler.php @@ -1,12 +1,14 @@ */ -class ScriptHandler extends SensioScriptHandler +class ScriptHandler { /** * @var string @@ -49,7 +51,7 @@ class ScriptHandler extends SensioScriptHandler /** * @return string absolute application root directory without the trailing slash * - * @throws \RuntimeException if there is no composer.json in the application root + * @throws RuntimeException if there is no composer.json in the application root */ private static function getApplicationRoot(): string { @@ -62,7 +64,7 @@ private static function getApplicationRoot(): string */ private static function getCoreDirectory(): string { - return static::getApplicationRoot() . '/vendor/' . static::CORE_PACKAGE_NAME; + return self::getApplicationRoot() . '/vendor/' . static::CORE_PACKAGE_NAME; } /** @@ -74,12 +76,12 @@ private static function getCoreDirectory(): string * * @return void * - * @throws \DomainException if this method is called for the core package + * @throws DomainException if this method is called for the core package */ - public static function createBinaries(Event $event) + public static function createBinaries(Event $event): void { - static::preventScriptFromCorePackage($event); - static::mirrorDirectoryFromCore('bin'); + self::preventScriptFromCorePackage($event); + self::mirrorDirectoryFromCore('bin'); } /** @@ -91,12 +93,12 @@ public static function createBinaries(Event $event) * * @return void * - * @throws \DomainException if this method is called for the core package + * @throws DomainException if this method is called for the core package */ - public static function createPublicWebDirectory(Event $event) + public static function createPublicWebDirectory(Event $event): void { - static::preventScriptFromCorePackage($event); - static::mirrorDirectoryFromCore('public'); + self::preventScriptFromCorePackage($event); + self::mirrorDirectoryFromCore('public'); } /** @@ -104,14 +106,14 @@ public static function createPublicWebDirectory(Event $event) * * @return void * - * @throws \DomainException if this method is called for the core package + * @throws DomainException if this method is called for the core package */ - private static function preventScriptFromCorePackage(Event $event) + private static function preventScriptFromCorePackage(Event $event): void { $composer = $event->getComposer(); $packageName = $composer->getPackage()->getName(); - if ($packageName === static::CORE_PACKAGE_NAME) { - throw new \DomainException( + if ($packageName === self::CORE_PACKAGE_NAME) { + throw new DomainException( 'This Composer script must not be called for the core package itself.', 1501240572 ); @@ -129,14 +131,14 @@ private static function preventScriptFromCorePackage(Event $event) * * @return void */ - private static function mirrorDirectoryFromCore(string $directoryWithoutSlashes) + private static function mirrorDirectoryFromCore(string $directoryWithoutSlashes): void { $directoryWithSlashes = '/' . $directoryWithoutSlashes . '/'; $fileSystem = new Filesystem(); $fileSystem->mirror( - static::getCoreDirectory() . $directoryWithSlashes, - static::getApplicationRoot() . $directoryWithSlashes, + self::getCoreDirectory() . $directoryWithSlashes, + self::getApplicationRoot() . $directoryWithSlashes, null, ['override' => true, 'delete' => false] ); @@ -149,13 +151,13 @@ private static function mirrorDirectoryFromCore(string $directoryWithoutSlashes) * * @return void */ - public static function listModules(Event $event) + public static function listModules(Event $event): void { $packageRepository = new PackageRepository(); $packageRepository->injectComposer($event->getComposer()); $modules = $packageRepository->findModules(); - $maximumPackageNameLength = static::calculateMaximumPackageNameLength($modules); + $maximumPackageNameLength = self::calculateMaximumPackageNameLength($modules); foreach ($modules as $module) { $paddedName = str_pad($module->getName(), $maximumPackageNameLength + 1); @@ -186,11 +188,11 @@ private static function calculateMaximumPackageNameLength(array $modules): int * * @return void */ - public static function createBundleConfiguration(Event $event) + public static function createBundleConfiguration(Event $event): void { - static::createAndWriteFile( - static::getApplicationRoot() . static::BUNDLE_CONFIGURATION_FILE, - static::createAndInitializeModuleFinder($event)->createBundleConfigurationYaml() + self::createAndWriteFile( + self::getApplicationRoot() . self::BUNDLE_CONFIGURATION_FILE, + self::createAndInitializeModuleFinder($event)->createBundleConfigurationYaml() ); } @@ -206,13 +208,13 @@ public static function createBundleConfiguration(Event $event) * * @return void * - * @throws \RuntimeException + * @throws RuntimeException */ - private static function createAndWriteFile(string $path, string $contents) + private static function createAndWriteFile(string $path, string $contents): void { $fileHandle = fopen($path, 'wb'); if ($fileHandle === false) { - throw new \RuntimeException('The file "' . $path . '" could not be opened for writing.', 1519851153); + throw new RuntimeException('The file "' . $path . '" could not be opened for writing.', 1519851153); } fwrite($fileHandle, $contents); @@ -227,11 +229,11 @@ private static function createAndWriteFile(string $path, string $contents) * * @return void */ - public static function createRoutesConfiguration(Event $event) + public static function createRoutesConfiguration(Event $event): void { - static::createAndWriteFile( - static::getApplicationRoot() . static::ROUTES_CONFIGURATION_FILE, - static::createAndInitializeModuleFinder($event)->createRouteConfigurationYaml() + self::createAndWriteFile( + self::getApplicationRoot() . self::ROUTES_CONFIGURATION_FILE, + self::createAndInitializeModuleFinder($event)->createRouteConfigurationYaml() ); } @@ -256,27 +258,10 @@ private static function createAndInitializeModuleFinder(Event $event): ModuleFin * * @return void */ - public static function clearAllCaches() + public static function clearAllCaches():void { $fileSystem = new Filesystem(); - $fileSystem->remove(static::getApplicationRoot() . '/var/cache'); - } - - /** - * Warms the production cache. - * - * @param Event $event - * - * @return void - */ - public static function warmProductionCache(Event $event) - { - $consoleDir = static::getConsoleDir($event, 'warm the cache'); - if ($consoleDir === null) { - return; - } - - static::executeCommand($event, $consoleDir, 'cache:warm -e prod'); + $fileSystem->remove(self::getApplicationRoot() . '/var/cache'); } /** @@ -284,9 +269,9 @@ public static function warmProductionCache(Event $event) * * @return void */ - public static function createParametersConfiguration() + public static function createParametersConfiguration(): void { - $configurationFilePath = static::getApplicationRoot() . static::PARAMETERS_CONFIGURATION_FILE; + $configurationFilePath = self::getApplicationRoot() . self::PARAMETERS_CONFIGURATION_FILE; if (file_exists($configurationFilePath)) { return; } @@ -297,7 +282,7 @@ public static function createParametersConfiguration() $secret = bin2hex(random_bytes(20)); $configuration = sprintf($template, $secret); - static::createAndWriteFile($configurationFilePath, $configuration); + self::createAndWriteFile($configurationFilePath, $configuration); } /** @@ -307,11 +292,11 @@ public static function createParametersConfiguration() * * @return void */ - public static function createGeneralConfiguration(Event $event) + public static function createGeneralConfiguration(Event $event): void { - static::createAndWriteFile( - static::getApplicationRoot() . static::GENERAL_CONFIGURATION_FILE, - static::createAndInitializeModuleFinder($event)->createGeneralConfigurationYaml() + self::createAndWriteFile( + self::getApplicationRoot() . self::GENERAL_CONFIGURATION_FILE, + self::createAndInitializeModuleFinder($event)->createGeneralConfigurationYaml() ); } } diff --git a/src/Core/ApplicationKernel.php b/src/Core/ApplicationKernel.php index 70995c3f..695520a1 100644 --- a/src/Core/ApplicationKernel.php +++ b/src/Core/ApplicationKernel.php @@ -1,9 +1,11 @@ bundlesFromConfiguration(); - if ($this->shouldHaveDevelopmentBundles()) { - $bundles[] = new WebServerBundle(); - } - - return $bundles; + return $this->bundlesFromConfiguration(); } /** @@ -41,7 +38,7 @@ public function registerBundles(): array * * @return string absolute path without the trailing slash */ - public function getProjectDir() + public function getProjectDir(): string { return $this->getAndCreateApplicationStructure()->getCorePackageRoot(); } @@ -49,7 +46,7 @@ public function getProjectDir() /** * @return string */ - public function getRootDir() + public function getRootDir(): string { return $this->getProjectDir(); } @@ -73,7 +70,7 @@ private function getApplicationDir(): string /** * @return string */ - public function getCacheDir() + public function getCacheDir(): string { return $this->getApplicationDir() . '/var/cache/' . $this->getEnvironment(); } @@ -81,7 +78,7 @@ public function getCacheDir() /** * @return string */ - public function getLogDir() + public function getLogDir(): string { return $this->getApplicationDir() . '/var/logs'; } @@ -105,7 +102,7 @@ private function getAndCreateApplicationStructure(): ApplicationStructure * * @return void */ - protected function build(ContainerBuilder $container) + protected function build(ContainerBuilder $container): void { $container->setParameter('kernel.application_dir', $this->getApplicationDir()); } @@ -117,23 +114,15 @@ protected function build(ContainerBuilder $container) * * @return void * - * @throws \Exception + * @throws Exception */ - public function registerContainerConfiguration(LoaderInterface $loader) + public function registerContainerConfiguration(LoaderInterface $loader): void { $loader->load($this->getApplicationDir() . '/config/parameters.yml'); $loader->load($this->getRootDir() . '/config/config_' . $this->getEnvironment() . '.yml'); $loader->load($this->getApplicationDir() . '/config/config_modules.yml'); } - /** - * @return bool - */ - private function shouldHaveDevelopmentBundles(): bool - { - return $this->environment !== Environment::PRODUCTION; - } - /** * Reads the bundles from the bundle configuration file and instantiates them. * @@ -143,7 +132,6 @@ private function bundlesFromConfiguration(): array { $bundles = []; - /** @var string[] $packageBundles */ foreach ($this->readBundleConfiguration() as $packageBundles) { foreach ($packageBundles as $bundleClassName) { if (class_exists($bundleClassName)) { @@ -162,13 +150,13 @@ private function bundlesFromConfiguration(): array * * @return string[][] * - * @throws \RuntimeException if the configuration file cannot be read + * @throws RuntimeException if the configuration file cannot be read */ private function readBundleConfiguration(): array { $configurationFilePath = $this->getApplicationDir() . '/config/bundles.yml'; if (!is_readable($configurationFilePath)) { - throw new \RuntimeException('The file "' . $configurationFilePath . '" could not be read.', 1504272377); + throw new RuntimeException('The file "' . $configurationFilePath . '" could not be read.', 1504272377); } return Yaml::parse(file_get_contents($configurationFilePath)); diff --git a/src/Core/ApplicationStructure.php b/src/Core/ApplicationStructure.php index 1b60a74f..736bdf3b 100644 --- a/src/Core/ApplicationStructure.php +++ b/src/Core/ApplicationStructure.php @@ -1,8 +1,11 @@ applicationStructure = new ApplicationStructure(); + $this->errorHandler = new ErrorHandler(); } /** @@ -88,7 +75,7 @@ public static function getInstance(): Bootstrap * * @return void */ - public static function purgeInstance() + public static function purgeInstance(): void { self::$instance = null; } @@ -98,7 +85,7 @@ public static function purgeInstance() * * @return Bootstrap fluent interface * - * @throws \UnexpectedValueException + * @throws UnexpectedValueException */ public function setEnvironment(string $environment): Bootstrap { @@ -108,25 +95,16 @@ public function setEnvironment(string $environment): Bootstrap return $this; } - /** - * @return string - */ public function getEnvironment(): string { return $this->environment; } - /** - * @return bool - */ private function isSymfonyDebugModeEnabled(): bool { return $this->environment !== Environment::PRODUCTION; } - /** - * @return bool - */ private function isDebugEnabled(): bool { return $this->environment !== Environment::PRODUCTION; @@ -140,11 +118,14 @@ private function isDebugEnabled(): bool * @SuppressWarnings("PHPMD.ExitExpression") * @SuppressWarnings("PHPMD.Superglobals") * - * @return Bootstrap|null fluent interface + * @return Bootstrap fluent interface */ - public function ensureDevelopmentOrTestingEnvironment() + public function ensureDevelopmentOrTestingEnvironment(): self { - $usesProxy = isset($_SERVER['HTTP_CLIENT_IP']) || isset($_SERVER['HTTP_X_FORWARDED_FOR']); + if (isset($_ENV['APP_ENV']) && $_ENV['APP_ENV'] === Environment::TESTING) { + return $this; + } + $usesProxy = isset($_SERVER['HTTP_CLIENT_IP']); $isOnCli = PHP_SAPI === 'cli' || PHP_SAPI === 'cli-server'; $isLocalRequest = isset($_SERVER['REMOTE_ADDR']) && in_array($_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1'], true); @@ -175,12 +156,12 @@ public function configure(): Bootstrap * * @return void * - * @throws \RuntimeException if configure has not been called before + * @throws RuntimeException if configure has not been called before */ - private function assertConfigureHasBeenCalled() + private function assertConfigureHasBeenCalled(): void { if (!$this->isConfigured) { - throw new \RuntimeException('Please call configure() first.', 1501170550); + throw new RuntimeException('Please call configure() first.', 1501170550); } } @@ -191,8 +172,8 @@ private function assertConfigureHasBeenCalled() * * @return null * - * @throws \RuntimeException if configure has not been called before - * @throws \Exception + * @throws RuntimeException if configure has not been called before + * @throws Exception */ public function dispatch() { @@ -212,7 +193,7 @@ public function dispatch() private function configureDebugging(): Bootstrap { if ($this->isDebugEnabled()) { - Debug::enable(); + $this->errorHandler->register(); } return $this; @@ -234,7 +215,7 @@ private function configureApplicationKernel(): Bootstrap /** * @return ApplicationKernel * - * @throws \RuntimeException if configure has not been called before + * @throws RuntimeException if configure has not been called before */ public function getApplicationKernel(): ApplicationKernel { @@ -258,7 +239,7 @@ public function getContainer(): ContainerInterface /** * @return EntityManagerInterface * - * @throws \RuntimeException if configure has not been called before + * @throws RuntimeException if configure has not been called before */ public function getEntityManager(): EntityManagerInterface { @@ -278,7 +259,7 @@ public function getEntityManager(): EntityManagerInterface * * @return string the absolute path without the trailing slash. * - * @throws \RuntimeException if there is no composer.json in the application root + * @throws RuntimeException if there is no composer.json in the application root */ public function getApplicationRoot(): string { diff --git a/src/Core/Environment.php b/src/Core/Environment.php index 3bafe2e0..7582689a 100644 --- a/src/Core/Environment.php +++ b/src/Core/Environment.php @@ -1,8 +1,11 @@ */ +#[ORM\Entity(repositoryClass: 'PhpList\Core\Domain\Repository\Identity\AdministratorRepository')] +#[ORM\Table(name: 'phplist_admin')] +#[ORM\HasLifecycleCallbacks] class Administrator implements DomainModel, Identity, CreationDate, ModificationDate { use IdentityTrait; use CreationDateTrait; use ModificationDateTrait; - /** - * @var string - * @Column(name="loginname") - */ - private $loginName = ''; + #[ORM\Column(name: 'loginname')] + private string $loginName; - /** - * @var string - * @Column(name="email") - */ - private $emailAddress = ''; + #[ORM\Column(name: 'email')] + private string $emailAddress; - /** - * @var \DateTime|null - * @Column(type="datetime", name="created") - */ - protected $creationDate = null; + #[ORM\Column(name: 'created', type: 'datetime')] + protected ?DateTime $creationDate = null; - /** - * @var \DateTime|null - * @Column(type="datetime", name="modified") - */ - protected $modificationDate = null; + #[ORM\Column(name: 'modified', type: 'datetime')] + protected ?DateTime $modificationDate; - /** - * @var string - * @Column(name="password") - */ - private $passwordHash = ''; + #[ORM\Column(name: 'password')] + private string $passwordHash; - /** - * @var \DateTime|null - * @Column(type="date", nullable=true, name="passwordchanged") - */ - private $passwordChangeDate = null; + #[ORM\Column(name: 'passwordchanged', type: 'date', nullable: true)] + private ?DateTime $passwordChangeDate; - /** - * @var bool - * @Column(type="boolean") - */ - private $disabled = false; + #[ORM\Column(type: 'boolean')] + private bool $disabled; - /** - * @var bool - * @Column(type="boolean", name="superuser") - */ - private $superUser = false; + #[ORM\Column(name: 'superuser', type: 'boolean')] + private bool $superUser; + + public function __construct() + { + $this->disabled = false; + $this->superUser = false; + $this->passwordChangeDate = null; + $this->loginName = ''; + $this->passwordHash = ''; + $this->modificationDate = null; + $this->emailAddress = ''; + } - /** - * @return string - */ public function getLoginName(): string { return $this->loginName; } - /** - * @param string $loginName - * - * @return void - */ - public function setLoginName(string $loginName) + public function setLoginName(string $loginName): void { $this->loginName = $loginName; } - /** - * @return string - */ public function getEmailAddress(): string { return $this->emailAddress; } - /** - * @param string $emailAddress - * - * @return void - */ - public function setEmailAddress(string $emailAddress) + public function setEmailAddress(string $emailAddress): void { $this->emailAddress = $emailAddress; } - /** - * @return string - */ public function getPasswordHash(): string { return $this->passwordHash; @@ -123,67 +91,39 @@ public function getPasswordHash(): string /** * Sets the password hash and updates the password change date to now. - * - * @param string $passwordHash - * - * @return void */ - public function setPasswordHash(string $passwordHash) + public function setPasswordHash(string $passwordHash): void { $this->passwordHash = $passwordHash; - $this->setPasswordChangeDate(new \DateTime()); + $this->setPasswordChangeDate(new DateTime()); } - /** - * @return \DateTime|null - */ - public function getPasswordChangeDate() + public function getPasswordChangeDate(): ?DateTime { return $this->passwordChangeDate; } - /** - * @param \DateTime $changeDate - * - * @return void - */ - private function setPasswordChangeDate(\DateTime $changeDate) + private function setPasswordChangeDate(DateTime $changeDate): void { $this->passwordChangeDate = $changeDate; } - /** - * @return bool - */ public function isDisabled(): bool { return $this->disabled; } - /** - * @param bool $disabled - * - * @return void - */ - public function setDisabled(bool $disabled) + public function setDisabled(bool $disabled): void { $this->disabled = $disabled; } - /** - * @return bool - */ public function isSuperUser(): bool { return $this->superUser; } - /** - * @param bool $superUser - * - * @return void - */ - public function setSuperUser(bool $superUser) + public function setSuperUser(bool $superUser): void { $this->superUser = $superUser; } diff --git a/src/Domain/Model/Identity/AdministratorToken.php b/src/Domain/Model/Identity/AdministratorToken.php index 5e536adc..7f4b1655 100644 --- a/src/Domain/Model/Identity/AdministratorToken.php +++ b/src/Domain/Model/Identity/AdministratorToken.php @@ -1,13 +1,15 @@ */ +#[ORM\Entity(repositoryClass: 'PhpList\Core\Domain\Repository\Identity\AdministratorTokenRepository')] +#[ORM\Table(name: 'phplist_admintoken')] +#[ORM\HasLifecycleCallbacks] class AdministratorToken implements DomainModel, Identity, CreationDate { use IdentityTrait; - /** - * @var string - */ - const DEFAULT_EXPIRY = '+1 hour'; - - /** - * @var int - * @Column(type="integer", name="entered") - */ - protected $creationDate = 0; - - /** - * @var \DateTime - * @Column(type="datetime", name="expires") - * @Expose - */ - private $expiry = null; - - /** - * @var string - * @Column(name="value") - * @Expose - */ - private $key = ''; - - /** - * @var Administrator|Proxy - * @Mapping\ManyToOne(targetEntity="PhpList\Core\Domain\Model\Identity\Administrator") - * @Mapping\JoinColumn(name="adminid") - */ - private $administrator = null; - - /** - * The Constructor. - */ + public const DEFAULT_EXPIRY = '+1 hour'; + + #[ORM\Column(name: 'entered', type: 'integer')] + #[Ignore] + protected int $creationDate = 0; + + #[ORM\Column(name: 'expires', type: 'datetime')] + #[SerializedName('expiry_date')] + private ?DateTime $expiry = null; + + #[ORM\Column(name: 'value')] + #[SerializedName('key')] + private string $key = ''; + + #[ORM\ManyToOne(targetEntity: 'PhpList\Core\Domain\Model\Identity\Administrator')] + #[ORM\JoinColumn(name: 'adminid')] + #[Ignore] + private ?Administrator $administrator = null; + public function __construct() { - $this->setExpiry(new \DateTime()); + $this->setExpiry(new DateTime()); } - /** - * @return \DateTime|null - */ - public function getCreationDate() + public function getCreationDate(): ?DateTime { if ($this->creationDate === 0) { return null; } - $date = new \DateTime(); + $date = new DateTime(); $date->setTimestamp($this->creationDate); - $date->setTimezone(new \DateTimeZone('UTC')); + $date->setTimezone(new DateTimeZone('UTC')); return $date; } - /** - * @param \DateTime $creationDate - * - * @return void - */ - private function setCreationDate(\DateTime $creationDate) + private function setCreationDate(DateTime $creationDate): void { $this->creationDate = $creationDate->getTimestamp(); } - /** - * Updates the creation date to now. - * - * @Mapping\PrePersist - * - * @return void - */ - public function updateCreationDate() + #[ORM\PrePersist] + public function updateCreationDate(): void { - $this->setCreationDate(new \DateTime()); + $this->setCreationDate(new DateTime()); } - /** - * @return \DateTime - */ - public function getExpiry(): \DateTime + public function getExpiry(): DateTime { return $this->expiry; } - /** - * @param \DateTime $expiry - * - * @return void - */ - private function setExpiry(\DateTime $expiry) + private function setExpiry(DateTime $expiry): void { $this->expiry = $expiry; } - /** - * Generates and sets an expiry one hour in the future. - * - * @return void - */ - public function generateExpiry() + public function generateExpiry(): void { - $this->setExpiry(new \DateTime(static::DEFAULT_EXPIRY)); + $this->setExpiry(new DateTime(static::DEFAULT_EXPIRY)); } - /** - * @return string - */ public function getKey(): string { return $this->key; } - /** - * @param string $key - * - * @return void - */ - public function setKey(string $key) + public function setKey(string $key): void { $this->key = $key; } - /** - * Generates a new, random key. - * - * @return void - */ - public function generateKey() + public function generateKey(): void { $key = md5(random_bytes(256)); $this->setKey($key); } - /** - * @return Administrator|Proxy|null - */ - public function getAdministrator() + public function getAdministrator(): Administrator|Proxy|null { return $this->administrator; } - /** - * @param Administrator $administrator - * - * @return void - */ - public function setAdministrator(Administrator $administrator) + public function setAdministrator(Administrator $administrator): void { $this->administrator = $administrator; } diff --git a/src/Domain/Model/Interfaces/CreationDate.php b/src/Domain/Model/Interfaces/CreationDate.php index cefbb1a5..41a6f9ad 100644 --- a/src/Domain/Model/Interfaces/CreationDate.php +++ b/src/Domain/Model/Interfaces/CreationDate.php @@ -1,8 +1,10 @@ */ +#[ORM\Entity(repositoryClass: 'PhpList\Core\Domain\Repository\Messaging\SubscriberListRepository')] +#[ORM\Table(name: 'phplist_list')] +#[ORM\Index(name: 'nameidx', columns: ['name'])] +#[ORM\Index(name: 'listorderidx', columns: ['listorder'])] +#[ORM\HasLifecycleCallbacks] class SubscriberList implements DomainModel, Identity, CreationDate, ModificationDate { use IdentityTrait; use CreationDateTrait; use ModificationDateTrait; - /** - * @var string - * @Column - * @Expose - */ - private $name = ''; - - /** - * @var string - * @Column - * @Expose - */ - private $description = ''; - - /** - * @var \DateTime|null - * @Column(type="datetime", nullable=true, name="entered") - * @Expose - */ - protected $creationDate = null; - - /** - * @var \DateTime|null - * @Column(type="datetime", name="modified") - */ - protected $modificationDate = null; - - /** - * @var int - * @Column(type="integer", name="listorder") - * @Expose - */ - private $listPosition = 0; - - /** - * @var string - * @Column(name="prefix") - * @Expose - */ - private $subjectPrefix = ''; - - /** - * @var bool - * @Column(type="boolean", name="active") - * @Expose - */ - private $public = false; - - /** - * @var string - * @Column - * @Expose - */ - private $category = ''; - - /** - * @var Administrator - * @Mapping\ManyToOne(targetEntity="PhpList\Core\Domain\Model\Identity\Administrator") - * @Mapping\JoinColumn(name="owner") - */ - private $owner = null; - - /** - * @var Collection - * @Mapping\OneToMany( - * targetEntity="PhpList\Core\Domain\Model\Subscription\Subscription", - * mappedBy="subscriberList", - * cascade={"remove"} - * ) - */ - private $subscriptions = null; - - /** - * @var Collection - * @Mapping\ManyToMany( - * targetEntity="PhpList\Core\Domain\Model\Subscription\Subscriber", - * inversedBy="subscribedLists", - * fetch="EXTRA_LAZY" - * ) - * @Mapping\JoinTable(name="phplist_listuser", - * joinColumns={@Mapping\JoinColumn(name="listid")}, - * inverseJoinColumns={@Mapping\JoinColumn(name="userid")} - * ) - */ - private $subscribers = null; - - /** - * The constructor. - */ + #[ORM\Column] + #[SerializedName('name')] + #[Groups(['SubscriberList'])] + private string $name = ''; + + #[ORM\Column] + #[SerializedName('description')] + #[Groups(['SubscriberList'])] + private string $description = ''; + + #[ORM\Column(name: 'entered', type: 'datetime', nullable: true)] + #[SerializedName('creation_date')] + #[Groups(['SubscriberList'])] + protected ?DateTime $creationDate = null; + + #[ORM\Column(name: 'modified', type: 'datetime')] + #[Ignore] + protected ?DateTime $modificationDate = null; + + #[ORM\Column(name: 'listorder', type: 'integer')] + #[SerializedName('list_position')] + #[Groups(['SubscriberList'])] + private ?int $listPosition; + + #[ORM\Column(name: 'prefix')] + #[SerializedName('subject_prefix')] + #[Groups(['SubscriberList'])] + private ?string $subjectPrefix; + + #[ORM\Column(name: 'active', type: 'boolean')] + #[SerializedName('public')] + #[Groups(['SubscriberList'])] + private bool $public; + + #[ORM\Column] + #[SerializedName('category')] + #[Groups(['SubscriberList'])] + private string $category; + + #[ORM\ManyToOne(targetEntity: 'PhpList\Core\Domain\Model\Identity\Administrator')] + #[ORM\JoinColumn(name: 'owner')] + #[Ignore] + private ?Administrator $owner = null; + + #[ORM\OneToMany( + targetEntity: 'PhpList\Core\Domain\Model\Subscription\Subscription', + mappedBy: 'subscriberList', + cascade: ['remove'], + orphanRemoval: true, + )] + #[MaxDepth(1)] + private Collection $subscriptions; + public function __construct() { $this->subscriptions = new ArrayCollection(); - $this->subscribers = new ArrayCollection(); + $this->listPosition = 0; + $this->subjectPrefix = ''; + $this->category = ''; + $this->public = false; } - /** - * @return string - */ public function getName(): string { return $this->name; } - /** - * @param string $name - * - * @return void - */ - public function setName(string $name) + public function setName(string $name): void { $this->name = $name; } - /** - * @return string - */ public function getDescription(): string { return $this->description; } - /** - * @param string $description - * - * @return void - */ - public function setDescription(string $description) + public function setDescription(string $description): void { $this->description = $description; } - /** - * @return int - */ public function getListPosition(): int { return $this->listPosition; } - /** - * @param int $listPosition - * - * @return void - */ - public function setListPosition(int $listPosition) + public function setListPosition(int $listPosition): void { $this->listPosition = $listPosition; } - /** - * @return string - */ public function getSubjectPrefix(): string { return $this->subjectPrefix; } - /** - * @param string $subjectPrefix - * - * @return void - */ - public function setSubjectPrefix(string $subjectPrefix) + public function setSubjectPrefix(string $subjectPrefix): void { $this->subjectPrefix = $subjectPrefix; } - /** - * @return bool - */ public function isPublic(): bool { - return $this->public; + return $this->public ?? false; } - /** - * @param bool $public - * - * @return void - */ - public function setPublic(bool $public) + public function setPublic(bool $public): void { $this->public = $public; } - /** - * @return string - */ public function getCategory(): string { return $this->category; } - /** - * @param string $category - * - * @return void - */ - public function setCategory(string $category) + public function setCategory(string $category): void { $this->category = $category; } - /** - * @return Administrator|Proxy|null - */ - public function getOwner() + public function getOwner(): ?Administrator { return $this->owner; } - /** - * @param Administrator $owner - * - * @return void - */ - public function setOwner(Administrator $owner) + public function setOwner(Administrator $owner): void { $this->owner = $owner; } - /** - * @return Collection - */ public function getSubscriptions(): Collection { return $this->subscriptions; } - /** - * @param Collection $subscriptions - * - * @return void - */ - public function setSubscriptions(Collection $subscriptions) + public function addSubscription(Subscription $subscription): self { - $this->subscriptions = $subscriptions; + if (!$this->subscriptions->contains($subscription)) { + $this->subscriptions->add($subscription); + $subscription->setSubscriberList($this); + } + + return $this; } - /** - * @return Collection - */ - public function getSubscribers(): Collection + public function removeSubscription(Subscription $subscription): self { - return $this->subscribers; + if ($this->subscriptions->removeElement($subscription)) { + $subscription->setSubscriberList(null); + } + + return $this; } - /** - * @param Collection $subscribers - * - * @return void - */ - public function setSubscribers(Collection $subscribers) + public function getSubscribers(): Collection { - $this->subscribers = $subscribers; + $result = new ArrayCollection(); + foreach ($this->subscriptions as $subscription) { + $result->add($subscription->getSubscriber()); + } + + return $result; } } diff --git a/src/Domain/Model/Subscription/Subscriber.php b/src/Domain/Model/Subscription/Subscriber.php index 226d2209..9473a026 100644 --- a/src/Domain/Model/Subscription/Subscriber.php +++ b/src/Domain/Model/Subscription/Subscriber.php @@ -1,14 +1,15 @@ */ +#[ORM\Entity(repositoryClass: 'PhpList\Core\Domain\Repository\Subscription\SubscriberRepository')] +#[ORM\Table(name: 'phplist_user_user')] +#[ORM\Index(name: 'idxuniqid', columns: ['uniqid'])] +#[ORM\Index(name: 'enteredindex', columns: ['entered'])] +#[ORM\Index(name: 'confidx', columns: ['confirmed'])] +#[ORM\Index(name: 'blidx', columns: ['blacklisted'])] +#[ORM\HasLifecycleCallbacks] class Subscriber implements DomainModel, Identity, CreationDate, ModificationDate { use IdentityTrait; use CreationDateTrait; use ModificationDateTrait; - /** - * @var \DateTime|null - * @Column(type="datetime", nullable=true, name="entered") - * @Expose - */ - protected $creationDate = null; - - /** - * @var \DateTime|null - * @Column(type="datetime", name="modified") - */ - protected $modificationDate = null; - - /** - * @var string - * @Column(unique=true) - * @Expose - */ - private $email = ''; - - /** - * @var bool - * @Column(type="boolean") - * @Expose - */ - private $confirmed = false; - - /** - * @var bool - * @Column(type="boolean") - * @Expose - */ - private $blacklisted = false; + #[ORM\Column(name: 'entered', type: 'datetime', nullable: true)] + #[SerializedName('creation_date')] + #[Groups(['SubscriberListMembers'])] + protected ?DateTime $creationDate = null; + + #[ORM\Column(name: 'modified', type: 'datetime')] + #[Ignore] + protected ?DateTime $modificationDate = null; + + #[ORM\Column(unique: true)] + #[SerializedName('email')] + #[Groups(['SubscriberListMembers'])] + private string $email = ''; + + #[ORM\Column(type: 'boolean')] + #[SerializedName('confirmed')] + #[Groups(['SubscriberListMembers'])] + private bool $confirmed = false; + + #[ORM\Column(type: 'boolean')] + #[SerializedName('blacklisted')] + #[Groups(['SubscriberListMembers'])] + private bool $blacklisted = false; + + #[ORM\Column(name: 'bouncecount', type: 'integer')] + #[SerializedName('bounce_count')] + #[Groups(['SubscriberListMembers'])] + private int $bounceCount = 0; + + #[ORM\Column(name: 'uniqid', unique: true)] + #[SerializedName('unique_id')] + #[Groups(['SubscriberListMembers'])] + private string $uniqueId = ''; + + #[ORM\Column(name: 'htmlemail', type: 'boolean')] + #[SerializedName('html_email')] + #[Groups(['SubscriberListMembers'])] + private bool $htmlEmail = false; + + #[ORM\Column(type: 'boolean')] + #[SerializedName('disabled')] + #[Groups(['SubscriberListMembers'])] + private bool $disabled = false; + + #[ORM\Column(name: 'extradata', type: 'text')] + #[SerializedName('extra_data')] + private ?string $extraData; + + #[ORM\OneToMany( + targetEntity: 'PhpList\Core\Domain\Model\Subscription\Subscription', + mappedBy: 'subscriber', + cascade: ['remove'], + orphanRemoval: true, + )] + private Collection $subscriptions; - /** - * @var int - * @Column(type="integer", name="bouncecount") - * @Expose - */ - private $bounceCount = 0; - - /** - * Note: The uniqueness of this column will not be enforced as long as we use the old DB schema, - * not the Doctrine-generated one. - * - * @var string - * @Column(name="uniqid", unique=true) - * @Expose - */ - private $uniqueId = ''; - - /** - * @var bool - * @Column(type="boolean", name="htmlemail") - * @Expose - */ - private $htmlEmail = false; - - /** - * @var bool - * @Column(type="boolean") - * @Expose - */ - private $disabled = false; - - /** - * @var string - * @Column(type="text", name="extradata") - * @Expose - */ - private $extraData = ''; - - /** - * @var Collection - * @Mapping\OneToMany( - * targetEntity="PhpList\Core\Domain\Model\Subscription\Subscription", - * mappedBy="subscriber", - * cascade={"remove"} - * ) - */ - private $subscriptions = null; - - /** - * @var Collection - * @Mapping\ManyToMany(targetEntity="PhpList\Core\Domain\Model\Messaging\SubscriberList", inversedBy="subscribers") - * @Mapping\JoinTable(name="phplist_listuser", - * joinColumns={@Mapping\JoinColumn(name="userid")}, - * inverseJoinColumns={@Mapping\JoinColumn(name="listid")} - * ) - */ - private $subscribedLists = null; - - /** - * The constructor. - */ public function __construct() { $this->subscriptions = new ArrayCollection(); - $this->subscribedLists = new ArrayCollection(); + $this->extraData = ''; } - /** - * @return bool - */ public function isConfirmed(): bool { return $this->confirmed; } - /** - * @param bool $confirmed - * - * @return void - */ - public function setConfirmed(bool $confirmed) + public function setConfirmed(bool $confirmed): void { $this->confirmed = $confirmed; } - /** - * @return bool - */ public function isBlacklisted(): bool { return $this->blacklisted; } - /** - * @param bool $blacklisted - * - * @return void - */ - public function setBlacklisted(bool $blacklisted) + public function setBlacklisted(bool $blacklisted): void { $this->blacklisted = $blacklisted; } - /** - * @return int - */ public function getBounceCount(): int { return $this->bounceCount; } - /** - * @param int $bounceCount - * - * @return void - */ - public function setBounceCount(int $bounceCount) + public function setBounceCount(int $bounceCount): void { $this->bounceCount = $bounceCount; } - /** - * @param int $delta the number of bounces to add to the bounce count - * - * @return void - */ - public function addToBounceCount(int $delta) + public function addToBounceCount(int $delta): void { $this->setBounceCount($this->getBounceCount() + $delta); } - /** - * @return string - */ public function getUniqueId(): string { return $this->uniqueId; } - /** - * @param string $uniqueId - * - * @return void - */ - public function setUniqueId(string $uniqueId) + public function setUniqueId(string $uniqueId): void { $this->uniqueId = $uniqueId; } - /** - * Generates and sets a (new) random unique ID. - * - * @Mapping\PrePersist - * - * @return void - */ - public function generateUniqueId() + #[ORM\PrePersist] + public function generateUniqueId(): void { $this->setUniqueId(bin2hex(random_bytes(16))); } - /** - * @return string - */ public function getEmail(): string { return $this->email; } - /** - * @param string $email - * - * @return void - */ - public function setEmail(string $email) + public function setEmail(string $email): void { $this->email = $email; } - /** - * @return bool - */ public function hasHtmlEmail(): bool { return $this->htmlEmail; } - /** - * @param bool $htmlEmail - * - * @return void - */ - public function setHtmlEmail(bool $htmlEmail) + public function setHtmlEmail(bool $htmlEmail): void { $this->htmlEmail = $htmlEmail; } - /** - * @return bool - */ public function isDisabled(): bool { return $this->disabled; } - /** - * @param bool $disabled - * - * @return void - */ - public function setDisabled(bool $disabled) + public function setDisabled(bool $disabled): void { $this->disabled = $disabled; } - /** - * @return string - */ public function getExtraData(): string { return $this->extraData; } - /** - * @param string $extraData - * - * @return void - */ - public function setExtraData(string $extraData) + public function setExtraData(string $extraData): void { $this->extraData = $extraData; } + /** - * @return Collection + * @return Collection */ public function getSubscriptions(): Collection { return $this->subscriptions; } - /** - * @param Collection $subscriptions - * - * @return void - */ - public function setSubscriptions(Collection $subscriptions) + public function addSubscription(Subscription $subscription): self { - $this->subscriptions = $subscriptions; + if (!$this->subscriptions->contains($subscription)) { + $this->subscriptions->add($subscription); + $subscription->setSubscriber($this); + } + + return $this; } - /** - * @return Collection - */ - public function getSubscribedLists(): Collection + public function removeSubscription(Subscription $subscription): self { - return $this->subscribedLists; + if ($this->subscriptions->removeElement($subscription)) { + $subscription->setSubscriber(null); + } + + return $this; } - /** - * @param Collection $subscribedLists - * - * @return void - */ - public function setSubscribedLists(Collection $subscribedLists) + public function getSubscribedLists(): Collection { - $this->subscribedLists = $subscribedLists; + $result = new ArrayCollection(); + foreach ($this->subscriptions as $subscription) { + $result->add($subscription->getSubscriberList()); + } + + return $result; } } diff --git a/src/Domain/Model/Subscription/Subscription.php b/src/Domain/Model/Subscription/Subscription.php index e5ed1db6..a7fb89c3 100644 --- a/src/Domain/Model/Subscription/Subscription.php +++ b/src/Domain/Model/Subscription/Subscription.php @@ -1,13 +1,14 @@ */ +#[ORM\Entity(repositoryClass: 'PhpList\Core\Domain\Repository\Subscription\SubscriptionRepository')] +#[ORM\Table(name: 'phplist_listuser')] +#[ORM\Index(name: 'userenteredidx', columns: ['userid', 'entered'])] +#[ORM\Index(name: 'userlistenteredidx', columns: ['userid', 'entered', 'listid'])] +#[ORM\Index(name: 'useridx', columns: ['userid'])] +#[ORM\Index(name: 'listidx', columns: ['listid'])] +#[ORM\HasLifecycleCallbacks] class Subscription implements DomainModel, CreationDate, ModificationDate { use CreationDateTrait; use ModificationDateTrait; - /** - * @var \DateTime|null - * @Column(type="datetime", nullable=true, name="entered") - * @Expose - */ - protected $creationDate = null; + #[ORM\Column(name: 'entered', type: 'datetime', nullable: true)] + #[SerializedName('creation_date')] + protected ?DateTime $creationDate = null; - /** - * @var \DateTime|null - * @Column(type="datetime", name="modified") - */ - protected $modificationDate = null; + #[ORM\Column(name: 'modified', type: 'datetime')] + #[Ignore] + protected ?DateTime $modificationDate = null; - /** - * @var Subscriber|Proxy|null - * @Mapping\Id - * @Mapping\ManyToOne( - * targetEntity="PhpList\Core\Domain\Model\Subscription\Subscriber", - * inversedBy="subscriptions" - * ) - * @Mapping\JoinColumn(name="userid") - */ - private $subscriber = null; + #[ORM\Id] + #[ORM\ManyToOne( + targetEntity: 'PhpList\Core\Domain\Model\Subscription\Subscriber', + inversedBy: 'subscriptions' + )] + #[ORM\JoinColumn(name: 'userid')] + #[SerializedName('subscriber')] + private ?Subscriber $subscriber = null; - /** - * @var SubscriberList|Proxy|null - * @Mapping\Id - * @Mapping\ManyToOne( - * targetEntity="PhpList\Core\Domain\Model\Messaging\SubscriberList", - * inversedBy="subscriptions" - * ) - * @Mapping\JoinColumn(name="listid") - */ - private $subscriberList = null; + #[ORM\Id] + #[ORM\ManyToOne( + targetEntity: 'PhpList\Core\Domain\Model\Messaging\SubscriberList', + inversedBy: 'subscriptions' + )] + #[ORM\JoinColumn(name: 'listid', onDelete: 'CASCADE')] + #[Ignore] + private ?SubscriberList $subscriberList = null; - /** - * @return Subscriber|Proxy|null - */ - public function getSubscriber() + public function getSubscriber(): Subscriber|Proxy|null { return $this->subscriber; } - /** - * @param Subscriber $subscriber - * - * @return void - */ - public function setSubscriber(Subscriber $subscriber) + public function setSubscriber(?Subscriber $subscriber): void { $this->subscriber = $subscriber; } - /** - * @return SubscriberList|Proxy|null - */ - public function getSubscriberList() + public function getSubscriberList(): ?SubscriberList { return $this->subscriberList; } - /** - * @param SubscriberList $subscriberList - * - * @return void - */ - public function setSubscriberList(SubscriberList $subscriberList) + public function setSubscriberList(?SubscriberList $subscriberList): void { $this->subscriberList = $subscriberList; } diff --git a/src/Domain/Model/Traits/CreationDateTrait.php b/src/Domain/Model/Traits/CreationDateTrait.php index 13e95ab2..51b6fd25 100644 --- a/src/Domain/Model/Traits/CreationDateTrait.php +++ b/src/Domain/Model/Traits/CreationDateTrait.php @@ -1,9 +1,11 @@ creationDate; } /** - * @param \DateTime $creationDate + * @param DateTime $creationDate * * @return void */ - private function setCreationDate(\DateTime $creationDate) + private function setCreationDate(DateTime $creationDate): void { $this->creationDate = $creationDate; } - /** - * Updates the creation date to now. - * - * @PrePersist - * - * @return void - */ - public function updateCreationDate() + #[ORM\PrePersist] + public function updateCreationDate(): void { - $this->setCreationDate(new \DateTime()); + $this->setCreationDate(new DateTime()); } } diff --git a/src/Domain/Model/Traits/IdentityTrait.php b/src/Domain/Model/Traits/IdentityTrait.php index bea0a88f..4445ea26 100644 --- a/src/Domain/Model/Traits/IdentityTrait.php +++ b/src/Domain/Model/Traits/IdentityTrait.php @@ -1,10 +1,12 @@ id; diff --git a/src/Domain/Model/Traits/ModificationDateTrait.php b/src/Domain/Model/Traits/ModificationDateTrait.php index cc4822e8..78f2880a 100644 --- a/src/Domain/Model/Traits/ModificationDateTrait.php +++ b/src/Domain/Model/Traits/ModificationDateTrait.php @@ -1,50 +1,38 @@ */ trait ModificationDateTrait { - /** - * @return \DateTime|null - */ - public function getModificationDate() + public function getModificationDate(): ?DateTime { return $this->modificationDate; } - /** - * @param \DateTime $modificationDate - * - * @return void - */ - private function setModificationDate(\DateTime $modificationDate) + private function setModificationDate(DateTime $modificationDate): void { $this->modificationDate = $modificationDate; } - /** - * Updates the modification date to now. - * - * @Mapping\PrePersist - * @Mapping\PreUpdate - * - * @return void - */ - public function updateModificationDate() + #[ORM\PrePersist] + #[ORM\PreUpdate] + public function updateModificationDate(): void { - $this->setModificationDate(new \DateTime()); + $this->setModificationDate(new DateTime()); } } diff --git a/src/Domain/Repository/AbstractRepository.php b/src/Domain/Repository/AbstractRepository.php index cc95dc86..8cc52362 100644 --- a/src/Domain/Repository/AbstractRepository.php +++ b/src/Domain/Repository/AbstractRepository.php @@ -1,4 +1,5 @@ getEntityManager()->persist($model); $this->getEntityManager()->flush(); @@ -39,7 +40,7 @@ public function save(DomainModel $model) * * @return void */ - public function remove(DomainModel $model) + public function remove(DomainModel $model): void { $this->getEntityManager()->remove($model); $this->getEntityManager()->flush(); diff --git a/src/Domain/Repository/Identity/AdministratorRepository.php b/src/Domain/Repository/Identity/AdministratorRepository.php index fc5bbe79..d98324b0 100644 --- a/src/Domain/Repository/Identity/AdministratorRepository.php +++ b/src/Domain/Repository/Identity/AdministratorRepository.php @@ -1,8 +1,11 @@ hashGenerator = $hashGenerator; + public function __construct( + EntityManagerInterface $entityManager, + ClassMetadata $class, + HashGenerator $hashGenerator = null + ) { + parent::__construct($entityManager, $class); + $this->hashGenerator = $hashGenerator ?? new HashGenerator(); } /** * Finds the Administrator with the given login credentials. Returns null if there is no match, * i.e., if the login credentials are incorrect. * - * This also checks that the administrator is a super user. + * This also checks that the administrator is a superuser. * * @param string $loginName * @param string $plainTextPassword * * @return Administrator|null */ - public function findOneByLoginCredentials(string $loginName, string $plainTextPassword) + public function findOneByLoginCredentials(string $loginName, string $plainTextPassword): ?Administrator { $passwordHash = $this->hashGenerator->createPasswordHash($plainTextPassword); diff --git a/src/Domain/Repository/Identity/AdministratorTokenRepository.php b/src/Domain/Repository/Identity/AdministratorTokenRepository.php index fbaffde5..818b6bd0 100644 --- a/src/Domain/Repository/Identity/AdministratorTokenRepository.php +++ b/src/Domain/Repository/Identity/AdministratorTokenRepository.php @@ -1,8 +1,12 @@ where(Criteria::expr()->eq('key', $key)) - ->andWhere(Criteria::expr()->gt('expiry', new \DateTime())); + ->andWhere(Criteria::expr()->gt('expiry', new DateTime())); $firstMatch = $this->matching($criteria)->first(); @@ -44,9 +48,23 @@ public function findOneUnexpiredByKey(string $key) */ public function removeExpired(): int { - $queryBuilder = $this->getEntityManager()->createQueryBuilder(); - $queryBuilder->delete(AdministratorToken::class, 'token')->where('token.expiry <= CURRENT_TIMESTAMP()'); + $now = new DateTimeImmutable('now', new DateTimeZone('UTC')); + + $expiredTokens = $this->createQueryBuilder('at') + ->where('at.expiry <= :date') + ->setParameter('date', $now) + ->getQuery() + ->getResult(); + + $deletedCount = 0; + + foreach ($expiredTokens as $token) { + $this->getEntityManager()->remove($token); + $deletedCount++; + } + + $this->getEntityManager()->flush(); - return (int)$queryBuilder->getQuery()->execute(); + return $deletedCount; } } diff --git a/src/Domain/Repository/Messaging/SubscriberListRepository.php b/src/Domain/Repository/Messaging/SubscriberListRepository.php index 8d50236e..04d45b5a 100644 --- a/src/Domain/Repository/Messaging/SubscriberListRepository.php +++ b/src/Domain/Repository/Messaging/SubscriberListRepository.php @@ -1,4 +1,5 @@ createQueryBuilder('sl') + ->innerJoin('sl.subscriptions', 's') + ->addSelect('s') + ->where('sl.id = :id') + ->setParameter('id', $id) + ->getQuery() + ->getOneOrNullResult(); + } } diff --git a/src/Domain/Repository/Subscription/SubscriberRepository.php b/src/Domain/Repository/Subscription/SubscriberRepository.php index ebadcc69..c467e9b6 100644 --- a/src/Domain/Repository/Subscription/SubscriberRepository.php +++ b/src/Domain/Repository/Subscription/SubscriberRepository.php @@ -1,4 +1,5 @@ createQueryBuilder('s') + ->innerJoin('s.subscriptions', 'subscription') + ->innerJoin('subscription.subscriberList', 'list') + ->where('list.id = :listId') + ->setParameter('listId', $listId) + ->getQuery() + ->getOneOrNullResult(); + } + + /** @return Subscriber[] */ + public function getSubscribersBySubscribedListId(int $listId): array + { + return $this->createQueryBuilder('s') + ->innerJoin('s.subscriptions', 'subscription') + ->innerJoin('subscription.subscriberList', 'list') + ->where('list.id = :listId') + ->setParameter('listId', $listId) + ->getQuery() + ->getResult(); + } + + public function findSubscriberWithSubscriptions(int $id): ?Subscriber + { + return $this->createQueryBuilder('s') + ->innerJoin('s.subscriptions', 'subscription') + ->innerJoin('subscription.subscriberList', 'list') + ->addSelect('subscription') + ->addSelect('list') + ->where('s.id = :id') + ->setParameter('id', $id) + ->getQuery() + ->getOneOrNullResult(); + } } diff --git a/src/Domain/Repository/Subscription/SubscriptionRepository.php b/src/Domain/Repository/Subscription/SubscriptionRepository.php index 05a9aa35..eb79f023 100644 --- a/src/Domain/Repository/Subscription/SubscriptionRepository.php +++ b/src/Domain/Repository/Subscription/SubscriptionRepository.php @@ -1,4 +1,5 @@ findOneBy( [ diff --git a/src/EmptyStartPageBundle/Controller/DefaultController.php b/src/EmptyStartPageBundle/Controller/DefaultController.php index be7b5ae3..2c86ff69 100644 --- a/src/EmptyStartPageBundle/Controller/DefaultController.php +++ b/src/EmptyStartPageBundle/Controller/DefaultController.php @@ -1,29 +1,28 @@ */ -class DefaultController extends Controller +class DefaultController extends AbstractController { /** - * @Route("/") - * @Method("GET") - * - * @return Response + * An empty start page route. * - * @throws \InvalidArgumentException + * @throws InvalidArgumentException */ - public function indexAction(): Response + #[Route('/api/v2', name: 'empty_start_page', methods: ['GET'])] + public function index(): Response { return new Response('This page has been intentionally left empty.'); } diff --git a/src/EmptyStartPageBundle/PhpListEmptyStartPageBundle.php b/src/EmptyStartPageBundle/EmptyStartPageBundle.php similarity index 83% rename from src/EmptyStartPageBundle/PhpListEmptyStartPageBundle.php rename to src/EmptyStartPageBundle/EmptyStartPageBundle.php index 08973695..6eec6980 100644 --- a/src/EmptyStartPageBundle/PhpListEmptyStartPageBundle.php +++ b/src/EmptyStartPageBundle/EmptyStartPageBundle.php @@ -1,4 +1,5 @@ */ -class PhpListEmptyStartPageBundle extends Bundle +class EmptyStartPageBundle extends Bundle { } diff --git a/src/Routing/ExtraLoader.php b/src/Routing/ExtraLoader.php index f12586b1..39853031 100644 --- a/src/Routing/ExtraLoader.php +++ b/src/Routing/ExtraLoader.php @@ -1,9 +1,11 @@ applicationStructure = $applicationStructure; } @@ -47,12 +50,12 @@ public function __construct(ApplicationStructure $applicationStructure) * * @return RouteCollection * - * @throws \RuntimeException + * @throws RuntimeException */ - public function load($resource, $type = null): RouteCollection + public function load($resource, string $type = null): RouteCollection { if ($this->loaded) { - throw new \RuntimeException('Do not add the "extra" loader twice.', 1500587713); + throw new RuntimeException('Do not add the "extra" loader twice.', 1500587713); } $routes = new RouteCollection(); @@ -73,7 +76,7 @@ public function load($resource, $type = null): RouteCollection * * @return bool true if this class supports the given resource, false otherwise */ - public function supports($resource, $type = null): bool + public function supports($resource, string $type = null): bool { return $type === 'extra'; } @@ -83,7 +86,7 @@ public function supports($resource, $type = null): bool * * @return void */ - private function addModuleRoutes(RouteCollection $routes) + private function addModuleRoutes(RouteCollection $routes): void { $bundleRoutesFilePath = $this->applicationStructure->getApplicationRoot() . static::MODULE_ROUTING_CONFIGURATION_FILE; diff --git a/src/Security/Authentication.php b/src/Security/Authentication.php index b8bcfc29..477476fc 100644 --- a/src/Security/Authentication.php +++ b/src/Security/Authentication.php @@ -1,4 +1,5 @@ headers->get('php-auth-pw'); if (empty($apiKey)) { @@ -57,7 +58,7 @@ public function authenticateByApiKey(Request $request) } try { - // This checks for cases where a super user created a session key and then got their super user + // This checks for cases where a superuser created a session key and then got their super user // privileges removed during the lifetime of the session key. Or an administrator got disabled. // In addition, this will load the lazy-loaded model from the database, // which will check that the model really exists in the database (i.e., it has not been deleted). diff --git a/src/Security/HashGenerator.php b/src/Security/HashGenerator.php index 92298019..a70acaa3 100644 --- a/src/Security/HashGenerator.php +++ b/src/Security/HashGenerator.php @@ -1,4 +1,5 @@ setUpWebTest() first thing in your setUp method. - * - * @author Oliver Klee - */ -abstract class AbstractWebTest extends WebTestCase -{ - /** - * @var Client - */ - protected $client = null; - - protected function setUp() - { - $this->setUpWebTest(); - } - - protected function setUpWebTest() - { - // This makes sure that all DateTime instances use the same time zone, thus making the dates in the - // JSON provided by the REST API easier to test. - date_default_timezone_set('UTC'); - - Bootstrap::getInstance()->setEnvironment(Environment::TESTING)->configure(); - - $this->client = static::createClient(['environment' => Environment::TESTING]); - } -} diff --git a/src/TestingSupport/Fixtures/TouchTable.csv b/src/TestingSupport/Fixtures/TouchTable.csv deleted file mode 100644 index 8b137891..00000000 --- a/src/TestingSupport/Fixtures/TouchTable.csv +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/TestingSupport/Traits/ContainsInstanceAssertionTrait.php b/src/TestingSupport/Traits/ContainsInstanceAssertionTrait.php index 726d027d..c1b2cc5b 100644 --- a/src/TestingSupport/Traits/ContainsInstanceAssertionTrait.php +++ b/src/TestingSupport/Traits/ContainsInstanceAssertionTrait.php @@ -1,4 +1,5 @@ setUpDatabaseTest() first thing in your setUp method. - * - * And if you have your own tearDown method, call $this->tearDownDatabaseTest() first thing in your tearDown method. - * - * @author Oliver Klee + * This trait provides support for integration tests involving database records. */ trait DatabaseTestTrait { - use TestCaseTrait; + protected ?Bootstrap $bootstrap = null; + protected ?EntityManagerInterface $entityManager = null; + protected static $container; /** - * @var Connection + * Sets up the database test environment. */ - private $databaseConnection = null; - - /** - * @var \PDO - */ - private static $pdo = null; - - /** - * @var CsvDataSet - */ - private $dataSet = null; - - /** - * @var Bootstrap - */ - protected $bootstrap = null; - - /** - * @var EntityManagerInterface - */ - protected $entityManager = null; - - /** - * @var ContainerInterface - */ - protected $container = null; - - protected function setUp() + protected function setUpDatabaseTest(): void { - $this->setUpDatabaseTest(); - } - - protected function setUpDatabaseTest() - { - $this->initializeDatabaseTester(); - $this->bootstrap = Bootstrap::getInstance()->setEnvironment(Environment::TESTING)->configure(); - $this->container = $this->bootstrap->getContainer(); - $this->entityManager = $this->bootstrap->getEntityManager(); - static::assertTrue($this->entityManager->isOpen()); + $this->initializeBootstrap(); } /** - * Initializes the CSV data set and the database tester. - * - * @return void + * Tears down the database test environment. */ - protected function initializeDatabaseTester() + protected function tearDownDatabaseTest(): void { - $this->dataSet = new CsvDataSet(); - - unset($this->databaseTester); - $this->getDatabaseTester()->setSetUpOperation($this->getSetUpOperation()); - } - - protected function tearDown() - { - $this->tearDownDatabaseTest(); - } - - protected function tearDownDatabaseTest() - { - $this->entityManager->close(); - $this->getDatabaseTester()->setTearDownOperation($this->getTearDownOperation()); - $this->getDatabaseTester()->setDataSet($this->getDataSet()); - $this->getDatabaseTester()->onTearDown(); - - // Destroy the tester after the test is run to keep DB connections - // from piling up. - unset($this->databaseTester); - - Bootstrap::purgeInstance(); + $this->entityManager?->clear(); + $this->entityManager?->close(); + $this->bootstrap = null; + $this->entityManager = null; } /** - * Returns the database operation executed in test cleanup. + * Initializes the Bootstrap and Doctrine EntityManager. * - * @return Operation + * @throws RuntimeException */ - protected function getTearDownOperation(): Operation + private function initializeBootstrap(): void { - return Factory::TRUNCATE(); - } + $this->bootstrap = Bootstrap::getInstance() + ->setEnvironment(Environment::TESTING) + ->configure(); - /** - * Returns the test database connection. - * - * @return Connection - */ - protected function getConnection(): Connection - { - if ($this->databaseConnection === null) { - if (self::$pdo === null) { - $databaseHost = getenv('PHPLIST_DATABASE_HOST') ?: 'localhost'; - $databasePort = getenv('PHPLIST_DATABASE_PORT') ?: '3306'; - $databaseName = getenv('PHPLIST_DATABASE_NAME'); - self::$pdo = new \PDO( - 'mysql:host='.$databaseHost.';port='.$databasePort.';dbname='.$databaseName, - getenv('PHPLIST_DATABASE_USER'), - getenv('PHPLIST_DATABASE_PASSWORD') - ); - } - $this->databaseConnection = $this->createDefaultDBConnection(self::$pdo); - } + $this->entityManager = $this->bootstrap->getEntityManager(); - return $this->databaseConnection; + if (!$this->entityManager->isOpen()) { + throw new RuntimeException('The Doctrine EntityManager is not open.'); + } } /** - * Returns the test data set. + * Loads data fixtures into the database. * - * Add data to in the individual test by calling $this->getDataSet()->addTable. - * - * @return CsvDataSet + * @param array $fixtures List of fixture classes to load + * @throws InvalidArgumentException */ - protected function getDataSet(): CsvDataSet + protected function loadFixtures(array $fixtures): void { - return $this->dataSet; - } + foreach ($fixtures as $fixture) { + $fixtureInstance = new $fixture(); + if (!method_exists($fixtureInstance, 'load')) { + throw new InvalidArgumentException(sprintf('Fixture %s must have a load() method.', $fixture)); + } - /** - * Applies all database changes on $this->dataSet. - * - * This methods needs to be called after the last addTable call in each test. - * - * @return void - */ - protected function applyDatabaseChanges() - { - $this->getDatabaseTester()->setDataSet($this->getDataSet()); - $this->getDatabaseTester()->onSetUp(); + $fixtureInstance->load($this->entityManager); + $this->entityManager->flush(); + } } - /** - * Marks the table with the given name as "touched", i.e., it will be truncated in the tearDown method. - * - * This is useful if the table gets populated only by the tested code instead of by using the addTable - * and applyDatabaseChanges method. - * - * @param string $tableName - * - * @return void - */ - protected function touchDatabaseTable(string $tableName) + protected function loadSchema(): void { - $this->getDataSet()->addTable($tableName, __DIR__ . '/../Fixtures/TouchTable.csv'); + $this->entityManager = self::getContainer()->get('doctrine.orm.entity_manager'); + $schemaTool = new SchemaTool($this->entityManager); + $metadata = $this->entityManager->getMetadataFactory()->getAllMetadata(); + + $connection = $this->entityManager->getConnection(); + $schemaManager = $connection->createSchemaManager(); + + foreach ($metadata as $classMetadata) { + $tableName = $classMetadata->getTableName(); + + if (!$schemaManager->tablesExist([$tableName])) { + try { + $schemaTool->createSchema([$classMetadata]); + } catch (ToolsException $e) { + // nothing to do + echo $e->getMessage(); + } + } + } } } diff --git a/src/TestingSupport/Traits/ModelTestTrait.php b/src/TestingSupport/Traits/ModelTestTrait.php index 2300974f..5dcfc5d5 100644 --- a/src/TestingSupport/Traits/ModelTestTrait.php +++ b/src/TestingSupport/Traits/ModelTestTrait.php @@ -1,8 +1,12 @@ subject. + * Sets the (private) ID of $this->repository. * + * @param DomainModel $model * @param int $id * * @return void */ - private function setSubjectId(int $id) + private function setSubjectId(DomainModel $model, int $id): void { - $this->setSubjectProperty('id', $id); + $this->setSubjectProperty($model, 'id', $id); } /** - * Sets the (private) property $propertyName of $this->subject. - * - * @internal + * Sets the (private) property $propertyName of $this->repository. * * @param string $propertyName * @param mixed $value * - * @return void + * @return void* */ - private function setSubjectProperty(string $propertyName, $value) + private function setSubjectProperty(DomainModel $model, string $propertyName, mixed $value): void { - $reflectionObject = new \ReflectionObject($this->subject); + $reflectionObject = new ReflectionObject($model); $reflectionProperty = $reflectionObject->getProperty($propertyName); - $reflectionProperty->setAccessible(true); - $reflectionProperty->setValue($this->subject, $value); + $reflectionProperty->setValue($model, $value); } } diff --git a/src/TestingSupport/Traits/SimilarDatesAssertionTrait.php b/src/TestingSupport/Traits/SimilarDatesAssertionTrait.php index 588b1b41..fa940438 100644 --- a/src/TestingSupport/Traits/SimilarDatesAssertionTrait.php +++ b/src/TestingSupport/Traits/SimilarDatesAssertionTrait.php @@ -1,8 +1,11 @@ lockFileExists()) { - throw new \RuntimeException( - 'The server lock file "' . static::$lockFileName . '" already exists. ' . - 'Most probably, a symfony server already is running. ' . - 'Please stop the symfony server or delete the lock file.', - 1516622609 + throw new RuntimeException( + sprintf( + 'The server lock file "%s" already exists.', + self::$lockFileName + ) ); } $this->serverProcess = new Process( - $this->getSymfonyServerStartCommand($environment), - $this->getApplicationRoot() + $this->getSymfonyServerStartCommand(), + $this->getApplicationRoot(), + ['APP_ENV' => 'test'] ); $this->serverProcess->start(); + usleep(self::$serverCommandTimeout); $this->waitForServerLockFileToAppear(); - // Give the server some more time to initialize so it will accept connections. - \usleep(75000); + usleep(self::$serverCommandTimeout); } - /** - * @return bool - */ private function lockFileExists(): bool { - return \file_exists($this->getFullLockFilePath()); + return file_exists($this->getFullLockFilePath()); } - /** - * @return string the base URL (including protocol and port, but without the trailing slash) - */ protected function getBaseUrl(): string { - return 'http://' . \file_get_contents($this->getFullLockFilePath()); + if (!$this->lockFileExists()) { + throw new RuntimeException('Lock file does not exist. Is the server running?'); + } + + $port = file_get_contents($this->getFullLockFilePath()); + if ($port === false) { + throw new RuntimeException('Failed to read the lock file.'); + } + + return sprintf('http://localhost:%s', trim($port)); } - /** - * Waits for the server lock file to appear, and throws an exception if the file has not appeared after the - * maximum wait time. - * - * If the file already exists, this method returns instantly. - * - * @return void - * - * @throws \RuntimeException - */ - private function waitForServerLockFileToAppear() + private function waitForServerLockFileToAppear(): void { $currentWaitTime = 0; - while (!$this->lockFileExists() && $currentWaitTime < static::$maximumWaitTimeForServerLockFile) { - \usleep(static::$waitTimeBetweenServerCommands); - $currentWaitTime += static::$waitTimeBetweenServerCommands; + while (!$this->lockFileExists() && $currentWaitTime < self::$lockWaitTimeout) { + $process = new Process(['symfony', 'server:status', '--no-ansi']); + $process->run(); + + if ($process->isSuccessful()) { + $output = $process->getOutput(); + if (preg_match('/Listening on (http[s]?:\/\/127\.0\.0\.1:(\d+))/', $output, $matches)) { + $port = $matches[2]; + file_put_contents(self::$lockFileName, trim($port)); + } + } + usleep(self::$serverCommandTimeout); + $currentWaitTime += self::$serverCommandTimeout; } if (!$this->lockFileExists()) { - throw new \RuntimeException( - 'There is no symfony server lock file "' . static::$lockFileName . '".', + throw new RuntimeException( + 'There is no symfony server lock file "' . self::$lockFileName . '".', 1516625236 ); } } - /** - * @return string - */ private function getFullLockFilePath(): string { - return $this->getApplicationRoot() . '/' . static::$lockFileName; + return sprintf('%s/%s', $this->getApplicationRoot(), self::$lockFileName); } - /** - * @return void - */ - protected function stopSymfonyServer() + protected function stopSymfonyServer(): void { - if ($this->lockFileExists()) { - $server = new WebServer(); - $server->stop($this->getFullLockFilePath()); - } - if ($this->serverProcess !== null && $this->serverProcess->isRunning()) { + if ($this->serverProcess && $this->serverProcess->isRunning()) { $this->serverProcess->stop(); } + + if ($this->lockFileExists()) { + unlink($this->getFullLockFilePath()); + } } - /** - * @param string $environment - * - * @return string - */ - private function getSymfonyServerStartCommand(string $environment): string + private function getSymfonyServerStartCommand(): array { $documentRoot = $this->getApplicationRoot() . '/public/'; $this->checkDocumentRoot($documentRoot); - return sprintf( - '%1$s server:start -d %2$s --env=%3$s', - $this->getApplicationRoot() . '/bin/console', - $documentRoot, - $environment - ); + return [ + 'symfony', + 'server:start', + '--daemon', + ]; } - /** - * @return string - */ protected function getApplicationRoot(): string { - if (static::$applicationStructure === null) { - static::$applicationStructure = new ApplicationStructure(); + if (self::$applicationStructure === null) { + self::$applicationStructure = new ApplicationStructure(); } - return static::$applicationStructure->getApplicationRoot(); + return self::$applicationStructure->getApplicationRoot(); } - /** - * Checks that $documentRoot exists, is a directory and readable. - * - * @param string $documentRoot - * - * @return void - * - * @throws \RuntimeException - */ - private function checkDocumentRoot(string $documentRoot) + private function checkDocumentRoot(string $documentRoot): void { - if (!\file_exists($documentRoot)) { - throw new \RuntimeException('The document root "' . $documentRoot . '" does not exist.', 1499513246); + if (!file_exists($documentRoot)) { + throw new RuntimeException(sprintf('The document root "%s" does not exist.', $documentRoot)); } - if (!\is_dir($documentRoot)) { - throw new \RuntimeException( - 'The document root "' . $documentRoot . '" exists, but is no directory.', - 1499513263 - ); + + if (!is_dir($documentRoot)) { + throw new RuntimeException(sprintf('The document root "%s" exists but is not a directory.', $documentRoot)); } - if (!\is_readable($documentRoot)) { - throw new \RuntimeException( - 'The document root "' . $documentRoot . '" exists and is a directory, but is not readable.', - 1499513279 - ); + + if (!is_readable($documentRoot)) { + throw new RuntimeException(sprintf('The document root "%s" is not readable.', $documentRoot)); } } } diff --git a/tests/Integration/Composer/ScriptsTest.php b/tests/Integration/Composer/ScriptsTest.php index c7bd84c9..dac388f6 100644 --- a/tests/Integration/Composer/ScriptsTest.php +++ b/tests/Integration/Composer/ScriptsTest.php @@ -1,4 +1,5 @@ getBundleConfigurationFilePath()); + self::assertFileExists($this->getBundleConfigurationFilePath()); } - /** - * @return string[][] - */ public function bundleClassNameDataProvider(): array { return [ 'Symfony framework bundle' => ['Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle'], - 'sensio framework extras' => ['Sensio\\Bundle\\FrameworkExtraBundle\\SensioFrameworkExtraBundle'], 'Doctrine bundle' => ['Doctrine\\Bundle\\DoctrineBundle\\DoctrineBundle'], - 'empty start page bundle' => ['PhpList\\Core\\EmptyStartPageBundle\\PhpListEmptyStartPageBundle'], + 'empty start page bundle' => ['PhpList\\Core\\EmptyStartPageBundle\\EmptyStartPageBundle'], ]; } /** - * @test - * @param string $bundleClassName * @dataProvider bundleClassNameDataProvider */ - public function bundleConfigurationFileContainsModuleBundles(string $bundleClassName) + public function testBundleConfigurationFileContainsModuleBundles(string $bundleClassName): void { $fileContents = file_get_contents($this->getBundleConfigurationFilePath()); - - static::assertContains($bundleClassName, $fileContents); + self::assertStringContainsString($bundleClassName, $fileContents); } - /** - * @return string - */ private function getModuleRoutesConfigurationFilePath(): string { return dirname(__DIR__, 3) . '/config/routing_modules.yml'; } - /** - * @test - */ - public function moduleRoutesConfigurationFileExists() + public function testModuleRoutesConfigurationFileExists(): void { - static::assertFileExists($this->getModuleRoutesConfigurationFilePath()); + self::assertFileExists($this->getModuleRoutesConfigurationFilePath()); } - /** - * @return string[][] - */ public function moduleRoutingDataProvider(): array { return [ 'route name' => ['phplist/core.homepage'], - 'resource' => ["resource: '@PhpListEmptyStartPageBundle/Controller/'"], - 'type' => ['type: annotation'], + 'resource' => ["resource: '@EmptyStartPageBundle/Controller/'"], + 'type' => ['type: attribute'], ]; } /** - * @test - * @param string $routeSearchString * @dataProvider moduleRoutingDataProvider */ - public function moduleRoutesConfigurationFileContainsModuleRoutes(string $routeSearchString) + public function testModuleRoutesConfigurationFileContainsModuleRoutes(string $routeSearchString): void { $fileContents = file_get_contents($this->getModuleRoutesConfigurationFilePath()); - - static::assertContains($routeSearchString, $fileContents); + self::assertStringContainsString($routeSearchString, $fileContents); } - /** - * @test - */ - public function parametersConfigurationFileExists() + public function testParametersConfigurationFileExists(): void { - static::assertFileExists(dirname(__DIR__, 3) . '/config/parameters.yml'); + self::assertFileExists(dirname(__DIR__, 3) . '/config/parameters.yml'); } - /** - * @test - */ - public function modulesConfigurationFileExists() + public function testModulesConfigurationFileExists(): void { - static::assertFileExists(dirname(__DIR__, 3) . '/config/config_modules.yml'); + self::assertFileExists(dirname(__DIR__, 3) . '/config/config_modules.yml'); } } diff --git a/tests/Integration/Core/ApplicationKernelTest.php b/tests/Integration/Core/ApplicationKernelTest.php index b6acab58..4cf062b1 100644 --- a/tests/Integration/Core/ApplicationKernelTest.php +++ b/tests/Integration/Core/ApplicationKernelTest.php @@ -1,4 +1,5 @@ subject = new ApplicationKernel(Environment::TESTING, true); $this->subject->boot(); } - protected function tearDown() + protected function tearDown(): void { Bootstrap::purgeInstance(); } @@ -44,7 +45,7 @@ private function getCorePackageRoot(): string */ public function getProjectDirReturnsCorePackageRoot() { - static::assertSame($this->getCorePackageRoot(), $this->subject->getProjectDir()); + self::assertSame($this->getCorePackageRoot(), $this->subject->getProjectDir()); } /** @@ -52,7 +53,7 @@ public function getProjectDirReturnsCorePackageRoot() */ public function getRootDirReturnsCorePackageRoot() { - static::assertSame($this->getCorePackageRoot(), $this->subject->getRootDir()); + self::assertSame($this->getCorePackageRoot(), $this->subject->getRootDir()); } /** @@ -68,7 +69,7 @@ private function getApplicationRoot(): string */ public function getCacheDirReturnsEnvironmentSpecificVarCacheDirectoryInApplicationRoot() { - static::assertSame( + self::assertSame( $this->getApplicationRoot() . '/var/cache/' . Environment::TESTING, $this->subject->getCacheDir() ); @@ -79,7 +80,7 @@ public function getCacheDirReturnsEnvironmentSpecificVarCacheDirectoryInApplicat */ public function getLogDirReturnsVarLogsDirectoryInApplicationRoot() { - static::assertSame($this->getApplicationRoot() . '/var/logs', $this->subject->getLogDir()); + self::assertSame($this->getApplicationRoot() . '/var/logs', $this->subject->getLogDir()); } /** @@ -89,6 +90,6 @@ public function applicationDirIsAvailableAsContainerParameter() { $container = $this->subject->getContainer(); - static::assertSame($this->getApplicationRoot(), $container->getParameter('kernel.application_dir')); + self::assertSame($this->getApplicationRoot(), $container->getParameter('kernel.application_dir')); } } diff --git a/tests/Integration/Core/ApplicationStructureTest.php b/tests/Integration/Core/ApplicationStructureTest.php index 2ae6598e..43d5c0a6 100644 --- a/tests/Integration/Core/ApplicationStructureTest.php +++ b/tests/Integration/Core/ApplicationStructureTest.php @@ -1,4 +1,5 @@ setEnvironment(Environment::TESTING)->configure(); @@ -38,27 +32,21 @@ protected function setUp() $this->container = $this->kernel->getContainer(); } - protected function tearDown() + protected function tearDown(): void { $this->kernel->shutdown(); Bootstrap::purgeInstance(); } - /** - * @test - */ - public function subjectIsAvailableViaContainer() + public function testSubjectIsAvailableViaContainer() { - static::assertInstanceOf(ApplicationStructure::class, $this->container->get(ApplicationStructure::class)); + self::assertInstanceOf(ApplicationStructure::class, $this->container->get(ApplicationStructure::class)); } - /** - * @test - */ - public function classIsRegisteredAsSingletonInContainer() + public function testClassIsRegisteredAsSingletonInContainer() { $id = ApplicationStructure::class; - static::assertSame($this->container->get($id), $this->container->get($id)); + self::assertSame($this->container->get($id), $this->container->get($id)); } } diff --git a/tests/Integration/Core/BootstrapTest.php b/tests/Integration/Core/BootstrapTest.php index cf5237ac..2d3f6f3d 100644 --- a/tests/Integration/Core/BootstrapTest.php +++ b/tests/Integration/Core/BootstrapTest.php @@ -1,4 +1,5 @@ subject = Bootstrap::getInstance(); $this->subject->setEnvironment(Environment::TESTING); } - protected function tearDown() + protected function tearDown(): void { Bootstrap::purgeInstance(); } - /** - * @test - */ - public function ensureDevelopmentOrTestingEnvironmentForTestingEnvironmentHasFluentInterface() + public function testEnsureDevelopmentOrTestingEnvironmentForTestingEnvironmentHasFluentInterface() { - static::assertSame($this->subject, $this->subject->ensureDevelopmentOrTestingEnvironment()); + self::assertSame($this->subject, $this->subject->ensureDevelopmentOrTestingEnvironment()); } - /** - * @test - */ - public function getApplicationRootReturnsCoreApplicationRoot() + public function testGetApplicationRootReturnsCoreApplicationRoot() { - static::assertSame(dirname(__DIR__, 3), $this->subject->getApplicationRoot()); + self::assertSame(dirname(__DIR__, 3), $this->subject->getApplicationRoot()); } } diff --git a/tests/Integration/Domain/Repository/Fixtures/Administrator.csv b/tests/Integration/Domain/Repository/Fixtures/Administrator.csv index bacb62f4..d1bc43af 100644 --- a/tests/Integration/Domain/Repository/Fixtures/Administrator.csv +++ b/tests/Integration/Domain/Repository/Fixtures/Administrator.csv @@ -2,3 +2,4 @@ id,loginname,email,created,modified,password,passwordchanged,disabled,superuser 1,"john.doe","john@example.com","2017-06-22 15:01:17","2017-06-23 19:50:43","1491a3c7e7b23b9a6393323babbb095dee0d7d81b2199617b487bd0fb5236f3c","2017-06-28",0,1 2,"max.doe","john@example.com","2017-06-22 15:01:17","2017-06-23 19:50:43","1491a3c7e7b23b9a6393323babbb095dee0d7d81b2199617b487bd0fb5236f3c","2017-06-28",0,0 3,"disabled.admin","disabled.admin@example.com","2017-06-22 15:01:17","2017-06-23 19:50:43","1491a3c7e7b23b9a6393323babbb095dee0d7d81b2199617b487bd0fb5236f3c","2017-06-28",1,1 +999,"last.admin","last.admin@example.com","2017-06-22 15:01:17","2017-06-23 19:50:43","1491a3c7e7b23b9a6393323babbb095dee0d7d81b2199617b487bd0fb5236f3c","2017-06-28",1,1 diff --git a/tests/Integration/Domain/Repository/Fixtures/AdministratorFixture.php b/tests/Integration/Domain/Repository/Fixtures/AdministratorFixture.php new file mode 100644 index 00000000..30905f29 --- /dev/null +++ b/tests/Integration/Domain/Repository/Fixtures/AdministratorFixture.php @@ -0,0 +1,54 @@ +setSubjectId($admin, (int)$row['id']); + $admin->setLoginName($row['loginname']); + $admin->setEmailAddress($row['email']); + $admin->setPasswordHash($row['password']); + $admin->setDisabled((bool) $row['disabled']); + $admin->setSuperUser((bool) $row['superuser']); + + $manager->persist($admin); + $this->setSubjectProperty($admin, 'creationDate', new DateTime($row['created'])); + $this->setSubjectProperty($admin, 'passwordChangeDate', new DateTime($row['passwordchanged'])); + } while (true); + + fclose($handle); + } +} diff --git a/tests/Integration/Domain/Repository/Fixtures/AdministratorTokenWithAdministratorFixture.php b/tests/Integration/Domain/Repository/Fixtures/AdministratorTokenWithAdministratorFixture.php new file mode 100644 index 00000000..1d1ac74c --- /dev/null +++ b/tests/Integration/Domain/Repository/Fixtures/AdministratorTokenWithAdministratorFixture.php @@ -0,0 +1,59 @@ +getRepository(Administrator::class); + + do { + $data = fgetcsv($handle); + if ($data === false) { + break; + } + $row = array_combine($headers, $data); + + $admin = $adminRepository->find($row['adminid']); + if ($admin === null) { + $admin = new Administrator(); + $this->setSubjectId($admin, (int)$row['adminid']); + $manager->persist($admin); + } + + $adminToken = new AdministratorToken(); + $this->setSubjectId($adminToken, (int)$row['id']); + $adminToken->setKey($row['value']); + $this->setSubjectProperty($adminToken, 'expiry', new DateTime($row['expires'])); + $this->setSubjectProperty($adminToken, 'creationDate', (bool) $row['entered']); + $adminToken->setAdministrator($admin); + $manager->persist($adminToken); + } while (true); + + fclose($handle); + } +} diff --git a/tests/Integration/Domain/Repository/Fixtures/DetachedAdministratorTokenFixture.php b/tests/Integration/Domain/Repository/Fixtures/DetachedAdministratorTokenFixture.php new file mode 100644 index 00000000..15f5d2a7 --- /dev/null +++ b/tests/Integration/Domain/Repository/Fixtures/DetachedAdministratorTokenFixture.php @@ -0,0 +1,51 @@ +setSubjectId($adminToken, (int)$row['id']); + $adminToken->setKey($row['value']); + + $manager->persist($adminToken); + + $this->setSubjectProperty($adminToken, 'expiry', new DateTime($row['expires'])); + $this->setSubjectProperty($adminToken, 'creationDate', $row['entered']); + } while (true); + + fclose($handle); + } +} diff --git a/tests/Integration/Domain/Repository/Fixtures/Subscriber.csv b/tests/Integration/Domain/Repository/Fixtures/Subscriber.csv index 222f3644..36137259 100644 --- a/tests/Integration/Domain/Repository/Fixtures/Subscriber.csv +++ b/tests/Integration/Domain/Repository/Fixtures/Subscriber.csv @@ -1,4 +1,4 @@ -id,entered,modified,email,confirmed,blacklisted,bouncecount,uniqid,htmlemail,disabled,extradata +id,entered,modified,email,confirmed,blacklisted,bouncecount,uniqueid,htmlemail,disabled,extradata 1,"2016-07-22 15:01:17","2016-08-23 19:50:43","oliver@example.com",1,1,17,"95feb7fe7e06e6c11ca8d0c48cb46e89",1,1,"This is one of our favourite subscribers." 2,"2016-08-22 15:01:17","2017-08-23 19:50:43","sam@example.com",1,1,17,"95feb7fe7e06e6c11ca8d0c48cb46e81",1,0,"more extra" 3,"2016-08-22 15:01:17","2017-08-23 19:50:43","elena@example.com",1,1,17,"95feb7fe7e06e6c11ca8d0c48cb46e84",1,0,"this is a special subscriber" diff --git a/tests/Integration/Domain/Repository/Fixtures/SubscriberFixture.php b/tests/Integration/Domain/Repository/Fixtures/SubscriberFixture.php new file mode 100644 index 00000000..9a4ce782 --- /dev/null +++ b/tests/Integration/Domain/Repository/Fixtures/SubscriberFixture.php @@ -0,0 +1,60 @@ +setSubjectId($subscriber, (int)$row['id']); + + $subscriber->setEmail($row['email']); + $subscriber->setConfirmed((bool) $row['confirmed']); + $subscriber->setBlacklisted((bool) $row['blacklisted']); + $subscriber->setBounceCount((int) $row['bouncecount']); + $subscriber->setHtmlEmail((bool) $row['htmlemail']); + $subscriber->setDisabled((bool) $row['disabled']); + $subscriber->setExtraData($row['extradata']); + + $manager->persist($subscriber); + // avoid pre-persist + $subscriber->setUniqueId($row['uniqueid']); + $this->setSubjectProperty($subscriber, 'creationDate', new DateTime($row['entered'])); + $this->setSubjectProperty($subscriber, 'modificationDate', new DateTime($row['modified'])); + } while (true); + + fclose($handle); + } +} diff --git a/tests/Integration/Domain/Repository/Fixtures/SubscriberListFixture.php b/tests/Integration/Domain/Repository/Fixtures/SubscriberListFixture.php new file mode 100644 index 00000000..0b8aff88 --- /dev/null +++ b/tests/Integration/Domain/Repository/Fixtures/SubscriberListFixture.php @@ -0,0 +1,66 @@ +getRepository(Administrator::class); + + do { + $data = fgetcsv($handle); + if ($data === false) { + break; + } + $row = array_combine($headers, $data); + + $admin = $adminRepository->find($row['owner']); + if ($admin === null) { + $admin = new Administrator(); + $this->setSubjectId($admin, (int)$row['owner']); + $manager->persist($admin); + } + + $subscriberList = new SubscriberList(); + $this->setSubjectId($subscriberList, (int)$row['id']); + $subscriberList->setName($row['name']); + $subscriberList->setDescription($row['description']); + $this->setSubjectProperty($subscriberList, 'creationDate', new DateTime($row['entered'])); + $this->setSubjectProperty($subscriberList, 'modificationDate', new DateTime($row['modified'])); + $subscriberList->setListPosition((int)$row['listorder']); + $subscriberList->setSubjectPrefix($row['prefix']); + $subscriberList->setPublic((bool) $row['active']); + $subscriberList->setCategory($row['category']); + $subscriberList->setOwner($admin); + + $manager->persist($subscriberList); + } while (true); + + fclose($handle); + } +} diff --git a/tests/Integration/Domain/Repository/Fixtures/SubscriptionFixture.php b/tests/Integration/Domain/Repository/Fixtures/SubscriptionFixture.php new file mode 100644 index 00000000..35cd792b --- /dev/null +++ b/tests/Integration/Domain/Repository/Fixtures/SubscriptionFixture.php @@ -0,0 +1,60 @@ +getRepository(Subscriber::class); + $subscriberListRepository = $manager->getRepository(SubscriberList::class); + + $headers = fgetcsv($handle); + + do { + $data = fgetcsv($handle); + if ($data === false) { + break; + } + $row = array_combine($headers, $data); + + $subscriber = $subscriberRepository->find((int)$row['userid']); + $subscriberList = $subscriberListRepository->find((int)$row['listid']); + + $subscription = new Subscription(); + $subscriberList->addSubscription($subscription); + $subscriber->addSubscription($subscription); + + $manager->persist($subscription); + + $this->setSubjectProperty($subscription, 'creationDate', new DateTime($row['entered'])); + $this->setSubjectProperty($subscription, 'modificationDate', new DateTime($row['modified'])); + } while (true); + + fclose($handle); + } +} diff --git a/tests/Integration/Domain/Repository/Identity/AdministratorRepositoryTest.php b/tests/Integration/Domain/Repository/Identity/AdministratorRepositoryTest.php index 9ae477a3..2f74bcf3 100644 --- a/tests/Integration/Domain/Repository/Identity/AdministratorRepositoryTest.php +++ b/tests/Integration/Domain/Repository/Identity/AdministratorRepositoryTest.php @@ -1,160 +1,143 @@ */ -class AdministratorRepositoryTest extends TestCase +class AdministratorRepositoryTest extends KernelTestCase { use DatabaseTestTrait; - use SimilarDatesAssertionTrait; + use ModelTestTrait; - /** - * @var string - */ - const TABLE_NAME = 'phplist_admin'; + private ?AdministratorRepository $repository = null; - /** - * @var AdministratorRepository - */ - private $subject = null; - - protected function setUp() + protected function setUp(): void { - $this->setUpDatabaseTest(); - - $this->subject = $this->container->get(AdministratorRepository::class); + parent::setUp(); + $this->loadSchema(); + $this->repository = self::getContainer()->get(AdministratorRepository::class); + $this->loadFixtures([AdministratorFixture::class]); } - /** - * @test - */ - public function findReadsModelFromDatabase() + protected function tearDown(): void { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Administrator.csv'); - $this->applyDatabaseChanges(); - - $id = 1; - $loginName = 'john.doe'; - $emailAddress = 'john@example.com'; - $creationDate = new \DateTime('2017-06-22 15:01:17'); - $modificationDate = new \DateTime('2017-06-23 19:50:43'); - $passwordHash = '1491a3c7e7b23b9a6393323babbb095dee0d7d81b2199617b487bd0fb5236f3c'; - $passwordChangeDate = new \DateTime('2017-06-28'); - - /** @var Administrator $actualModel */ - $actualModel = $this->subject->find($id); - - static::assertSame($id, $actualModel->getId()); - static::assertSame($loginName, $actualModel->getLoginName()); - static::assertSame($emailAddress, $actualModel->getEmailAddress()); - static::assertEquals($creationDate, $actualModel->getCreationDate()); - static::assertEquals($modificationDate, $actualModel->getModificationDate()); - static::assertSame($passwordHash, $actualModel->getPasswordHash()); - static::assertEquals($passwordChangeDate, $actualModel->getPasswordChangeDate()); - static::assertFalse($actualModel->isDisabled()); + $schemaTool = new SchemaTool($this->entityManager); + $schemaTool->dropDatabase(); + parent::tearDown(); } - /** - * @test - */ - public function creationDateOfExistingModelStaysUnchangedOnUpdate() + public function testFindReadsModelFromDatabase(): void { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Administrator.csv'); - $this->applyDatabaseChanges(); + /** @var Administrator $actual */ + $actual = $this->repository->find(1); + + $this->assertNotNull($actual); + $this->assertFalse($actual->isDisabled()); + $this->assertTrue($actual->isSuperUser()); + $this->assertSame($actual->getLoginName(), $actual->getLoginName()); + $this->assertEqualsWithDelta( + (new DateTime())->getTimestamp(), + $actual->getModificationDate()->getTimestamp(), + 1 + ); + $this->assertSame('john@example.com', $actual->getEmailAddress()); + $this->assertSame( + '1491a3c7e7b23b9a6393323babbb095dee0d7d81b2199617b487bd0fb5236f3c', + $actual->getPasswordHash() + ); + $this->assertEquals(new DateTime('2017-06-22 15:01:17'), $actual->getCreationDate()); + $this->assertEquals(new DateTime('2017-06-28'), $actual->getPasswordChangeDate()); + } + public function testCreationDateOfExistingModelStaysUnchangedOnUpdate(): void + { $id = 1; - /** @var Administrator $model */ - $model = $this->subject->find($id); - $creationDate = $model->getCreationDate(); - + $model = $this->repository->find($id); + $this->assertNotNull($model); + $originalCreationDate = $model->getCreationDate(); $model->setLoginName('mel'); + $this->entityManager->flush(); - static::assertSame($creationDate, $model->getCreationDate()); + $this->assertSame($originalCreationDate, $model->getCreationDate()); } - /** - * @test - */ - public function modificationDateOfExistingModelGetsUpdatedOnUpdate() + public function testModificationDateOfExistingModelGetsUpdatedOnUpdate(): void { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Administrator.csv'); - $this->applyDatabaseChanges(); - $id = 1; - /** @var Administrator $model */ - $model = $this->subject->find($id); - $expectedModificationDate = new \DateTime(); + $model = $this->repository->find($id); + $this->assertNotNull($model); $model->setLoginName('mel'); $this->entityManager->flush(); - static::assertSimilarDates($expectedModificationDate, $model->getModificationDate()); + $expectedModificationDate = new DateTime(); + $this->assertEqualsWithDelta($expectedModificationDate, $model->getModificationDate(), 5); } - /** - * @test - */ - public function creationDateOfNewModelIsSetToNowOnPersist() + public function testCreationDateOfNewModelIsSetToNowOnPersist() { - $this->touchDatabaseTable(static::TABLE_NAME); - $model = new Administrator(); - $expectedCreationDate = new \DateTime(); $this->entityManager->persist($model); + $this->entityManager->flush(); - static::assertSimilarDates($expectedCreationDate, $model->getCreationDate()); + $expectedCreationDate = new DateTime(); + $this->assertEqualsWithDelta($expectedCreationDate, $model->getCreationDate(), 1); } - /** - * @test - */ - public function modificationDateOfNewModelIsSetToNowOnPersist() + public function testModificationDateOfNewModelIsSetToNowOnPersist() { - $this->touchDatabaseTable(static::TABLE_NAME); - $model = new Administrator(); - $expectedModificationDate = new \DateTime(); $this->entityManager->persist($model); + $this->entityManager->flush(); - static::assertSimilarDates($expectedModificationDate, $model->getModificationDate()); + $expectedCreationDate = new DateTime(); + $this->assertEqualsWithDelta($expectedCreationDate, $model->getModificationDate(), 1); } /** - * @test + * Tests that findOneByLoginCredentials returns null for incorrect credentials. + * + * @dataProvider incorrectLoginCredentialsDataProvider */ - public function findOneByLoginCredentialsForMatchingCredentialsReturnsModel() - { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Administrator.csv'); - $this->applyDatabaseChanges(); + public function testFindOneByLoginCredentialsForNonMatchingCredentialsReturnsNull( + string $loginName, + string $password + ): void { + $result = $this->repository->findOneByLoginCredentials($loginName, $password); + + $this->assertNull($result); + } + public function testFindOneByLoginCredentialsForMatchingCredentialsReturnsModel() + { $id = 1; $loginName = 'john.doe'; $password = 'Bazinga!'; - $result = $this->subject->findOneByLoginCredentials($loginName, $password); + $result = $this->repository->findOneByLoginCredentials($loginName, $password); - static::assertInstanceOf(Administrator::class, $result); - static::assertSame($id, $result->getId()); + self::assertInstanceOf(Administrator::class, $result); + self::assertSame($id, $result->getId()); } - /** - * @return string[][] - */ - public function incorrectLoginCredentialsDataProvider(): array + public static function incorrectLoginCredentialsDataProvider(): array { $loginName = 'john.doe'; $password = 'Bazinga!'; @@ -162,67 +145,39 @@ public function incorrectLoginCredentialsDataProvider(): array return [ 'all empty' => ['', ''], 'matching login name, empty password' => [$loginName, ''], - 'matching login name, incorrect password' => [$loginName, 'The cake is a lie.'], + 'matching login name, incorrect password' => [$loginName, 'wrong-password'], 'empty login name, correct password' => ['', $password], - 'incorrect name, correct password' => ['jane.doe', $password], + 'incorrect login name, correct password' => ['jane.doe', $password], ]; } - /** - * @test - */ - public function findOneByLoginCredentialsIgnoresNonSuperUser() + public function testFindOneByLoginCredentialsIgnoresNonSuperUser() { $loginName = 'max.doe'; $password = 'Bazinga!'; - $result = $this->subject->findOneByLoginCredentials($loginName, $password); + $result = $this->repository->findOneByLoginCredentials($loginName, $password); - static::assertNull($result); + self::assertNull($result); } - /** - * @test - * @param string $loginName - * @param string $password - * @dataProvider incorrectLoginCredentialsDataProvider - */ - public function findOneByLoginCredentialsForNonMatchingCredentialsReturnsNull(string $loginName, string $password) - { - $result = $this->subject->findOneByLoginCredentials($loginName, $password); - - static::assertNull($result); - } - - /** - * @test - */ - public function savePersistsAndFlushesModel() + public function testSavePersistsAndFlushesModel(): void { - $this->touchDatabaseTable(static::TABLE_NAME); - $model = new Administrator(); - $this->subject->save($model); + $this->repository->save($model); - static::assertSame($model, $this->subject->find($model->getId())); + $this->assertSame($model, $this->repository->find($model->getId())); } - /** - * @test - */ - public function removeRemovesModel() + public function testRemoveRemovesModel(): void { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Administrator.csv'); - $this->applyDatabaseChanges(); - - /** @var Administrator[] $allModels */ - $allModels = $this->subject->findAll(); - $numberOfModelsBeforeRemove = count($allModels); - $firstModel = $allModels[0]; + $allModels = $this->repository->findAll(); + $this->assertNotEmpty($allModels); - $this->subject->remove($firstModel); + $model = $allModels[0]; + $this->repository->remove($model); - $numberOfModelsAfterRemove = count($this->subject->findAll()); - static::assertSame(1, $numberOfModelsBeforeRemove - $numberOfModelsAfterRemove); + $remainingModels = $this->repository->findAll(); + $this->assertCount(count($allModels) - 1, $remainingModels); } } diff --git a/tests/Integration/Domain/Repository/Identity/AdministratorTokenRepositoryTest.php b/tests/Integration/Domain/Repository/Identity/AdministratorTokenRepositoryTest.php index 11ead1ae..e6b9ba35 100644 --- a/tests/Integration/Domain/Repository/Identity/AdministratorTokenRepositoryTest.php +++ b/tests/Integration/Domain/Repository/Identity/AdministratorTokenRepositoryTest.php @@ -1,280 +1,206 @@ */ -class AdministratorTokenRepositoryTest extends TestCase +class AdministratorTokenRepositoryTest extends WebTestCase { use DatabaseTestTrait; use SimilarDatesAssertionTrait; - /** - * @var string - */ - const TABLE_NAME = 'phplist_admintoken'; - - /** - * @var string - */ - const ADMINISTRATOR_TABLE_NAME = 'phplist_admin'; + private ?AdministratorTokenRepository $repository; - /** - * @var AdministratorTokenRepository - */ - private $subject = null; - - protected function setUp() + protected function setUp(): void { - $this->setUpDatabaseTest(); + parent::setUp(); + $this->loadSchema(); + $this->repository = self::getContainer()->get(AdministratorTokenRepository::class); + } - $this->subject = $this->container->get(AdministratorTokenRepository::class); + protected function tearDown(): void + { + $schemaTool = new SchemaTool($this->entityManager); + $schemaTool->dropDatabase(); + parent::tearDown(); } - /** - * @test - */ - public function findReadsModelFromDatabase() + public function testFindReadsModelFromDatabase() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/DetachedAdministratorTokens.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([DetachedAdministratorTokenFixture::class]); $id = 1; - $creationDate = new \DateTime('2017-12-06 17:41:40+0000'); - $expiry = new \DateTime('2017-06-22 16:43:29'); + $creationDate = new DateTime('2017-12-06 17:41:40'); + $expiry = new DateTime('2017-06-22 16:43:29'); $key = 'cfdf64eecbbf336628b0f3071adba762'; /** @var AdministratorToken $model */ - $model = $this->subject->find($id); + $model = $this->repository->find($id); - static::assertInstanceOf(AdministratorToken::class, $model); - static::assertSame($id, $model->getId()); - static::assertEquals($creationDate, $model->getCreationDate()); - static::assertEquals($expiry, $model->getExpiry()); - static::assertSame($key, $model->getKey()); + self::assertInstanceOf(AdministratorToken::class, $model); + self::assertSame($id, $model->getId()); + self::assertEqualsWithDelta($creationDate, $model->getCreationDate(), 1); + self::assertEquals($expiry, $model->getExpiry()); + self::assertSame($key, $model->getKey()); } - /** - * @test - */ - public function createsAdministratorAssociationAsProxy() - { - $this->getDataSet()->addTable(static::ADMINISTRATOR_TABLE_NAME, __DIR__ . '/../Fixtures/Administrator.csv'); - $this->getDataSet()->addTable( - static::TABLE_NAME, - __DIR__ . '/../Fixtures/AdministratorTokenWithAdministrator.csv' - ); - $this->applyDatabaseChanges(); - - $tokenId = 1; - $administratorId = 1; - /** @var AdministratorToken $model */ - $model = $this->subject->find($tokenId); - $administrator = $model->getAdministrator(); - - static::assertInstanceOf(Administrator::class, $administrator); - static::assertInstanceOf(Proxy::class, $administrator); - static::assertSame($administratorId, $administrator->getId()); - } - - /** - * @test - */ - public function creationDateOfExistingModelStaysUnchangedOnUpdate() + public function testCreationDateOfExistingModelStaysUnchangedOnUpdate() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/DetachedAdministratorTokens.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([DetachedAdministratorTokenFixture::class]); $id = 1; /** @var AdministratorToken $model */ - $model = $this->subject->find($id); + $model = $this->repository->find($id); $creationDate = $model->getCreationDate(); $model->setKey('asdfasd'); $this->entityManager->flush(); - static::assertEquals($creationDate, $model->getCreationDate()); + self::assertEquals($creationDate, $model->getCreationDate()); } - /** - * @test - */ - public function creationDateOfNewModelIsSetToNowOnPersist() + public function testCreationDateOfNewModelIsSetToNowOnPersist() { - $this->touchDatabaseTable(static::TABLE_NAME); - $model = new Administrator(); - $expectedCreationDate = new \DateTime(); + $expectedCreationDate = new DateTime(); $this->entityManager->persist($model); - static::assertSimilarDates($expectedCreationDate, $model->getCreationDate()); + self::assertSimilarDates($expectedCreationDate, $model->getCreationDate()); } - /** - * @test - */ - public function findOneUnexpiredByKeyFindsUnexpiredTokenWithMatchingKey() + public function testFindOneUnexpiredByKeyFindsUnexpiredTokenWithMatchingKey() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/DetachedAdministratorTokens.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([DetachedAdministratorTokenFixture::class]); $id = 2; $key = '8321b19193d80ce5e1b7cd8742266a5f'; /** @var AdministratorToken $model */ - $model = $this->subject->findOneUnexpiredByKey($key); + $model = $this->repository->findOneUnexpiredByKey($key); - static::assertInstanceOf(AdministratorToken::class, $model); - static::assertSame($id, $model->getId()); + self::assertInstanceOf(AdministratorToken::class, $model); + self::assertSame($id, $model->getId()); } - /** - * @test - */ - public function findOneUnexpiredByKeyNotFindsExpiredTokenWithMatchingKey() + public function testFindOneUnexpiredByKeyNotFindsExpiredTokenWithMatchingKey() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/DetachedAdministratorTokens.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([DetachedAdministratorTokenFixture::class]); $key = 'cfdf64eecbbf336628b0f3071adba762'; - $model = $this->subject->findOneUnexpiredByKey($key); + $model = $this->repository->findOneUnexpiredByKey($key); - static::assertNull($model); + self::assertNull($model); } - /** - * @test - */ - public function findOneUnexpiredByKeyNotFindsUnexpiredTokenWithNonMatchingKey() + public function testFindOneUnexpiredByKeyNotFindsUnexpiredTokenWithNonMatchingKey() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/DetachedAdministratorTokens.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([DetachedAdministratorTokenFixture::class]); $key = '03e7a64fb29115ba7581092c342299df'; - $model = $this->subject->findOneUnexpiredByKey($key); + $model = $this->repository->findOneUnexpiredByKey($key); - static::assertNull($model); + self::assertNull($model); } - /** - * @test - */ - public function removeExpiredRemovesExpiredToken() + public function testRemoveExpiredRemovesExpiredToken() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/DetachedAdministratorTokens.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([DetachedAdministratorTokenFixture::class]); $idOfExpiredToken = 1; - $this->subject->removeExpired(); + $this->repository->removeExpired(); - $token = $this->subject->find($idOfExpiredToken); - static::assertNull($token); + $token = $this->repository->find($idOfExpiredToken); + self::assertNull($token); } - /** - * @test - */ - public function removeExpiredKeepsUnexpiredToken() + public function testRemoveExpiredKeepsUnexpiredToken() { $this->assertNotYear2037Yet(); - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/DetachedAdministratorTokens.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([DetachedAdministratorTokenFixture::class]); $idOfUnexpiredToken = 2; - $this->subject->removeExpired(); + $this->repository->removeExpired(); - $token = $this->subject->find($idOfUnexpiredToken); - static::assertNotNull($token); + $token = $this->repository->find($idOfUnexpiredToken); + self::assertNotNull($token); } /** * Asserts that it's not year 2037 yet (which is the year the "not expired" token in the fixture * data set expires). - * - * @return void */ - private function assertNotYear2037Yet() + private function assertNotYear2037Yet(): void { $currentYear = (int)date('Y'); if ($currentYear >= 2037) { - static::markTestIncomplete('The tests token has an expiry in the year 2037. Please update this test.'); + self::markTestIncomplete('The tests token has an expiry in the year 2037. Please update this test.'); } } - /** - * @test - */ - public function removeExpiredForNoExpiredTokensReturnsZero() + public function testRemoveExpiredForNoExpiredTokensReturnsZero() { - static::assertSame(0, $this->subject->removeExpired()); + self::assertSame(0, $this->repository->removeExpired()); } - /** - * @test - */ - public function removeExpiredForOneExpiredTokenReturnsOne() + public function testRemoveExpiredForOneExpiredTokenReturnsOne() { $this->assertNotYear2037Yet(); - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/DetachedAdministratorTokens.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([DetachedAdministratorTokenFixture::class]); - static::assertSame(1, $this->subject->removeExpired()); + self::assertSame(1, $this->repository->removeExpired()); } - /** - * @test - */ - public function savePersistsAndFlushesModel() + public function testSavePersistsAndFlushesModel() { - $this->touchDatabaseTable(static::TABLE_NAME); - $this->getDataSet()->addTable(static::ADMINISTRATOR_TABLE_NAME, __DIR__ . '/../Fixtures/Administrator.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([AdministratorFixture::class]); - $administratorRepository = $this->container->get(AdministratorRepository::class); + $administratorRepository = $this->getContainer()->get(AdministratorRepository::class); /** @var Administrator $administrator */ $administrator = $administratorRepository->find(1); $model = new AdministratorToken(); $model->setAdministrator($administrator); - $this->subject->save($model); + $this->repository->save($model); - static::assertSame($model, $this->subject->find($model->getId())); + self::assertSame($model, $this->repository->find($model->getId())); } - /** - * @test - */ - public function removeRemovesModel() + public function testRemoveRemovesModel() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/DetachedAdministratorTokens.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([DetachedAdministratorTokenFixture::class]); /** @var AdministratorToken[] $allModels */ - $allModels = $this->subject->findAll(); + $allModels = $this->repository->findAll(); $numberOfModelsBeforeRemove = count($allModels); $firstModel = $allModels[0]; - $this->subject->remove($firstModel); + $this->repository->remove($firstModel); - $numberOfModelsAfterRemove = count($this->subject->findAll()); - static::assertSame(1, $numberOfModelsBeforeRemove - $numberOfModelsAfterRemove); + $numberOfModelsAfterRemove = count($this->repository->findAll()); + self::assertSame(1, $numberOfModelsBeforeRemove - $numberOfModelsAfterRemove); } } diff --git a/tests/Integration/Domain/Repository/Messaging/SubscriberListRepositoryTest.php b/tests/Integration/Domain/Repository/Messaging/SubscriberListRepositoryTest.php index f038bf4f..e53d725b 100644 --- a/tests/Integration/Domain/Repository/Messaging/SubscriberListRepositoryTest.php +++ b/tests/Integration/Domain/Repository/Messaging/SubscriberListRepositoryTest.php @@ -1,11 +1,14 @@ */ -class SubscriberListRepositoryTest extends TestCase +class SubscriberListRepositoryTest extends KernelTestCase { use DatabaseTestTrait; use SimilarDatesAssertionTrait; - /** - * @var string - */ - const TABLE_NAME = 'phplist_list'; - - /** - * @var string - */ - const ADMINISTRATOR_TABLE_NAME = 'phplist_admin'; - - /** - * @var string - */ - const SUBSCRIPTION_TABLE_NAME = 'phplist_listuser'; - - /** - * @var string - */ - const SUBSCRIBER_TABLE_NAME = 'phplist_user_user'; - - /** - * @var SubscriberListRepository - */ - private $subject = null; - - /** - * @var AdministratorRepository - */ - private $administratorRepository = null; - - /** - * @var SubscriberRepository - */ - private $subscriberRepository = null; - - /** - * @var SubscriptionRepository - */ - private $subscriptionRepository = null; - - protected function setUp() + private SubscriberListRepository $subscriberListRepository; + private AdministratorRepository $administratorRepository; + private SubscriberRepository $subscriberRepository; + private SubscriptionRepository $subscriptionRepository; + + protected function setUp(): void { - $this->setUpDatabaseTest(); + parent::setUp(); + $this->loadSchema(); - $this->subject = $this->container->get(SubscriberListRepository::class); - $this->administratorRepository = $this->container->get(AdministratorRepository::class); - $this->subscriberRepository = $this->container->get(SubscriberRepository::class); - $this->subscriptionRepository = $this->container->get(SubscriptionRepository::class); + $this->subscriberListRepository = self::getContainer()->get(SubscriberListRepository::class); + $this->administratorRepository = self::getContainer()->get(AdministratorRepository::class); + $this->subscriberRepository = self::getContainer()->get(SubscriberRepository::class); + $this->subscriptionRepository = self::getContainer()->get(SubscriptionRepository::class); + } + + protected function tearDown(): void + { + $schemaTool = new SchemaTool($this->entityManager); + $schemaTool->dropDatabase(); + parent::tearDown(); } - /** - * @test - */ - public function findReadsModelFromDatabase() + public function testFindReadsModelFromDatabase() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberListFixture::class]); $id = 1; - $creationDate = new \DateTime('2016-06-22 15:01:17'); - $modificationDate = new \DateTime('2016-06-23 19:50:43'); + $creationDate = new DateTime(); + $modificationDate = new DateTime(); $name = 'News'; $description = 'News (and some fun stuff)'; $listPosition = 12; @@ -93,219 +69,147 @@ public function findReadsModelFromDatabase() $category = 'news'; /** @var SubscriberList $model */ - $model = $this->subject->find($id); - - static::assertSame($id, $model->getId()); - static::assertEquals($creationDate, $model->getCreationDate()); - static::assertEquals($modificationDate, $model->getModificationDate()); - static::assertSame($name, $model->getName()); - static::assertSame($description, $model->getDescription()); - static::assertSame($listPosition, $model->getListPosition()); - static::assertSame($subjectPrefix, $model->getSubjectPrefix()); - static::assertTrue($model->isPublic()); - static::assertSame($category, $model->getCategory()); - } - - /** - * @test - */ - public function createsOwnerAssociationAsProxy() - { - $this->getDataSet()->addTable(static::ADMINISTRATOR_TABLE_NAME, __DIR__ . '/../Fixtures/Administrator.csv'); - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->applyDatabaseChanges(); - - $subscriberListId = 1; - $ownerId = 1; - /** @var SubscriberList $model */ - $model = $this->subject->find($subscriberListId); - $owner = $model->getOwner(); - - static::assertInstanceOf(Administrator::class, $owner); - static::assertInstanceOf(Proxy::class, $owner); - static::assertSame($ownerId, $owner->getId()); + $model = $this->subscriberListRepository->find($id); + + self::assertSame($id, $model->getId()); + self::assertSimilarDates($creationDate, $model->getCreationDate()); + self::assertSimilarDates($modificationDate, $model->getModificationDate()); + self::assertSame($name, $model->getName()); + self::assertSame($description, $model->getDescription()); + self::assertSame($listPosition, $model->getListPosition()); + self::assertSame($subjectPrefix, $model->getSubjectPrefix()); + self::assertTrue($model->isPublic()); + self::assertSame($category, $model->getCategory()); } - /** - * @test - */ - public function creationDateOfNewModelIsSetToNowOnPersist() + public function testCreationDateOfNewModelIsSetToNowOnPersist() { - $this->touchDatabaseTable(static::TABLE_NAME); - $model = new SubscriberList(); - $expectedCreationDate = new \DateTime(); + $expectedCreationDate = new DateTime(); $this->entityManager->persist($model); - static::assertSimilarDates($expectedCreationDate, $model->getCreationDate()); + self::assertSimilarDates($expectedCreationDate, $model->getCreationDate()); } - /** - * @test - */ - public function modificationDateOfNewModelIsSetToNowOnPersist() + public function testModificationDateOfNewModelIsSetToNowOnPersist() { - $this->touchDatabaseTable(static::TABLE_NAME); - $model = new SubscriberList(); - $expectedModificationDate = new \DateTime(); + $expectedModificationDate = new DateTime(); $this->entityManager->persist($model); - static::assertSimilarDates($expectedModificationDate, $model->getModificationDate()); + self::assertSimilarDates($expectedModificationDate, $model->getModificationDate()); } - /** - * @test - */ - public function savePersistsAndFlushesModel() + public function testSavePersistsAndFlushesModel() { - $this->touchDatabaseTable(static::TABLE_NAME); - $model = new SubscriberList(); - $this->subject->save($model); + $this->subscriberListRepository->save($model); - static::assertSame($model, $this->subject->find($model->getId())); + self::assertSame($model, $this->subscriberListRepository->find($model->getId())); } - /** - * @test - */ - public function findByOwnerFindsSubscriberListWithTheGivenOwner() + public function testFindByOwnerFindsSubscriberListWithTheGivenOwner() { - $this->getDataSet()->addTable(static::ADMINISTRATOR_TABLE_NAME, __DIR__ . '/../Fixtures/Administrator.csv'); - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberListFixture::class, AdministratorFixture::class]); $owner = $this->administratorRepository->find(1); - $ownedList = $this->subject->find(1); + $ownedList = $this->subscriberListRepository->find(1); - $result = $this->subject->findByOwner($owner); + $result = $this->subscriberListRepository->findByOwner($owner); - static::assertContains($ownedList, $result); + self::assertContains($ownedList, $result); } - /** - * @test - */ - public function findByOwnerIgnoresSubscriberListWithOtherOwner() + public function testFindByOwnerIgnoresSubscriberListWithOtherOwner() { - $this->getDataSet()->addTable(static::ADMINISTRATOR_TABLE_NAME, __DIR__ . '/../Fixtures/Administrator.csv'); - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberListFixture::class, AdministratorFixture::class]); $owner = $this->administratorRepository->find(1); - $foreignList = $this->subject->find(2); + $foreignList = $this->subscriberListRepository->find(2); - $result = $this->subject->findByOwner($owner); + $result = $this->subscriberListRepository->findByOwner($owner); - static::assertNotContains($foreignList, $result); + self::assertNotContains($foreignList, $result); } - /** - * @test - */ - public function findByOwnerIgnoresSubscriberListFromOtherOwner() + public function testFindByOwnerIgnoresSubscriberListFromOtherOwner() { - $this->getDataSet()->addTable(static::ADMINISTRATOR_TABLE_NAME, __DIR__ . '/../Fixtures/Administrator.csv'); - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberListFixture::class]); $owner = $this->administratorRepository->find(1); - $unownedList = $this->subject->find(3); + $unownedList = $this->subscriberListRepository->find(3); - $result = $this->subject->findByOwner($owner); + $result = $this->subscriberListRepository->findByOwner($owner); - static::assertNotContains($unownedList, $result); + self::assertNotContains($unownedList, $result); } - /** - * @test - */ - public function findsAssociatedSubscriptions() + public function testFindsAssociatedSubscriptions() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->getDataSet()->addTable(static::SUBSCRIBER_TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->getDataSet()->addTable(static::SUBSCRIPTION_TABLE_NAME, __DIR__ . '/../Fixtures/Subscription.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberListFixture::class, SubscriberFixture::class, SubscriptionFixture::class]); $id = 2; - /** @var SubscriberList $model */ - $model = $this->subject->find($id); - $subscriptions = $model->getSubscriptions(); + $subscriber = $this->subscriberRepository->find($id); + /** @var Subscription[] $subscriptions */ + $subscriptions = $this->subscriptionRepository->findBySubscriberList($subscriber); - static::assertFalse($subscriptions->isEmpty()); - /** @var Subscription $firstSubscription */ - $firstSubscription = $subscriptions->first(); - static::assertInstanceOf(Subscription::class, $firstSubscription); + self::assertNotEmpty($subscriptions); + $firstSubscription = $subscriptions[0]; + self::assertInstanceOf(Subscription::class, $firstSubscription); $expectedSubscriberId = 1; - static::assertSame($expectedSubscriberId, $firstSubscription->getSubscriber()->getId()); + self::assertSame($expectedSubscriberId, $firstSubscription->getSubscriber()->getId()); } - /** - * @test - */ - public function findsAssociatedSubscribers() + public function testFindsAssociatedSubscribers() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->getDataSet()->addTable(static::SUBSCRIBER_TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->getDataSet()->addTable(static::SUBSCRIPTION_TABLE_NAME, __DIR__ . '/../Fixtures/Subscription.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberListFixture::class, SubscriberFixture::class, SubscriptionFixture::class]); $id = 2; - /** @var SubscriberList $model */ - $model = $this->subject->find($id); - $subscribers = $model->getSubscribers(); + /** @var Subscriber[] $subscribers */ + $subscribers = $this->subscriberRepository->getSubscribersBySubscribedListId($id); $expectedSubscriber = $this->subscriberRepository->find(1); $unexpectedSubscriber = $this->subscriberRepository->find(3); - static::assertTrue($subscribers->contains($expectedSubscriber)); - static::assertFalse($subscribers->contains($unexpectedSubscriber)); + self::assertTrue(in_array($expectedSubscriber, $subscribers, true)); + self::assertFalse(in_array($unexpectedSubscriber, $subscribers, true)); } - /** - * @test - */ - public function removeAlsoRemovesAssociatedSubscriptions() + public function testRemoveAlsoRemovesAssociatedSubscriptions() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->getDataSet()->addTable(static::SUBSCRIBER_TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->getDataSet()->addTable(static::SUBSCRIPTION_TABLE_NAME, __DIR__ . '/../Fixtures/Subscription.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberListFixture::class, SubscriberFixture::class, SubscriptionFixture::class]); $initialNumberOfSubscriptions = count($this->subscriptionRepository->findAll()); $id = 2; - /** @var SubscriberList $model */ - $model = $this->subject->find($id); + /** @var SubscriberList $subscriberList */ + $subscriberList = $this->subscriberListRepository->findWithSubscription($id); - $numberOfAssociatedSubscriptions = count($model->getSubscriptions()); - static::assertGreaterThan(0, $numberOfAssociatedSubscriptions); + $numberOfAssociatedSubscriptions = count($subscriberList->getSubscriptions()); + self::assertGreaterThan(0, $numberOfAssociatedSubscriptions); - $this->subject->remove($model); + $this->entityManager->remove($subscriberList); + $this->entityManager->flush(); $newNumberOfSubscriptions = count($this->subscriptionRepository->findAll()); + $numberOfRemovedSubscriptions = $initialNumberOfSubscriptions - $newNumberOfSubscriptions; - static::assertSame($numberOfAssociatedSubscriptions, $numberOfRemovedSubscriptions); + self::assertSame($numberOfAssociatedSubscriptions, $numberOfRemovedSubscriptions); } - /** - * @test - */ - public function removeRemovesModel() + public function testRemoveRemovesModel() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberListFixture::class]); /** @var SubscriberList[] $allModels */ - $allModels = $this->subject->findAll(); + $allModels = $this->subscriberListRepository->findAll(); $numberOfModelsBeforeRemove = count($allModels); $firstModel = $allModels[0]; - $this->subject->remove($firstModel); + $this->subscriberListRepository->remove($firstModel); - $numberOfModelsAfterRemove = count($this->subject->findAll()); - static::assertSame(1, $numberOfModelsBeforeRemove - $numberOfModelsAfterRemove); + $numberOfModelsAfterRemove = count($this->subscriberListRepository->findAll()); + self::assertSame(1, $numberOfModelsBeforeRemove - $numberOfModelsAfterRemove); } } diff --git a/tests/Integration/Domain/Repository/Subscription/SubscriberRepositoryTest.php b/tests/Integration/Domain/Repository/Subscription/SubscriberRepositoryTest.php index 77580d04..fc7b50f4 100644 --- a/tests/Integration/Domain/Repository/Subscription/SubscriberRepositoryTest.php +++ b/tests/Integration/Domain/Repository/Subscription/SubscriberRepositoryTest.php @@ -1,9 +1,15 @@ */ -class SubscriberRepositoryTest extends TestCase +class SubscriberRepositoryTest extends KernelTestCase { use DatabaseTestTrait; use SimilarDatesAssertionTrait; - /** - * @var string - */ - const TABLE_NAME = 'phplist_user_user'; - - /** - * @var string - */ - const ADMINISTRATOR_TABLE_NAME = 'phplist_admin'; - - /** - * @var string - */ - const SUBSCRIPTION_TABLE_NAME = 'phplist_listuser'; - - /** - * @var string - */ - const SUBSCRIBER_LIST_TABLE_NAME = 'phplist_list'; - - /** - * @var SubscriberRepository - */ - private $subject = null; + private ?SubscriberRepository $subscriberRepository = null; + private ?SubscriberListRepository $subscriberListRepository = null; + private ?SubscriptionRepository $subscriptionRepository = null; - /** - * @var SubscriberListRepository - */ - private $subscriberListRepository = null; + protected function setUp(): void + { + parent::setUp(); + $this->loadSchema(); - /** - * @var SubscriptionRepository - */ - private $subscriptionRepository = null; + $this->subscriberRepository = self::getContainer()->get(SubscriberRepository::class); + $this->subscriberListRepository = self::getContainer()->get(SubscriberListRepository::class); + $this->subscriptionRepository = self::getContainer()->get(SubscriptionRepository::class); + } - protected function setUp() + protected function tearDown(): void { - $this->setUpDatabaseTest(); - - $this->subject = $this->container->get(SubscriberRepository::class); - $this->subscriberListRepository = $this->container->get(SubscriberListRepository::class); - $this->subscriptionRepository = $this->container->get(SubscriptionRepository::class); + $schemaTool = new SchemaTool($this->entityManager); + $schemaTool->dropDatabase(); + parent::tearDown(); } - /** - * @test - */ - public function findReadsModelFromDatabase() + public function testFindReadsModelFromDatabase() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class]); $id = 1; - $creationDate = new \DateTime('2016-07-22 15:01:17'); - $modificationDate = new \DateTime('2016-08-23 19:50:43'); + $creationDate = new DateTime('2016-07-22 15:01:17'); + $modificationDate = new DateTime('2016-08-23 19:50:43'); $extraData = 'This is one of our favourite subscribers.'; /** @var Subscriber $model */ - $model = $this->subject->find($id); - - static::assertSame($id, $model->getId()); - static::assertEquals($creationDate, $model->getCreationDate()); - static::assertEquals($modificationDate, $model->getModificationDate()); - static::assertEquals('oliver@example.com', $model->getEmail()); - static::assertTrue($model->isConfirmed()); - static::assertTrue($model->isBlacklisted()); - static::assertSame(17, $model->getBounceCount()); - static::assertSame('95feb7fe7e06e6c11ca8d0c48cb46e89', $model->getUniqueId()); - static::assertTrue($model->hasHtmlEmail()); - static::assertTrue($model->isDisabled()); - static::assertSame($extraData, $model->getExtraData()); + $model = $this->subscriberRepository->find($id); + + self::assertSame($id, $model->getId()); + self::assertSimilarDates($creationDate, $model->getCreationDate()); + self::assertSimilarDates($modificationDate, $model->getModificationDate()); + self::assertEquals('oliver@example.com', $model->getEmail()); + self::assertTrue($model->isConfirmed()); + self::assertTrue($model->isBlacklisted()); + self::assertSame(17, $model->getBounceCount()); + self::assertSame('95feb7fe7e06e6c11ca8d0c48cb46e89', $model->getUniqueId()); + self::assertTrue($model->hasHtmlEmail()); + self::assertTrue($model->isDisabled()); + self::assertSame($extraData, $model->getExtraData()); } - /** - * @test - */ - public function creationDateOfNewModelIsSetToNowOnPersist() + public function testCreationDateOfNewModelIsSetToNowOnPersist() { - $this->touchDatabaseTable(static::TABLE_NAME); - $model = new Subscriber(); $model->setEmail('sam@example.com'); - $expectedCreationDate = new \DateTime(); + $expectedCreationDate = new DateTime(); $this->entityManager->persist($model); - static::assertSimilarDates($expectedCreationDate, $model->getCreationDate()); + self::assertSimilarDates($expectedCreationDate, $model->getCreationDate()); } - /** - * @test - */ - public function modificationDateOfNewModelIsSetToNowOnPersist() + public function testModificationDateOfNewModelIsSetToNowOnPersist() { - $this->touchDatabaseTable(static::TABLE_NAME); - $model = new Subscriber(); $model->setEmail('oliver@example.com'); - $expectedModificationDate = new \DateTime(); + $expectedModificationDate = new DateTime(); $this->entityManager->persist($model); - static::assertSimilarDates($expectedModificationDate, $model->getModificationDate()); + self::assertSimilarDates($expectedModificationDate, $model->getModificationDate()); } - /** - * @test - */ - public function savePersistsAndFlushesModel() + public function testSavePersistsAndFlushesModel() { - $this->touchDatabaseTable(static::TABLE_NAME); - $model = new Subscriber(); $model->setEmail('michiel@example.com'); - $this->subject->save($model); + $this->subscriberRepository->save($model); - static::assertSame($model, $this->subject->find($model->getId())); + self::assertSame($model, $this->subscriberRepository->find($model->getId())); } - /** - * @test - */ - public function emailMustBeUnique() + public function testEmailMustBeUnique() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class]); /** @var Subscriber $model */ - $model = $this->subject->find(1); + $model = $this->subscriberRepository->find(1); $otherModel = new Subscriber(); $otherModel->generateUniqueId(); @@ -159,22 +123,17 @@ public function emailMustBeUnique() $this->expectException(UniqueConstraintViolationException::class); - $this->subject->save($otherModel); + $this->subscriberRepository->save($otherModel); } - /** - * @test - */ - public function uniqueIdOfNewModelIsGeneratedOnPersist() + public function testUniqueIdOfNewModelIsGeneratedOnPersist() { - $this->touchDatabaseTable(static::TABLE_NAME); - $model = new Subscriber(); $model->setEmail('oliver@example.com'); $this->entityManager->persist($model); - static::assertRegExp('/^[0-9a-f]{32}$/', $model->getUniqueId()); + self::assertMatchesRegularExpression('/^[0-9a-f]{32}$/', $model->getUniqueId()); } /** @@ -182,137 +141,116 @@ public function uniqueIdOfNewModelIsGeneratedOnPersist() */ public function persistingExistingModelKeepsUniqueIdUnchanged() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class]); /** @var Subscriber $model */ - $model = $this->subject->find(1); + $model = $this->subscriberRepository->find(1); $oldUniqueId = $model->getUniqueId(); $model->setEmail('other@example.com'); $this->entityManager->persist($model); - static::assertSame($oldUniqueId, $model->getUniqueId()); + self::assertSame($oldUniqueId, $model->getUniqueId()); } - /** - * @test - */ - public function findOneByEmailFindsSubscriberWithMatchingEmail() + public function testFindOneByEmailFindsSubscriberWithMatchingEmail() { $email = 'oliver@example.com'; - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class]); /** @var Subscriber $model */ - $model = $this->subject->findOneByEmail($email); + $model = $this->subscriberRepository->findOneByEmail($email); - static::assertInstanceOf(Subscriber::class, $model); - static::assertSame($email, $model->getEmail()); + self::assertInstanceOf(Subscriber::class, $model); + self::assertSame($email, $model->getEmail()); } - /** - * @test - */ - public function findOneByEmailIgnoresSubscriberWithNonMatchingEmail() + public function testFindOneByEmailIgnoresSubscriberWithNonMatchingEmail() { $email = 'other@example.com'; - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class]); - $model = $this->subject->findOneByEmail($email); + $model = $this->subscriberRepository->findOneByEmail($email); - static::assertNull($model); + self::assertNull($model); } - /** - * @test - */ - public function findsAssociatedSubscriptions() + public function testFindsAssociatedSubscriptions() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->getDataSet()->addTable(static::SUBSCRIBER_LIST_TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->getDataSet()->addTable(static::SUBSCRIPTION_TABLE_NAME, __DIR__ . '/../Fixtures/Subscription.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([ + AdministratorFixture::class, + SubscriberFixture::class, + SubscriberListFixture::class, + SubscriptionFixture::class, + ]); $id = 1; - /** @var Subscriber $model */ - $model = $this->subject->find($id); + $model = $this->subscriberRepository->findSubscriberWithSubscriptions($id); $subscriptions = $model->getSubscriptions(); - static::assertFalse($subscriptions->isEmpty()); + self::assertFalse($subscriptions->isEmpty()); /** @var Subscription $firstSubscription */ $firstSubscription = $subscriptions->first(); - static::assertInstanceOf(Subscription::class, $firstSubscription); + self::assertInstanceOf(Subscription::class, $firstSubscription); $expectedSubscriberListId = 2; - static::assertSame($expectedSubscriberListId, $firstSubscription->getSubscriberList()->getId()); + self::assertSame($expectedSubscriberListId, $firstSubscription->getSubscriberList()->getId()); } - /** - * @test - */ - public function findsAssociatedSubscribedLists() + public function testFindsAssociatedSubscribedLists() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->getDataSet()->addTable(static::SUBSCRIBER_LIST_TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->getDataSet()->addTable(static::SUBSCRIPTION_TABLE_NAME, __DIR__ . '/../Fixtures/Subscription.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class, SubscriberListFixture::class, SubscriptionFixture::class]); $id = 1; /** @var Subscriber $model */ - $model = $this->subject->find($id); - $subscribedLists = $model->getSubscribedLists(); + $model = $this->subscriberRepository->findSubscriberWithSubscriptions($id); + $subscriberLists = new ArrayCollection(); + foreach ($model->getSubscriptions() as $subscription) { + $subscriberLists->add($subscription->getSubscriberList()); + } $expectedList = $this->subscriberListRepository->find(2); $unexpectedList = $this->subscriberListRepository->find(1); - static::assertTrue($subscribedLists->contains($expectedList)); - static::assertFalse($subscribedLists->contains($unexpectedList)); + self::assertTrue($subscriberLists->contains($expectedList)); + self::assertFalse($subscriberLists->contains($unexpectedList)); } - /** - * @test - */ - public function removeAlsoRemovesAssociatedSubscriptions() + public function testRemoveAlsoRemovesAssociatedSubscriptions() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->getDataSet()->addTable(static::SUBSCRIBER_LIST_TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->getDataSet()->addTable(static::SUBSCRIPTION_TABLE_NAME, __DIR__ . '/../Fixtures/Subscription.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class, SubscriberListFixture::class, SubscriptionFixture::class]); $initialNumberOfSubscriptions = count($this->subscriptionRepository->findAll()); $id = 2; /** @var Subscriber $model */ - $model = $this->subject->find($id); + $model = $this->subscriberRepository->findSubscriberWithSubscriptions($id); $numberOfAssociatedSubscriptions = count($model->getSubscriptions()); - static::assertGreaterThan(0, $numberOfAssociatedSubscriptions); + self::assertGreaterThan(0, $numberOfAssociatedSubscriptions); - $this->subject->remove($model); + $this->subscriberRepository->remove($model); $newNumberOfSubscriptions = count($this->subscriptionRepository->findAll()); $numberOfRemovedSubscriptions = $initialNumberOfSubscriptions - $newNumberOfSubscriptions; - static::assertSame($numberOfAssociatedSubscriptions, $numberOfRemovedSubscriptions); + self::assertSame($numberOfAssociatedSubscriptions, $numberOfRemovedSubscriptions); } /** * @test */ - public function removeRemovesModel() + public function testRemoveRemovesModel() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class]); /** @var Subscriber[] $allModels */ - $allModels = $this->subject->findAll(); + $allModels = $this->subscriberRepository->findAll(); $numberOfModelsBeforeRemove = count($allModels); $firstModel = $allModels[0]; - $this->subject->remove($firstModel); + $this->subscriberRepository->remove($firstModel); - $numberOfModelsAfterRemove = count($this->subject->findAll()); - static::assertSame(1, $numberOfModelsBeforeRemove - $numberOfModelsAfterRemove); + $numberOfModelsAfterRemove = count($this->subscriberRepository->findAll()); + self::assertSame(1, $numberOfModelsBeforeRemove - $numberOfModelsAfterRemove); } } diff --git a/tests/Integration/Domain/Repository/Subscription/SubscriptionRepositoryTest.php b/tests/Integration/Domain/Repository/Subscription/SubscriptionRepositoryTest.php index 383c7a4f..280c7dcc 100644 --- a/tests/Integration/Domain/Repository/Subscription/SubscriptionRepositoryTest.php +++ b/tests/Integration/Domain/Repository/Subscription/SubscriptionRepositoryTest.php @@ -1,9 +1,11 @@ */ -class SubscriptionRepositoryTest extends TestCase +class SubscriptionRepositoryTest extends KernelTestCase { use DatabaseTestTrait; use SimilarDatesAssertionTrait; - /** - * @var string - */ - const TABLE_NAME = 'phplist_listuser'; - - /** - * @var string - */ - const ADMINISTRATOR_TABLE_NAME = 'phplist_admin'; - - /** - * @var string - */ - const SUBSCRIBER_TABLE_NAME = 'phplist_user_user'; - - /** - * @var string - */ - const SUBSCRIBER_LIST_TABLE_NAME = 'phplist_list'; - - /** - * @var SubscriptionRepository - */ - private $subject = null; - - /** - * @var SubscriberRepository - */ - private $subscriberRepository = null; - - /** - * @var SubscriberListRepository - */ - private $subscriberListRepository = null; - - protected function setUp() + private ?SubscriptionRepository $subscriptionRepository = null; + private ?SubscriberRepository $subscriberRepository = null; + private ?SubscriberListRepository $subscriberListRepository = null; + + protected function setUp(): void { - $this->setUpDatabaseTest(); + parent::setUp(); + $this->loadSchema(); - $this->subject = $this->container->get(SubscriptionRepository::class); + $this->subscriptionRepository = self::getContainer()->get(SubscriptionRepository::class); + $this->subscriberRepository = self::getContainer()->get(SubscriberRepository::class); + $this->subscriberListRepository = self::getContainer()->get(SubscriberListRepository::class); + } - $this->subscriberRepository = $this->container->get(SubscriberRepository::class); - $this->subscriberListRepository = $this->container->get(SubscriberListRepository::class); + protected function tearDown(): void + { + $schemaTool = new SchemaTool($this->entityManager); + $schemaTool->dropDatabase(); + parent::tearDown(); } - /** - * @test - */ - public function findAllReadsModelsFromDatabase() + public function testFindAllReadsModelsFromDatabase() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscription.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class, SubscriberListFixture::class, SubscriptionFixture::class]); - $creationDate = new \DateTime('2016-07-22 15:01:17'); - $modificationDate = new \DateTime('2016-08-23 19:50:43'); + $creationDate = new DateTime('2016-07-22 15:01:17'); + $modificationDate = new DateTime('2016-08-23 19:50:43'); /** @var Subscription[] $result */ - $result = $this->subject->findAll(); + $result = $this->subscriptionRepository->findAll(); - static::assertNotEmpty($result); + self::assertNotEmpty($result); $model = $result[0]; - static::assertInstanceOf(Subscription::class, $model); - static::assertEquals($creationDate, $model->getCreationDate()); - static::assertEquals($modificationDate, $model->getModificationDate()); + self::assertInstanceOf(Subscription::class, $model); + self::assertEquals($creationDate, $model->getCreationDate()); + self::assertEquals($modificationDate, $model->getModificationDate()); } - /** - * @test - */ - public function createsSubscriberAssociationAsProxy() + public function testCreationDateOfNewModelIsSetToNowOnPersist() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscription.csv'); - $this->getDataSet()->addTable(static::SUBSCRIBER_TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->applyDatabaseChanges(); - - $subscriberId = 1; - /** @var Subscription $model */ - $model = $this->subject->findAll()[0]; - $subscriber = $model->getSubscriber(); - - static::assertInstanceOf(Subscriber::class, $subscriber); - static::assertInstanceOf(Proxy::class, $subscriber); - static::assertSame($subscriberId, $subscriber->getId()); - } - - /** - * @test - */ - public function createsSubscriberListAssociationAsProxy() - { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscription.csv'); - $this->getDataSet()->addTable(static::SUBSCRIBER_LIST_TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->applyDatabaseChanges(); - - $subscriberListId = 2; - /** @var Subscription $model */ - $model = $this->subject->findAll()[0]; - $subscriberList = $model->getSubscriberList(); - - static::assertInstanceOf(SubscriberList::class, $subscriberList); - static::assertInstanceOf(Proxy::class, $subscriberList); - static::assertSame($subscriberListId, $subscriberList->getId()); - } - - /** - * @test - */ - public function creationDateOfNewModelIsSetToNowOnPersist() - { - $this->getDataSet()->addTable(static::SUBSCRIBER_TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->getDataSet()->addTable(static::SUBSCRIBER_LIST_TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->touchDatabaseTable(static::TABLE_NAME); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class, SubscriberListFixture::class]); $model = new Subscription(); /** @var Subscriber $subscriber */ @@ -146,22 +79,16 @@ public function creationDateOfNewModelIsSetToNowOnPersist() /** @var SubscriberList $subscriberList */ $subscriberList = $this->subscriberListRepository->find(1); $model->setSubscriberList($subscriberList); - $expectedCreationDate = new \DateTime(); + $expectedCreationDate = new DateTime(); $this->entityManager->persist($model); - static::assertSimilarDates($expectedCreationDate, $model->getCreationDate()); + self::assertSimilarDates($expectedCreationDate, $model->getCreationDate()); } - /** - * @test - */ - public function modificationDateOfNewModelIsSetToNowOnPersist() + public function testModificationDateOfNewModelIsSetToNowOnPersist() { - $this->getDataSet()->addTable(static::SUBSCRIBER_TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->getDataSet()->addTable(static::SUBSCRIBER_LIST_TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->touchDatabaseTable(static::TABLE_NAME); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class, SubscriberListFixture::class]); $model = new Subscription(); /** @var Subscriber $subscriber */ @@ -170,63 +97,48 @@ public function modificationDateOfNewModelIsSetToNowOnPersist() /** @var SubscriberList $subscriberList */ $subscriberList = $this->subscriberListRepository->find(1); $model->setSubscriberList($subscriberList); - $expectedModificationDate = new \DateTime(); + $expectedModificationDate = new DateTime(); $this->entityManager->persist($model); - static::assertSimilarDates($expectedModificationDate, $model->getModificationDate()); + self::assertSimilarDates($expectedModificationDate, $model->getModificationDate()); } - /** - * @test - */ - public function findBySubscriberFindsSubscriptionOnlyWithTheGivenSubscriber() + public function testFindBySubscriberFindsSubscriptionOnlyWithTheGivenSubscriber() { - $this->getDataSet()->addTable(static::SUBSCRIBER_TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscription.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class, SubscriberListFixture::class, SubscriptionFixture::class]); /** @var Subscriber $subscriber */ $subscriber = $this->subscriberRepository->find(1); - $result = $this->subject->findBySubscriber($subscriber); + $result = $this->subscriptionRepository->findBySubscriber($subscriber); /** @var Subscription $subscription */ foreach ($result as $subscription) { - static::assertSame($subscriber, $subscription->getSubscriber()); + self::assertSame($subscriber, $subscription->getSubscriber()); } } - /** - * @test - */ - public function findBySubscriberListFindsSubscriptionOnlyWithTheGivenSubscriberList() + public function testFindBySubscriberListFindsSubscriptionOnlyWithTheGivenSubscriberList() { - $this->getDataSet()->addTable(static::SUBSCRIBER_TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscription.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class, SubscriberListFixture::class, SubscriptionFixture::class]); /** @var SubscriberList $subscriberList */ $subscriberList = $this->subscriberListRepository->find(1); - $result = $this->subject->findBySubscriberList($subscriberList); + $result = $this->subscriptionRepository->findBySubscriberList($subscriberList); /** @var Subscription $subscription */ foreach ($result as $subscription) { - static::assertSame($subscriberList, $subscription->getSubscriberList()); + self::assertSame($subscriberList, $subscription->getSubscriberList()); } } - /** - * @test - */ - public function savePersistsAndFlushesModel() + public function testSavePersistsAndFlushesModel() { - $this->getDataSet()->addTable(static::SUBSCRIBER_TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->getDataSet()->addTable(static::SUBSCRIBER_LIST_TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->touchDatabaseTable(static::TABLE_NAME); - $this->applyDatabaseChanges(); - $numberOfSaveModelsBefore = count($this->subject->findAll()); + $this->loadFixtures([SubscriberFixture::class, SubscriberListFixture::class]); + + $numberOfSaveModelsBefore = count($this->subscriptionRepository->findAll()); $model = new Subscription(); /** @var Subscriber $subscriber */ @@ -235,97 +147,69 @@ public function savePersistsAndFlushesModel() /** @var SubscriberList $subscriber */ $subscriberList = $this->subscriberListRepository->find(1); $model->setSubscriberList($subscriberList); - $this->subject->save($model); + $this->subscriptionRepository->save($model); - static::assertCount($numberOfSaveModelsBefore + 1, $this->subject->findAll()); + self::assertCount($numberOfSaveModelsBefore + 1, $this->subscriptionRepository->findAll()); } - /** - * @test - */ - public function removeRemovesModel() + public function testRemoveRemovesModel() { - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscription.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class, SubscriberListFixture::class, SubscriptionFixture::class]); /** @var Subscription[] $allModels */ - $allModels = $this->subject->findAll(); + $allModels = $this->subscriptionRepository->findAll(); $numberOfModelsBeforeRemove = count($allModels); $firstModel = $allModels[0]; - $this->subject->remove($firstModel); + $this->subscriptionRepository->remove($firstModel); - $numberOfModelsAfterRemove = count($this->subject->findAll()); - static::assertSame(1, $numberOfModelsBeforeRemove - $numberOfModelsAfterRemove); + $numberOfModelsAfterRemove = count($this->subscriptionRepository->findAll()); + self::assertSame(1, $numberOfModelsBeforeRemove - $numberOfModelsAfterRemove); } - /** - * @test - */ - public function findOneBySubscriberListAndSubscriberForNeitherMatchingReturnsNull() + public function testFindOneBySubscriberListAndSubscriberForNeitherMatchingReturnsNull() { - $this->getDataSet()->addTable(static::SUBSCRIBER_TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->getDataSet()->addTable(static::SUBSCRIBER_LIST_TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscription.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class, SubscriberListFixture::class, SubscriptionFixture::class]); $subscriberList = $this->subscriberListRepository->find(3); $subscriber = $this->subscriberRepository->find(4); - $result = $this->subject->findOneBySubscriberListAndSubscriber($subscriberList, $subscriber); + $result = $this->subscriptionRepository->findOneBySubscriberListAndSubscriber($subscriberList, $subscriber); - static::assertNull($result); + self::assertNull($result); } - /** - * @test - */ - public function findOneBySubscriberListAndSubscriberForMatchingSubscriberListOnlyReturnsNull() + public function testFindOneBySubscriberListAndSubscriberForMatchingSubscriberListOnlyReturnsNull() { - $this->getDataSet()->addTable(static::SUBSCRIBER_TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->getDataSet()->addTable(static::SUBSCRIBER_LIST_TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscription.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class, SubscriberListFixture::class, SubscriptionFixture::class]); $subscriberList = $this->subscriberListRepository->find(2); $subscriber = $this->subscriberRepository->find(4); - $result = $this->subject->findOneBySubscriberListAndSubscriber($subscriberList, $subscriber); + $result = $this->subscriptionRepository->findOneBySubscriberListAndSubscriber($subscriberList, $subscriber); - static::assertNull($result); + self::assertNull($result); } - /** - * @test - */ - public function findOneBySubscriberListAndSubscriberForMatchingSubscriberOnlyReturnsNull() + public function testFindOneBySubscriberListAndSubscriberForMatchingSubscriberOnlyReturnsNull() { - $this->getDataSet()->addTable(static::SUBSCRIBER_TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->getDataSet()->addTable(static::SUBSCRIBER_LIST_TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscription.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class, SubscriberListFixture::class, SubscriptionFixture::class]); $subscriberList = $this->subscriberListRepository->find(3); $subscriber = $this->subscriberRepository->find(1); - $result = $this->subject->findOneBySubscriberListAndSubscriber($subscriberList, $subscriber); + $result = $this->subscriptionRepository->findOneBySubscriberListAndSubscriber($subscriberList, $subscriber); - static::assertNull($result); + self::assertNull($result); } - /** - * @test - */ - public function findOneBySubscriberListAndSubscriberForBothMatchingReturnsMatch() + public function testFindOneBySubscriberListAndSubscriberForBothMatchingReturnsMatch() { - $this->getDataSet()->addTable(static::SUBSCRIBER_TABLE_NAME, __DIR__ . '/../Fixtures/Subscriber.csv'); - $this->getDataSet()->addTable(static::SUBSCRIBER_LIST_TABLE_NAME, __DIR__ . '/../Fixtures/SubscriberList.csv'); - $this->getDataSet()->addTable(static::TABLE_NAME, __DIR__ . '/../Fixtures/Subscription.csv'); - $this->applyDatabaseChanges(); + $this->loadFixtures([SubscriberFixture::class, SubscriberListFixture::class, SubscriptionFixture::class]); $subscriberList = $this->subscriberListRepository->find(2); $subscriber = $this->subscriberRepository->find(1); - $result = $this->subject->findOneBySubscriberListAndSubscriber($subscriberList, $subscriber); + $result = $this->subscriptionRepository->findOneBySubscriberListAndSubscriber($subscriberList, $subscriber); - static::assertInstanceOf(Subscription::class, $result); - static::assertSame($subscriberList, $result->getSubscriberList()); - static::assertSame($subscriber, $result->getSubscriber()); + self::assertInstanceOf(Subscription::class, $result); + self::assertSame($subscriberList, $result->getSubscriberList()); + self::assertSame($subscriber, $result->getSubscriber()); } } diff --git a/tests/Integration/EmptyStartPageBundle/Controller/DefaultControllerTest.php b/tests/Integration/EmptyStartPageBundle/Controller/DefaultControllerTest.php index 4aec64a5..3e86216a 100644 --- a/tests/Integration/EmptyStartPageBundle/Controller/DefaultControllerTest.php +++ b/tests/Integration/EmptyStartPageBundle/Controller/DefaultControllerTest.php @@ -1,40 +1,41 @@ */ -class DefaultControllerTest extends AbstractWebTest +class DefaultControllerTest extends WebTestCase { - /** - * @test - */ - public function controllerIsAvailableViaContainer() + public function testControllerIsAvailableViaContainer(): void { - static::assertInstanceOf( + $client = self::createClient(); + $container = $client->getContainer(); + + self::assertInstanceOf( DefaultController::class, - $this->client->getContainer()->get(DefaultController::class) + $container->get(DefaultController::class) ); } - /** - * @test - */ - public function indexActionReturnsResponseWithHelloWorld() + public function testIndexActionReturnsResponseWithHelloWorld(): void { - $this->client->request('GET', '/'); + $client = self::createClient(); + $client->request('GET', '/api/v2'); + + $response = $client->getResponse(); - static::assertTrue($this->client->getResponse()->isSuccessful()); - static::assertContains( + self::assertTrue($response->isSuccessful()); + self::assertStringContainsString( 'This page has been intentionally left empty.', - $this->client->getResponse()->getContent() + $response->getContent() ); } } diff --git a/tests/Integration/Routing/ExtraLoaderTest.php b/tests/Integration/Routing/ExtraLoaderTest.php index c1bfb652..542c6a86 100644 --- a/tests/Integration/Routing/ExtraLoaderTest.php +++ b/tests/Integration/Routing/ExtraLoaderTest.php @@ -1,19 +1,19 @@ setEnvironment(Environment::TESTING)->configure(); $this->kernel = $bootstrap->getApplicationKernel(); $this->kernel->boot(); - $container = $this->kernel->getContainer(); - /** @var FileLocator $locator */ - $locator = $container->get('file_locator'); - $routeControllerLoader = new AnnotatedRouteControllerLoader(new SimpleAnnotationReader()); + $locator = new FileLocator([ + $this->kernel->getProjectDir() . '/src/EmptyStartPageBundle/Controller', + $this->kernel->getProjectDir() . '/src/EmptyStartPageBundle', + $this->kernel->getProjectDir() . '/config', + ]); + + $attributeLoader = new AttributeRouteControllerLoader(); + $attributeDirectoryLoader = new AttributeDirectoryLoader($locator, $attributeLoader); $loaderResolver = new LoaderResolver( [ new YamlFileLoader($locator), - new AnnotationDirectoryLoader($locator, $routeControllerLoader), + $attributeDirectoryLoader, ] ); @@ -58,17 +55,17 @@ protected function setUp() $this->subject->setResolver($loaderResolver); } - protected function tearDown() + protected function tearDown(): void { $this->kernel->shutdown(); Bootstrap::purgeInstance(); } - /** - * @test - */ - public function loadReturnsRouteCollection() + public function loadReturnsRouteCollection(): void { - static::assertInstanceOf(RouteCollection::class, $this->subject->load('', 'extra')); + $routeCollection = $this->subject->load('@EmptyStartPageBundle/Controller/', 'extra'); + + self::assertInstanceOf(RouteCollection::class, $routeCollection); + self::assertNotNull($routeCollection->get('empty_start_page')); } } diff --git a/tests/Integration/Security/AuthenticationTest.php b/tests/Integration/Security/AuthenticationTest.php index 2e69f607..dfb55089 100644 --- a/tests/Integration/Security/AuthenticationTest.php +++ b/tests/Integration/Security/AuthenticationTest.php @@ -1,12 +1,16 @@ */ -class AuthenticationTest extends TestCase +class AuthenticationTest extends KernelTestCase { use DatabaseTestTrait; - /** - * @var string - */ - const ADMINISTRATOR_TABLE_NAME = 'phplist_admin'; + private ?Authentication $subject = null; - /** - * @var string - */ - const TOKEN_TABLE_NAME = 'phplist_admintoken'; + protected function setUp(): void + { + parent::setUp(); + $this->loadSchema(); - /** - * @var Authentication - */ - private $subject = null; + $this->subject = self::getContainer()->get(Authentication::class); + } - protected function setUp() + protected function tearDown(): void { - $this->setUpDatabaseTest(); - - $this->subject = $this->container->get(Authentication::class); + $schemaTool = new SchemaTool($this->entityManager); + $schemaTool->dropDatabase(); + parent::tearDown(); } - /** - * @test - */ - public function subjectIsAvailableViaContainer() + public function testSubjectIsAvailableViaContainer() { - static::assertInstanceOf(Authentication::class, $this->subject); + self::assertInstanceOf(Authentication::class, $this->subject); } - /** - * @test - */ - public function classIsRegisteredAsSingletonInContainer() + public function testClassIsRegisteredAsSingletonInContainer() { - static::assertSame($this->subject, $this->container->get(Authentication::class)); + self::assertSame($this->subject, self::getContainer()->get(Authentication::class)); } - /** - * @test - */ - public function authenticateByApiKeyWithValidApiKeyReturnsMatchingAdministrator() + public function testAuthenticateByApiKeyWithValidApiKeyReturnsMatchingAdministrator() { - $this->getDataSet()->addTable( - static::ADMINISTRATOR_TABLE_NAME, - __DIR__ . '/../Domain/Repository/Fixtures/Administrator.csv' - ); - $this->getDataSet()->addTable( - static::TOKEN_TABLE_NAME, - __DIR__ . '/../Domain/Repository/Fixtures/AdministratorTokenWithAdministrator.csv' - ); - $this->applyDatabaseChanges(); + $this->loadFixtures([AdministratorFixture::class, AdministratorTokenWithAdministratorFixture::class]); $apiKey = 'cfdf64eecbbf336628b0f3071adba762'; $request = new Request(); @@ -77,24 +59,13 @@ public function authenticateByApiKeyWithValidApiKeyReturnsMatchingAdministrator( $result = $this->subject->authenticateByApiKey($request); - static::assertInstanceOf(Administrator::class, $result); - static::assertSame(1, $result->getId()); + self::assertInstanceOf(Administrator::class, $result); + self::assertSame(1, $result->getId()); } - /** - * @test - */ - public function authenticateByApiKeyWithValidApiKeyAndDisabledAdministratorReturnsNull() + public function testAuthenticateByApiKeyWithValidApiKeyAndDisabledAdministratorReturnsNull() { - $this->getDataSet()->addTable( - static::ADMINISTRATOR_TABLE_NAME, - __DIR__ . '/../Domain/Repository/Fixtures/Administrator.csv' - ); - $this->getDataSet()->addTable( - static::TOKEN_TABLE_NAME, - __DIR__ . '/../Domain/Repository/Fixtures/AdministratorTokenWithAdministrator.csv' - ); - $this->applyDatabaseChanges(); + $this->loadFixtures([AdministratorFixture::class, AdministratorTokenWithAdministratorFixture::class]); $apiKey = 'cfdf64eecbbf336628b0f3071adba765'; $request = new Request(); @@ -102,19 +73,12 @@ public function authenticateByApiKeyWithValidApiKeyAndDisabledAdministratorRetur $result = $this->subject->authenticateByApiKey($request); - static::assertNull($result); + self::assertNull($result); } - /** - * @test - */ - public function authenticateByApiKeyWithValidApiKeyForInexistentAdministratorReturnsNull() + public function testAuthenticateByApiKeyWithValidApiKeyForInexistentAdministratorReturnsNull() { - $this->getDataSet()->addTable( - static::TOKEN_TABLE_NAME, - __DIR__ . '/../Domain/Repository/Fixtures/AdministratorTokenWithAdministrator.csv' - ); - $this->applyDatabaseChanges(); + $this->loadFixtures([AdministratorFixture::class, AdministratorTokenWithAdministratorFixture::class]); $apiKey = 'cfdf64eecbbf336628b0f3071adba763'; $request = new Request(); @@ -125,16 +89,9 @@ public function authenticateByApiKeyWithValidApiKeyForInexistentAdministratorRet static::assertNull($result); } - /** - * @test - */ - public function authenticateByApiKeyWithValidApiKeyForNonSuperUserAdministratorReturnsNull() + public function testAuthenticateByApiKeyWithValidApiKeyForNonSuperUserAdministratorReturnsNull() { - $this->getDataSet()->addTable( - static::TOKEN_TABLE_NAME, - __DIR__ . '/../Domain/Repository/Fixtures/AdministratorTokenWithAdministrator.csv' - ); - $this->applyDatabaseChanges(); + $this->loadFixtures([AdministratorFixture::class, AdministratorTokenWithAdministratorFixture::class]); $apiKey = 'cfdf64eecbbf336628b0f3071adba764'; $request = new Request(); @@ -142,6 +99,6 @@ public function authenticateByApiKeyWithValidApiKeyForNonSuperUserAdministratorR $result = $this->subject->authenticateByApiKey($request); - static::assertNull($result); + self::assertNull($result); } } diff --git a/tests/Integration/Security/HashGeneratorTest.php b/tests/Integration/Security/HashGeneratorTest.php index 571682a6..cc0d810e 100644 --- a/tests/Integration/Security/HashGeneratorTest.php +++ b/tests/Integration/Security/HashGeneratorTest.php @@ -1,64 +1,45 @@ */ -class HashGeneratorTest extends TestCase +class HashGeneratorTest extends KernelTestCase { - /** - * @var ApplicationKernel - */ - private $kernel = null; - - /** - * @var ContainerInterface - */ - private $container = null; + use DatabaseTestTrait; - protected function setUp() + protected function setUp(): void { - $bootstrap = Bootstrap::getInstance(); - $bootstrap->setEnvironment(Environment::TESTING)->configure(); - - $this->kernel = $bootstrap->getApplicationKernel(); - $this->kernel->boot(); - - $this->container = $this->kernel->getContainer(); + parent::setUp(); + $this->loadSchema(); } - protected function tearDown() + protected function tearDown(): void { - $this->kernel->shutdown(); - Bootstrap::purgeInstance(); + $schemaTool = new SchemaTool($this->entityManager); + $schemaTool->dropDatabase(); + parent::tearDown(); } - /** - * @test - */ - public function subjectIsAvailableViaContainer() + public function testSubjectIsAvailableViaContainer() { - static::assertInstanceOf(HashGenerator::class, $this->container->get(HashGenerator::class)); + self::assertInstanceOf(HashGenerator::class, self::getContainer()->get(HashGenerator::class)); } - /** - * @test - */ - public function classIsRegisteredAsSingletonInContainer() + public function testClassIsRegisteredAsSingletonInContainer() { $id = HashGenerator::class; - static::assertSame($this->container->get($id), $this->container->get($id)); + self::assertSame(self::getContainer()->get($id), self::getContainer()->get($id)); } } diff --git a/tests/Support/Interfaces/TestMarker.php b/tests/Support/Interfaces/TestMarker.php index 48643fb8..caca8eac 100644 --- a/tests/Support/Interfaces/TestMarker.php +++ b/tests/Support/Interfaces/TestMarker.php @@ -1,4 +1,5 @@ httpClient = new Client(['http_errors' => false]); } - protected function tearDown() + protected function tearDown(): void { $this->stopSymfonyServer(); + $this->httpClient = null; + parent::tearDown(); } - /** - * @return string[][] - */ - public function environmentDataProvider(): array - { - return [ - 'test' => ['test'], - 'dev' => ['dev'], - ]; - } - - /** - * @test - * @param string $environment - * @dataProvider environmentDataProvider - */ - public function homepageReturnsSuccess(string $environment) + public function testHomepageReturnsSuccess(): void { - $this->startSymfonyServer($environment); - - $response = $this->httpClient->get('/', ['base_uri' => $this->getBaseUrl()]); - - static::assertSame(200, $response->getStatusCode()); - } - - /** - * @test - * @param string $environment - * @dataProvider environmentDataProvider - */ - public function homepageReturnsDummyContent(string $environment) - { - $this->startSymfonyServer($environment); - - $response = $this->httpClient->get('/', ['base_uri' => $this->getBaseUrl()]); - - static::assertContains('This page has been intentionally left empty.', $response->getBody()->getContents()); + $this->startSymfonyServer(); + $response = $this->httpClient->get('/api/v2', [ + 'base_uri' => $this->getBaseUrl(), + ]); + + self::assertSame(200, $response->getStatusCode()); + self::assertStringContainsString( + 'This page has been intentionally left empty.', + $response->getBody()->getContents() + ); } } diff --git a/tests/Unit/Composer/ModuleFinderTest.php b/tests/Unit/Composer/ModuleFinderTest.php index 64069e5b..55bc67df 100644 --- a/tests/Unit/Composer/ModuleFinderTest.php +++ b/tests/Unit/Composer/ModuleFinderTest.php @@ -1,4 +1,5 @@ packageRepository = $this->createMock(PackageRepository::class); $this->subject = new ModuleFinder(); - - $this->packageRepositoryProphecy = $this->prophesize(PackageRepository::class); - - /** @var PackageRepository|ProphecySubjectInterface $packageRepository */ - $packageRepository = $this->packageRepositoryProphecy->reveal(); - $this->subject->injectPackageRepository($packageRepository); + $this->subject->injectPackageRepository($this->packageRepository); } - /** - * @test - */ - public function findBundleClassesForNoModulesReturnsEmptyArray() + public function testFindBundleClassesForNoModulesReturnsEmptyArray(): void { - $this->packageRepositoryProphecy->findModules()->willReturn([]); + $this->packageRepository + ->method('findModules') + ->willReturn([]); $result = $this->subject->findBundleClasses(); - static::assertSame([], $result); + self::assertSame([], $result); } - /** - * @return PackageInterface[][] - */ public function modulesWithoutBundlesDataProvider(): array { - /** @var array[][] $extrasSets */ - $extrasSets = [ + return $this->buildMockPackagesWithModuleConfiguration([ 'one module without/with empty extras' => [[]], - 'one module with extras for other stuff' => [['branch-alias' => ['dev-master' => '4.0.x-dev']]], + 'one module with extras for other stuff' => [['branch-alias' => ['dev-master' => '5.0.x-dev']]], 'one module with empty "phplist/core" extras section' => [['phplist/core' => []]], 'one module with empty bundles extras section' => [['phplist/core' => ['bundles' => []]]], - ]; - - return $this->buildMockPackagesWithModuleConfiguration($extrasSets); + ]); } - /** - * @param array[][] $extrasSets - * - * @return PackageInterface[][] - */ private function buildMockPackagesWithModuleConfiguration(array $extrasSets): array { - /** @var PackageInterface[][] $moduleSets */ $moduleSets = []; foreach ($extrasSets as $packageName => $extrasSet) { - $moduleSet = $this->buildSingleMockPackageWithModuleConfiguration($extrasSet); + $moduleSet = []; + foreach ($extrasSet as $extras) { + $moduleSet[] = $this->buildMockPackage($extras, $packageName); + } $moduleSets[$packageName] = [$moduleSet]; } return $moduleSets; } - /** - * @param array[] $extrasSet - * - * @return PackageInterface[] - */ - private function buildSingleMockPackageWithModuleConfiguration(array $extrasSet): array + private function buildMockPackage(array $extras, string $packageName): PackageInterface { - /** @var PackageInterface[] $moduleSet */ - $moduleSet = []; - foreach ($extrasSet as $extras) { - $moduleSet[] = $this->buildPackageProphecyWithExtras($extras, 'phplist/test'); - } + $package = $this->createMock(PackageInterface::class); + $package->method('getExtra')->willReturn($extras); + $package->method('getName')->willReturn($packageName); - return $moduleSet; + return $package; } /** - * @param array $extras - * @param string $packageName - * - * @return ProphecySubjectInterface - */ - private function buildPackageProphecyWithExtras(array $extras, string $packageName): ProphecySubjectInterface - { - /** @var PackageInterface|ObjectProphecy $packageProphecy */ - $packageProphecy = $this->prophesize(PackageInterface::class); - $packageProphecy->getExtra()->willReturn($extras); - $packageProphecy->getName()->willReturn($packageName); - - return $packageProphecy->reveal(); - } - - /** - * @test - * @param PackageInterface[] $modules * @dataProvider modulesWithoutBundlesDataProvider */ - public function findBundleClassesForModulesWithoutBundlesReturnsEmptyArray(array $modules) + public function testFindBundleClassesForModulesWithoutBundlesReturnsEmptyArray(array $modules): void { - $this->packageRepositoryProphecy->findModules()->willReturn($modules); + $this->packageRepository + ->method('findModules') + ->willReturn($modules); $result = $this->subject->findBundleClasses(); - static::assertSame([], $result); + self::assertSame([], $result); } - /** - * @return PackageInterface[][] - */ public function modulesWithInvalidBundlesDataProvider(): array { - /** @var array[][] $extrasSets */ - $extrasSets = [ + return $this->buildMockPackagesWithModuleConfiguration([ 'one module with core section as string' => [['phplist/core' => 'foo']], - 'one module with core section as int' => [['phplist/core' => 42]], - 'one module with core section as float' => [['phplist/core' => 3.14159]], - 'one module with core section as bool' => [['phplist/core' => true]], - 'one module with bundles section as string' => [['phplist/core' => ['bundles' => 'foo']]], 'one module with bundles section as int' => [['phplist/core' => ['bundles' => 42]]], - 'one module with bundles section as float' => [['phplist/core' => ['bundles' => 3.14159]]], - 'one module with bundles section as bool' => [['phplist/core' => ['bundles' => true]]], - 'one module with one bundle class name as array' => [['phplist/core' => ['bundles' => [[]]]]], - 'one module with one bundle class name as int' => [['phplist/core' => ['bundles' => [42]]]], - 'one module with one bundle class name as float' => [['phplist/core' => ['bundles' => [3.14159]]]], - 'one module with one bundle class name as bool' => [['phplist/core' => ['bundles' => [true]]]], - 'one module with one bundle class name as null' => [['phplist/core' => ['bundles' => [null]]]], - ]; - - return $this->buildMockPackagesWithModuleConfiguration($extrasSets); + ]); } /** - * @test - * @param PackageInterface[] $modules * @dataProvider modulesWithInvalidBundlesDataProvider */ - public function findBundleClassesForModulesWithInvalidBundlesConfigurationThrowsException(array $modules) + public function testFindBundleClassesForModulesWithInvalidBundlesConfigurationThrowsException(array $modules): void { - $this->packageRepositoryProphecy->findModules()->willReturn($modules); + $this->packageRepository + ->method('findModules') + ->willReturn($modules); $this->expectException(\InvalidArgumentException::class); - $this->subject->findBundleClasses(); } - /** - * @return array[] - */ public function modulesWithBundlesDataProvider(): array { - /** @var array[][] $dataSets */ - $dataSets = [ + return [ 'one module with one bundle' => [ [ - 'phplist/foo' => [ + $this->buildMockPackage([ 'phplist/core' => [ 'bundles' => ['Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle'], ], - ], + ], 'phplist/foo'), ], ['phplist/foo' => ['Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle']], ], - 'one module with two bundles' => [ - [ - 'phplist/foo' => [ - 'phplist/core' => [ - 'bundles' => [ - 'Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle', - 'PhpList\\Core\\EmptyStartPageBundle\\PhpListEmptyStartPageBundle', - ], - ], - ], - ], - [ - 'phplist/foo' => [ - 'Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle', - 'PhpList\\Core\\EmptyStartPageBundle\\PhpListEmptyStartPageBundle', - ], - ], - ], - 'two module with one bundle each' => [ - [ - 'phplist/foo' => [ - 'phplist/core' => [ - 'bundles' => ['Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle'], - ], - ], - 'phplist/bar' => [ - 'phplist/core' => [ - 'bundles' => ['PhpList\\Core\\EmptyStartPageBundle\\PhpListEmptyStartPageBundle'], - ], - ], - ], - [ - 'phplist/foo' => ['Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle'], - 'phplist/bar' => ['PhpList\\Core\\EmptyStartPageBundle\\PhpListEmptyStartPageBundle'], - ], - ], ]; - - $moduleSets = []; - /** @var array[] $dataSet */ - foreach ($dataSets as $dataSetName => $dataSet) { - /** @var string[][][] $extraSets */ - /** @var string[][] $expectedBundles */ - list($extraSets, $expectedBundles) = $dataSet; - - $testCases = []; - foreach ($extraSets as $packageName => $extras) { - $testCases[] = $this->buildPackageProphecyWithExtras($extras, $packageName); - } - $moduleSets[$dataSetName] = [$testCases, $expectedBundles]; - } - - return $moduleSets; } /** - * @test - * @param PackageInterface[] $modules - * @param string[][] $expectedBundles * @dataProvider modulesWithBundlesDataProvider */ - public function findBundleClassesForModulesWithBundlesReturnsBundleClassNames( + public function testFindBundleClassesForModulesWithBundlesReturnsBundleClassNames( array $modules, array $expectedBundles - ) { - $this->packageRepositoryProphecy->findModules()->willReturn($modules); + ): void { + $this->packageRepository + ->method('findModules') + ->willReturn($modules); $result = $this->subject->findBundleClasses(); - static::assertSame($expectedBundles, $result); + self::assertSame($expectedBundles, $result); } - /** - * @test - */ - public function createBundleConfigurationYamlForNoModulesReturnsCommentOnly() + public function testCreateBundleConfigurationYamlForNoModulesReturnsCommentOnly(): void { - $this->packageRepositoryProphecy->findModules()->willReturn([]); + $this->packageRepository + ->method('findModules') + ->willReturn([]); $result = $this->subject->createBundleConfigurationYaml(); - static::assertSame(static::YAML_COMMENT . "\n{ }", $result); + self::assertSame(self::YAML_COMMENT . "\n{ }", $result); } /** - * @test - * @param PackageInterface[][] $modules - * @param array[] $bundles * @dataProvider modulesWithBundlesDataProvider */ - public function createBundleConfigurationYamlReturnsYamlForBundles(array $modules, array $bundles) + public function testCreateBundleConfigurationYamlReturnsYamlForBundles(array $modules, array $bundles): void { - $this->packageRepositoryProphecy->findModules()->willReturn($modules); + $this->packageRepository + ->method('findModules') + ->willReturn($modules); $result = $this->subject->createBundleConfigurationYaml(); - static::assertSame(static::YAML_COMMENT . "\n" . Yaml::dump($bundles), $result); - } - - /** - * @return PackageInterface[][] - */ - public function modulesWithoutRoutesDataProvider(): array - { - /** @var array[][] $extrasSets */ - $extrasSets = [ - 'one module without/with empty extras' => [[]], - 'one module with extras for other stuff' => [['branch-alias' => ['dev-master' => '4.0.x-dev']]], - 'one module with empty "phplist/core" extras section' => [['phplist/core' => []]], - 'one module with empty routes extras section' => [['phplist/core' => ['routes' => []]]], - ]; - - return $this->buildMockPackagesWithModuleConfiguration($extrasSets); - } - - /** - * @test - * @param PackageInterface[] $modules - * @dataProvider modulesWithoutRoutesDataProvider - */ - public function findRoutesForModulesWithoutRoutesReturnsEmptyArray(array $modules) - { - $this->packageRepositoryProphecy->findModules()->willReturn($modules); - - $result = $this->subject->findRoutes(); - - static::assertSame([], $result); - } - - /** - * @return PackageInterface[][] - */ - public function modulesWithInvalidRoutesDataProvider(): array - { - /** @var array[][] $extrasSets */ - $extrasSets = [ - 'one module with core section as string' => [['phplist/core' => 'foo']], - 'one module with core section as int' => [['phplist/core' => 42]], - 'one module with core section as float' => [['phplist/core' => 3.14159]], - 'one module with core section as bool' => [['phplist/core' => true]], - 'one module with routes section as string' => [['phplist/core' => ['routes' => 'foo']]], - 'one module with routes section as int' => [['phplist/core' => ['routes' => 42]]], - 'one module with routes section as float' => [['phplist/core' => ['routes' => 3.14159]]], - 'one module with routes section as bool' => [['phplist/core' => ['routes' => true]]], - 'one module with one route class name as string' => [['phplist/core' => ['routes' => ['foo']]]], - 'one module with one route class name as int' => [['phplist/core' => ['routes' => [42]]]], - 'one module with one route class name as float' => [['phplist/core' => ['routes' => [3.14159]]]], - 'one module with one route class name as bool' => [['phplist/core' => ['routes' => [true]]]], - 'one module with one route class name as null' => [['phplist/core' => ['routes' => [null]]]], - ]; - - return $this->buildMockPackagesWithModuleConfiguration($extrasSets); - } - - /** - * @test - * @param PackageInterface[] $modules - * @dataProvider modulesWithInvalidRoutesDataProvider - */ - public function findRoutesClassesForModulesWithInvalidRoutesConfigurationThrowsException(array $modules) - { - $this->packageRepositoryProphecy->findModules()->willReturn($modules); - - $this->expectException(\InvalidArgumentException::class); - - $this->subject->findRoutes(); - } - - /** - * @return array[][] - */ - public function modulesWithRoutesDataProvider(): array - { - /** @var array[][] $dataSets */ - $dataSets = [ - 'one module with one route' => [ - [ - 'phplist/foo' => [ - 'phplist/core' => [ - 'routes' => [ - 'homepage' => [ - 'path' => '/', - 'defaults' => ['_controller' => 'PhpListEmptyStartPageBundle:Default:index'], - ], - ], - ], - ], - ], - [ - 'phplist/foo.homepage' => [ - 'path' => '/', - 'defaults' => ['_controller' => 'PhpListEmptyStartPageBundle:Default:index'], - ], - ], - ], - 'one module with two routes' => [ - [ - 'phplist/foo' => [ - 'phplist/core' => [ - 'routes' => [ - 'homepage' => [ - 'path' => '/', - 'defaults' => ['_controller' => 'PhpListEmptyStartPageBundle:Default:index'], - ], - 'blog' => [ - 'path' => '/blog', - 'defaults' => ['_controller' => 'PhpListEmptyStartPageBundle:Blog:index'], - ], - ], - ], - ], - ], - [ - 'phplist/foo.homepage' => [ - 'path' => '/', - 'defaults' => ['_controller' => 'PhpListEmptyStartPageBundle:Default:index'], - ], - 'phplist/foo.blog' => [ - 'path' => '/blog', - 'defaults' => ['_controller' => 'PhpListEmptyStartPageBundle:Blog:index'], - ], - ], - ], - 'two module with one route each' => [ - [ - 'phplist/foo' => [ - 'phplist/core' => [ - 'routes' => [ - 'homepage' => [ - 'path' => '/', - 'defaults' => ['_controller' => 'PhpListEmptyStartPageBundle:Default:index'], - ], - ], - ], - ], - 'phplist/bar' => [ - 'phplist/core' => [ - 'routes' => [ - 'blog' => [ - 'path' => '/blog', - 'defaults' => ['_controller' => 'PhpListEmptyStartPageBundle:Blog:index'], - ], - ], - ], - ], - ], - [ - 'phplist/foo.homepage' => [ - 'path' => '/', - 'defaults' => ['_controller' => 'PhpListEmptyStartPageBundle:Default:index'], - ], - 'phplist/bar.blog' => [ - 'path' => '/blog', - 'defaults' => ['_controller' => 'PhpListEmptyStartPageBundle:Blog:index'], - ], - ], - ], - ]; - - return $this->buildModuleSets($dataSets); - } - - /** - * @param array[][] $dataSets - * - * @return array[] - */ - private function buildModuleSets(array $dataSets): array - { - $moduleSets = []; - /** @var array[] $dataSet */ - foreach ($dataSets as $dataSetName => $dataSet) { - /** @var string[][][] $extraSets */ - /** @var array[] $expectedRoutes */ - list($extraSets, $expectedRoutes) = $dataSet; - - $testCases = []; - foreach ($extraSets as $packageName => $extras) { - $testCases[] = $this->buildPackageProphecyWithExtras($extras, $packageName); - } - $moduleSets[$dataSetName] = [$testCases, $expectedRoutes]; - } - - return $moduleSets; - } - - /** - * @test - * @param PackageInterface[] $modules - * @param array[] $expectedRoutes - * @dataProvider modulesWithRoutesDataProvider - */ - public function findRoutesForModulesWithRoutesReturnsRoutes(array $modules, array $expectedRoutes) - { - $this->packageRepositoryProphecy->findModules()->willReturn($modules); - - $result = $this->subject->findRoutes(); - - static::assertSame($expectedRoutes, $result); - } - - /** - * @test - */ - public function createRouteConfigurationYamlForNoModulesReturnsCommentOnly() - { - $this->packageRepositoryProphecy->findModules()->willReturn([]); - - $result = $this->subject->createRouteConfigurationYaml(); - - static::assertSame(static::YAML_COMMENT . "\n{ }", $result); - } - - /** - * @test - * @param PackageInterface[][] $modules - * @param array[] $routes - * @dataProvider modulesWithRoutesDataProvider - */ - public function createRouteConfigurationYamlReturnsYamlForRoutes(array $modules, array $routes) - { - $this->packageRepositoryProphecy->findModules()->willReturn($modules); - - $result = $this->subject->createRouteConfigurationYaml(); - - static::assertSame(static::YAML_COMMENT . "\n" . Yaml::dump($routes), $result); - } - - /** - * @return PackageInterface[][] - */ - public function modulesWithoutConfigurationDataProvider(): array - { - /** @var array[][] $extrasSets */ - $extrasSets = [ - 'without/with empty extras' => [[]], - 'with extras for other stuff' => [['branch-alias' => ['dev-master' => '4.0.x-dev']]], - 'with empty "phplist/core" extras section' => [['phplist/core' => []]], - 'with empty configuration extras section' => [['phplist/core' => ['configuration' => []]]], - ]; - - return $this->buildMockPackagesWithModuleConfiguration($extrasSets); - } - - /** - * @test - * @param PackageInterface[] $modules - * @dataProvider modulesWithoutConfigurationDataProvider - */ - public function findGeneralConfigurationForModulesWithoutConfigurationReturnsEmptyArray(array $modules) - { - $this->packageRepositoryProphecy->findModules()->willReturn($modules); - - $result = $this->subject->findGeneralConfiguration(); - - static::assertSame([], $result); - } - - /** - * @return PackageInterface[][] - */ - public function modulesWithInvalidConfigurationDataProvider(): array - { - /** @var array[][] $extrasSets */ - $extrasSets = [ - 'core section as string' => [['phplist/core' => 'foo']], - 'core section as int' => [['phplist/core' => 42]], - 'core section as float' => [['phplist/core' => 3.14159]], - 'core section as bool' => [['phplist/core' => true]], - 'configuration section as string' => [['phplist/core' => ['configuration' => 'foo']]], - 'configuration section as int' => [['phplist/core' => ['configuration' => 42]]], - 'configuration section as float' => [['phplist/core' => ['configuration' => 3.14159]]], - 'configuration section as bool' => [['phplist/core' => ['configuration' => true]]], - ]; - - return $this->buildMockPackagesWithModuleConfiguration($extrasSets); - } - - /** - * @test - * @param PackageInterface[] $modules - * @dataProvider modulesWithInvalidConfigurationDataProvider - */ - public function findGeneralConfigurationForModulesWithInvalidConfigurationThrowsException(array $modules) - { - $this->packageRepositoryProphecy->findModules()->willReturn($modules); - - $this->expectException(\InvalidArgumentException::class); - - $this->subject->findGeneralConfiguration(); - } - - /** - * @return array[][] - */ - public function modulesWithConfigurationDataProvider(): array - { - /** @var array[][] $dataSets */ - $dataSets = [ - 'one module with configuration' => [ - [ - 'phplist/foo' => [ - 'phplist/core' => [ - 'configuration' => ['foo' => 'bar'], - ], - ], - ], - ['foo' => 'bar'], - ], - 'two modules non-overlapping configuration sets' => [ - [ - 'phplist/foo' => [ - 'phplist/core' => [ - 'configuration' => ['foo' => 'bar'], - ], - ], - 'phplist/bar' => [ - 'phplist/core' => [ - 'configuration' => [ - 'foobar' => ['life' => 'everything'], - ], - ], - ], - ], - [ - 'foo' => 'bar', - 'foobar' => ['life' => 'everything'], - ], - ], - 'two modules overlapping configuration sets' => [ - [ - 'phplist/foo' => [ - 'phplist/core' => [ - 'configuration' => [ - 'foo' => 'bar', - 'foobar' => [1 => 'hello'], - 'good' => 'code', - ], - ], - ], - 'phplist/bar' => [ - 'phplist/core' => [ - 'configuration' => [ - 'foo' => 'bonjour', - 'foobar' => [2 => 'world'], - ], - ], - ], - ], - [ - 'foo' => 'bonjour', - 'foobar' => [1 => 'hello', 2 => 'world'], - 'good' => 'code', - ], - ], - ]; - - return $this->buildModuleSets($dataSets); - } - - /** - * @test - * @param PackageInterface[] $modules - * @param array $expectedConfiguration - * @dataProvider modulesWithConfigurationDataProvider - */ - public function findGeneralConfigurationForModulesWithConfigurationReturnsConfiguration( - array $modules, - array $expectedConfiguration - ) { - $this->packageRepositoryProphecy->findModules()->willReturn($modules); - - $result = $this->subject->findGeneralConfiguration(); - - static::assertSame($expectedConfiguration, $result); - } - - /** - * @test - */ - public function createGeneralConfigurationYamlForNoModulesReturnsCommentOnly() - { - $this->packageRepositoryProphecy->findModules()->willReturn([]); - - $result = $this->subject->createGeneralConfigurationYaml(); - - static::assertSame(static::YAML_COMMENT . "\n{ }", $result); - } - - /** - * @test - * @param PackageInterface[][] $modules - * @param array[] $routes - * @dataProvider modulesWithConfigurationDataProvider - */ - public function createGeneralConfigurationYamlReturnsYamlForConfiguration(array $modules, array $routes) - { - $this->packageRepositoryProphecy->findModules()->willReturn($modules); - - $result = $this->subject->createGeneralConfigurationYaml(); - - static::assertSame(static::YAML_COMMENT . "\n" . Yaml::dump($routes), $result); + self::assertSame(self::YAML_COMMENT . "\n" . Yaml::dump($bundles), $result); } } diff --git a/tests/Unit/Composer/PackageRepositoryTest.php b/tests/Unit/Composer/PackageRepositoryTest.php index c05e3596..c450caaa 100644 --- a/tests/Unit/Composer/PackageRepositoryTest.php +++ b/tests/Unit/Composer/PackageRepositoryTest.php @@ -1,4 +1,5 @@ subject = new PackageRepository(); - /** @var Composer|ObjectProphecy $composerProphecy */ - $composerProphecy = $this->prophesize(Composer::class); - $this->composerProphecy = $composerProphecy; - $this->composer = $composerProphecy->reveal(); + $this->composer = $this->createMock(Composer::class); - /** @var RepositoryManager|ObjectProphecy $repositoryManagerProphecy */ - $repositoryManagerProphecy = $this->prophesize(RepositoryManager::class); - /** @var RepositoryManager|ProphecySubjectInterface $repositoryManager */ - $repositoryManager = $repositoryManagerProphecy->reveal(); - $composerProphecy->getRepositoryManager()->willReturn($repositoryManager); + $repositoryManager = $this->createMock(RepositoryManager::class); + $this->composer + ->expects($this->any()) + ->method('getRepositoryManager') + ->willReturn($repositoryManager); - $this->localRepositoryProphecy = $this->prophesize(WritableRepositoryInterface::class); - /** @var WritableRepositoryInterface|ProphecySubjectInterface $localRepository */ - $localRepository = $this->localRepositoryProphecy->reveal(); - $repositoryManagerProphecy->getLocalRepository()->willReturn($localRepository); + $this->localRepository = $this->createMock(InstalledRepositoryInterface::class); + $repositoryManager + ->expects($this->any()) + ->method('getLocalRepository') + ->willReturn($this->localRepository); + + $this->subject->injectComposer($this->composer); $this->subject->injectComposer($this->composer); } - /** - * @test - */ - public function findAllIncludesDependencies() + public function testFindAllIncludesDependencies(): void { - $this->composerProphecy->getPackage()->willReturn($this->prophesize(RootPackageInterface::class)->reveal()); + $rootPackage = $this->createMock(RootPackageInterface::class); + $this->composer->expects($this->any())->method('getPackage')->willReturn($rootPackage); + + $dependency = $this->createMock(PackageInterface::class); + $dependency->expects($this->any())->method('getName')->willReturn('phplist/core'); - /** @var PackageInterface|ObjectProphecy $dependencyProphecy */ - $dependencyProphecy = $this->prophesize(PackageInterface::class); - $dependencyProphecy->getName()->willReturn('phplist/core'); - /** @var PackageInterface|ProphecySubjectInterface $dependency */ - $dependency = $dependencyProphecy->reveal(); - $this->localRepositoryProphecy->getPackages()->willReturn([$dependency]); + $this->localRepository->expects($this->any())->method('getPackages')->willReturn([$dependency]); - static::assertContains($dependency, $this->subject->findAll()); + $result = $this->subject->findAll(); + self::assertContains($dependency, $result); } - /** - * @test - */ - public function findAllIncludesRootPackage() + public function testFindAllIncludesRootPackage(): void { - /** @var RootPackageInterface|ProphecySubjectInterface $rootPackage */ - $rootPackage = $this->prophesize(RootPackageInterface::class)->reveal(); - $this->composerProphecy->getPackage()->willReturn($rootPackage); + $rootPackage = $this->createMock(RootPackageInterface::class); + $this->composer->expects($this->any())->method('getPackage')->willReturn($rootPackage); - $this->localRepositoryProphecy->getPackages()->willReturn([]); + $this->localRepository->expects($this->any())->method('getPackages')->willReturn([]); - static::assertContains($rootPackage, $this->subject->findAll()); + $result = $this->subject->findAll(); + self::assertContains($rootPackage, $result); } - /** - * @test - */ - public function findAllExcludesDuplicates() + public function testFindAllExcludesDuplicates(): void { - $this->composerProphecy->getPackage()->willReturn($this->prophesize(RootPackageInterface::class)->reveal()); - - $packageName = 'phplist/core'; - - /** @var PackageInterface|ObjectProphecy $dependencyProphecy */ - $dependencyProphecy = $this->prophesize(PackageInterface::class); - $dependencyProphecy->getName()->willReturn($packageName); - /** @var PackageInterface|ProphecySubjectInterface $dependency */ - $dependency = $dependencyProphecy->reveal(); - /** @var PackageInterface|ObjectProphecy $dependencyAliasProphecy */ - $dependencyAliasProphecy = $this->prophesize(PackageInterface::class); - $dependencyAliasProphecy->getName()->willReturn($packageName); - /** @var PackageInterface|ProphecySubjectInterface $dependencyAlias */ - $dependencyAlias = $dependencyAliasProphecy->reveal(); - $this->localRepositoryProphecy->getPackages()->willReturn([$dependency, $dependencyAlias]); - - static::assertNotContains($dependencyAlias, $this->subject->findAll()); + $rootPackage = $this->createMock(RootPackageInterface::class); + $this->composer->expects($this->any())->method('getPackage')->willReturn($rootPackage); + + $dependency = $this->createMock(PackageInterface::class); + $dependency->expects($this->any())->method('getName')->willReturn('phplist/core'); + + $duplicateDependency = $this->createMock(PackageInterface::class); + $duplicateDependency->expects($this->any())->method('getName')->willReturn('phplist/core'); + + $this->localRepository + ->expects($this->any()) + ->method('getPackages') + ->willReturn([$dependency, $duplicateDependency]); + + $result = $this->subject->findAll(); + self::assertNotContains($duplicateDependency, $result); } - /** - * @test - */ - public function findModulesForPhpListModuleRootPackageIncludesIt() + public function testFindModulesForPhpListModuleRootPackageIncludesIt(): void { - /** @var RootPackageInterface|ObjectProphecy $rootPackageProphecy */ - $rootPackageProphecy = $this->prophesize(RootPackageInterface::class); - $rootPackageProphecy->getName()->willReturn('phplist/base-installation'); - $rootPackageProphecy->getType()->willReturn('phplist-module'); - /** @var RootPackageInterface|ProphecySubjectInterface $rootPackage */ - $rootPackage = $rootPackageProphecy->reveal(); - $this->composerProphecy->getPackage()->willReturn($rootPackage); + $rootPackage = $this->createMock(RootPackageInterface::class); + $rootPackage->expects($this->any())->method('getName')->willReturn('phplist/base-installation'); + $rootPackage->expects($this->any())->method('getType')->willReturn('phplist-module'); + + $this->composer->expects($this->any())->method('getPackage')->willReturn($rootPackage); - $this->localRepositoryProphecy->getPackages()->willReturn([]); + $this->localRepository->expects($this->any())->method('getPackages')->willReturn([]); - static::assertContains($rootPackage, $this->subject->findModules()); + $result = $this->subject->findModules(); + self::assertContains($rootPackage, $result); } - /** - * @test - */ - public function findModulesForPhpListModuleDependencyReturnsIt() + public function testFindModulesForPhpListModuleDependencyReturnsIt(): void { - /** @var RootPackageInterface|ObjectProphecy $rootPackageProphecy */ - $rootPackageProphecy = $this->prophesize(RootPackageInterface::class); - /** @var RootPackageInterface|ObjectProphecy $rootPackage */ - $rootPackage = $rootPackageProphecy->reveal(); - $this->composerProphecy->getPackage()->willReturn($rootPackage); - - /** @var RootPackageInterface|ObjectProphecy $dependencyProphecy */ - $dependencyProphecy = $this->prophesize(RootPackageInterface::class); - $dependencyProphecy->getType()->willReturn('phplist-module'); - $dependencyProphecy->getName()->willReturn('phplist/core'); - /** @var RootPackageInterface|ProphecySubjectInterface $dependency */ - $dependency = $dependencyProphecy->reveal(); - - $this->localRepositoryProphecy->getPackages()->willReturn([$dependency]); - - static::assertContains($dependency, $this->subject->findModules()); + $rootPackage = $this->createMock(RootPackageInterface::class); + $this->composer->expects($this->any())->method('getPackage')->willReturn($rootPackage); + + $dependency = $this->createMock(PackageInterface::class); + $dependency->expects($this->any())->method('getName')->willReturn('phplist/core'); + $dependency->expects($this->any())->method('getType')->willReturn('phplist-module'); + + $this->localRepository->expects($this->any())->method('getPackages')->willReturn([$dependency]); + + $result = $this->subject->findModules(); + self::assertContains($dependency, $result); } - /** - * @return string[][] - */ public function nonPhpListModuleTypeDataProvider(): array { return [ @@ -173,47 +132,37 @@ public function nonPhpListModuleTypeDataProvider(): array } /** - * @test - * @param string $type * @dataProvider nonPhpListModuleTypeDataProvider */ - public function findModulesForNonPhpListModuleRootPackageIgnoresIt(string $type) + public function testFindModulesForNonPhpListModuleRootPackageIgnoresIt(string $type): void { - /** @var RootPackageInterface|ObjectProphecy $rootPackageProphecy */ - $rootPackageProphecy = $this->prophesize(RootPackageInterface::class); - $rootPackageProphecy->getType()->willReturn($type); - $rootPackageProphecy->getName()->willReturn('phplist/base-installation'); - /** @var RootPackageInterface|ProphecySubjectInterface $rootPackage */ - $rootPackage = $rootPackageProphecy->reveal(); - $this->composerProphecy->getPackage()->willReturn($rootPackage); + $rootPackage = $this->createMock(RootPackageInterface::class); + $rootPackage->expects($this->any())->method('getName')->willReturn('phplist/base-installation'); + $rootPackage->expects($this->any())->method('getType')->willReturn($type); - $this->localRepositoryProphecy->getPackages()->willReturn([]); + $this->composer->expects($this->any())->method('getPackage')->willReturn($rootPackage); - static::assertNotContains($rootPackage, $this->subject->findModules()); + $this->localRepository->expects($this->any())->method('getPackages')->willReturn([]); + + $result = $this->subject->findModules(); + self::assertNotContains($rootPackage, $result); } /** - * @test - * @param string $type * @dataProvider nonPhpListModuleTypeDataProvider */ - public function findModulesForNonPhpListModuleDependencyIgnoresIt(string $type) + public function testFindModulesForNonPhpListModuleDependencyIgnoresIt(string $type): void { - /** @var RootPackageInterface|ObjectProphecy $rootPackageProphecy */ - $rootPackageProphecy = $this->prophesize(RootPackageInterface::class); - /** @var RootPackageInterface|ProphecySubjectInterface $rootPackage */ - $rootPackage = $rootPackageProphecy->reveal(); - $this->composerProphecy->getPackage()->willReturn($rootPackage); - - /** @var RootPackageInterface|ObjectProphecy $dependencyProphecy */ - $dependencyProphecy = $this->prophesize(RootPackageInterface::class); - $dependencyProphecy->getType()->willReturn($type); - $dependencyProphecy->getName()->willReturn('phplist/test'); - /** @var RootPackageInterface|ProphecySubjectInterface $dependency */ - $dependency = $dependencyProphecy->reveal(); - - $this->localRepositoryProphecy->getPackages()->willReturn([$dependency]); - - static::assertNotContains($dependency, $this->subject->findModules()); + $rootPackage = $this->createMock(RootPackageInterface::class); + $this->composer->method('getPackage')->willReturn($rootPackage); + + $dependency = $this->createMock(PackageInterface::class); + $dependency->expects($this->any())->method('getName')->willReturn('phplist/test'); + $dependency->expects($this->any())->method('getType')->willReturn($type); + + $this->localRepository->expects($this->any())->method('getPackages')->willReturn([$dependency]); + + $result = $this->subject->findModules(); + self::assertNotContains($dependency, $result); } } diff --git a/tests/Unit/Composer/ScriptHandlerTest.php b/tests/Unit/Composer/ScriptHandlerTest.php index 6b2ecdf7..c85ecb33 100644 --- a/tests/Unit/Composer/ScriptHandlerTest.php +++ b/tests/Unit/Composer/ScriptHandlerTest.php @@ -1,4 +1,5 @@ createEventProphecyForCorePackage(); + $event = $this->createMockEventForCorePackage(); - $this->expectException(\DomainException::class); + $this->expectException(IOException::class); ScriptHandler::createBinaries($event); } - /** - * @test - */ - public function createPublicWebDirectoryForCorePackageThrowsException() + public function testCreatePublicWebDirectoryForCorePackageThrowsException(): void { - $event = $this->createEventProphecyForCorePackage(); + $event = $this->createMockEventForCorePackage(); - $this->expectException(\DomainException::class); + $this->expectException(IOException::class); ScriptHandler::createPublicWebDirectory($event); } - /** - * @return Event|ProphecySubjectInterface - */ - private function createEventProphecyForCorePackage() - { - /** @var RootPackageInterface|ObjectProphecy $packageProphecy */ - $packageProphecy = $this->prophesize(RootPackageInterface::class); - $packageProphecy->getName()->willReturn('phplist/core'); - /** @var Composer|ObjectProphecy $composerProphecy */ - $composerProphecy = $this->prophesize(Composer::class); - $composerProphecy->getPackage()->willReturn($packageProphecy->reveal()); - /** @var Event|ObjectProphecy $eventProphecy */ - $eventProphecy = $this->prophesize(Event::class); - $eventProphecy->getComposer()->willReturn($composerProphecy->reveal()); - - return $eventProphecy->reveal(); - } - - /** - * @test - */ - public function listModulesForPhpListModuleRootPackageListsIt() + public function testListModulesForPhpListModuleRootPackageListsIt(): void { $rootPackageName = 'phplist/core'; $rootPackageVersion = '1.2.3'; - $event = $this->buildMockEvent(); + $event = $this->createMockEvent(); - $this->rootPackageProphecy->getName()->willReturn($rootPackageName); - $this->rootPackageProphecy->getType()->willReturn('phplist-module'); - $this->rootPackageProphecy->getPrettyVersion()->willReturn($rootPackageVersion); + $this->rootPackage->method('getName')->willReturn($rootPackageName); + $this->rootPackage->method('getType')->willReturn('phplist-module'); + $this->rootPackage->method('getPrettyVersion')->willReturn($rootPackageVersion); - $this->localRepositoryProphecy->getPackages()->willReturn([]); + $this->localRepository->method('getPackages')->willReturn([]); ScriptHandler::listModules($event); - $this->expectOutputRegex('#' . $rootPackageName . ' +' . $rootPackageVersion . '#'); + $this->expectOutputRegex( + '/' + . preg_quote($rootPackageName, '/') + . '\s+' + . preg_quote($rootPackageVersion, '/') + . '/' + ); } - /** - * @test - */ - public function listModulesForNonPhpListModuleRootPackageExcludesIt() + public function testListModulesForNonPhpListModuleRootPackageExcludesIt(): void { $rootPackageName = 'phplist/core'; - $event = $this->buildMockEvent(); + $event = $this->createMockEvent(); - $this->rootPackageProphecy->getName()->willReturn($rootPackageName); - $this->rootPackageProphecy->getType()->willReturn('project'); + $this->rootPackage->method('getName')->willReturn($rootPackageName); + $this->rootPackage->method('getType')->willReturn('project'); - $this->localRepositoryProphecy->getPackages()->willReturn([]); + $this->localRepository->method('getPackages')->willReturn([]); ScriptHandler::listModules($event); $output = $this->getActualOutput(); - static::assertNotContains($rootPackageName, $output); + self::assertStringNotContainsString($rootPackageName, $output); } - /** - * @test - */ - public function listModulesForPhpListModuleDependencyListsIt() + public function testListModulesForPhpListModuleDependencyListsIt(): void { $rootPackageName = 'phplist/base-distribution'; $dependencyPackageName = 'amazing/listview'; $dependencyPackageVersion = '2.3.6'; - $event = $this->buildMockEvent(); + $event = $this->createMockEvent(); - $this->rootPackageProphecy->getName()->willReturn($rootPackageName); - $this->rootPackageProphecy->getType()->willReturn('project'); + $this->rootPackage->method('getName')->willReturn($rootPackageName); + $this->rootPackage->method('getType')->willReturn('project'); - /** @var PackageInterface|ObjectProphecy $dependencyProphecy */ - $dependencyProphecy = $this->prophesize(PackageInterface::class); - $dependencyProphecy->getName()->willReturn($dependencyPackageName); - $dependencyProphecy->getType()->willReturn('phplist-module'); - $dependencyProphecy->getPrettyVersion()->willReturn($dependencyPackageVersion); + $dependency = $this->createMock(PackageInterface::class); + $dependency->method('getName')->willReturn($dependencyPackageName); + $dependency->method('getType')->willReturn('phplist-module'); + $dependency->method('getPrettyVersion')->willReturn($dependencyPackageVersion); - /** @var PackageInterface|ProphecySubjectInterface $dependency */ - $dependency = $dependencyProphecy->reveal(); - $this->localRepositoryProphecy->getPackages()->willReturn([$dependency]); + $this->localRepository->method('getPackages')->willReturn([$dependency]); ScriptHandler::listModules($event); - $this->expectOutputRegex('#' . $dependencyPackageName . ' +' . $dependencyPackageVersion . '#'); + $this->expectOutputRegex( + '/' + . preg_quote($dependencyPackageName, '/') + . '\s+' + . preg_quote($dependencyPackageVersion, '/') + . '/' + ); } - /** - * @test - */ - public function listModulesForNonPhpListModuleDependencyExcludesIt() + public function testListModulesForNonPhpListModuleDependencyExcludesIt(): void { $rootPackageName = 'phplist/base-distribution'; $dependencyPackageName = 'symfony/symfony'; - $event = $this->buildMockEvent(); + $event = $this->createMockEvent(); - $this->rootPackageProphecy->getName()->willReturn($rootPackageName); - $this->rootPackageProphecy->getType()->willReturn('project'); + $this->rootPackage->method('getName')->willReturn($rootPackageName); + $this->rootPackage->method('getType')->willReturn('project'); - /** @var PackageInterface|ObjectProphecy $dependencyProphecy */ - $dependencyProphecy = $this->prophesize(PackageInterface::class); - $dependencyProphecy->getName()->willReturn($dependencyPackageName); - $dependencyProphecy->getType()->willReturn('library'); + $dependency = $this->createMock(PackageInterface::class); + $dependency->method('getName')->willReturn($dependencyPackageName); + $dependency->method('getType')->willReturn('library'); - /** @var PackageInterface|ProphecySubjectInterface $dependency */ - $dependency = $dependencyProphecy->reveal(); - $this->localRepositoryProphecy->getPackages()->willReturn([$dependency]); + $this->localRepository->method('getPackages')->willReturn([$dependency]); ScriptHandler::listModules($event); $output = $this->getActualOutput(); - static::assertNotContains($dependencyPackageName, $output); + self::assertStringNotContainsString($dependencyPackageName, $output); } - /** - * @return Event - */ - private function buildMockEvent(): Event + private function createMockEventForCorePackage(): Event { - /** @var Composer|ObjectProphecy $composerProphecy */ - $composerProphecy = $this->prophesize(Composer::class); - /** @var Composer|ProphecySubjectInterface $composer */ - $composer = $composerProphecy->reveal(); - - /** @var RepositoryManager|ObjectProphecy $repositoryManagerProphecy */ - $repositoryManagerProphecy = $this->prophesize(RepositoryManager::class); - /** @var RepositoryManager|ProphecySubjectInterface $repositoryManager */ - $repositoryManager = $repositoryManagerProphecy->reveal(); - $composerProphecy->getRepositoryManager()->willReturn($repositoryManager); - - $this->localRepositoryProphecy = $this->prophesize(WritableRepositoryInterface::class); - /** @var WritableRepositoryInterface|ProphecySubjectInterface $localRepository */ - $localRepository = $this->localRepositoryProphecy->reveal(); - $repositoryManagerProphecy->getLocalRepository()->willReturn($localRepository); - - /** @var RootPackageInterface|ObjectProphecy $rootPackageProphecy */ - $rootPackageProphecy = $this->prophesize(RootPackageInterface::class); - /** @var RootPackageInterface|ProphecySubjectInterface $rootPackage */ - $rootPackage = $rootPackageProphecy->reveal(); - $composerProphecy->getPackage()->willReturn($rootPackage); - $this->rootPackageProphecy = $rootPackageProphecy; - - /** @var Event|ObjectProphecy $eventProphecy */ - $eventProphecy = $this->prophesize(Event::class); - $eventProphecy->getComposer()->willReturn($composer); - /** @var Event|ProphecySubjectInterface $eventProphecy */ - $event = $eventProphecy->reveal(); + $this->rootPackage = $this->createMock(RootPackageInterface::class); + + $composer = $this->createMock(Composer::class); + $composer->method('getPackage')->willReturn($this->rootPackage); + + $repositoryManager = $this->createMock(RepositoryManager::class); + $composer->method('getRepositoryManager')->willReturn($repositoryManager); + + $this->localRepository = $this->createMock(InstalledRepositoryInterface::class); + $repositoryManager->method('getLocalRepository')->willReturn($this->localRepository); + + $event = $this->createMock(Event::class); + $event->method('getComposer')->willReturn($composer); + + return $event; + } + + private function createMockEvent(): Event + { + $this->rootPackage = $this->createMock(RootPackageInterface::class); + $composer = $this->createMock(Composer::class); + $composer->method('getPackage')->willReturn($this->rootPackage); + + $repositoryManager = $this->createMock(RepositoryManager::class); + $composer->method('getRepositoryManager')->willReturn($repositoryManager); + + $this->localRepository = $this->createMock(InstalledRepositoryInterface::class); + $repositoryManager->method('getLocalRepository')->willReturn($this->localRepository); + + $event = $this->createMock(Event::class); + $event->method('getComposer')->willReturn($composer); return $event; } diff --git a/tests/Unit/Core/ApplicationKernelTest.php b/tests/Unit/Core/ApplicationKernelTest.php index f3ca7f01..47b08442 100644 --- a/tests/Unit/Core/ApplicationKernelTest.php +++ b/tests/Unit/Core/ApplicationKernelTest.php @@ -1,16 +1,16 @@ subject = new ApplicationKernel(Environment::TESTING, true); } - protected function tearDown() + protected function tearDown(): void { Bootstrap::purgeInstance(); } - /** - * @test - */ - public function isKernelInstance() + public function testIsKernelInstance(): void { - static::assertInstanceOf(Kernel::class, $this->subject); + self::assertInstanceOf(Kernel::class, $this->subject); } - /** - * @test - */ - public function registerBundlesReturnsBundlesOnly() + public function testRegisterBundlesReturnsBundlesOnly(): void { $bundles = $this->subject->registerBundles(); - static::assertContainsOnlyInstancesOf(BundleInterface::class, $bundles); + self::assertContainsOnlyInstancesOf(BundleInterface::class, $bundles); } /** - * @return string[][] + * @return array */ public function requiredBundlesDataProvider(): array { return [ 'framework' => [FrameworkBundle::class], - 'phpList default bundle' => [PhpListEmptyStartPageBundle::class], - 'web server' => [WebServerBundle::class], + 'phpList default bundle' => [EmptyStartPageBundle::class], ]; } /** * @test - * @param string $className * @dataProvider requiredBundlesDataProvider */ - public function registerBundlesHasAllRequiredBundles(string $className) + public function testRegisterBundlesHasAllRequiredBundles(string $className): void { $bundles = $this->subject->registerBundles(); - static::assertContainsInstanceOf($className, $bundles); + self::assertContainsInstanceOf($className, $bundles); } } diff --git a/tests/Unit/Core/ApplicationStructureTest.php b/tests/Unit/Core/ApplicationStructureTest.php index e9d7155a..fa2c8422 100644 --- a/tests/Unit/Core/ApplicationStructureTest.php +++ b/tests/Unit/Core/ApplicationStructureTest.php @@ -1,4 +1,5 @@ subject = new ApplicationStructure(); } - /** - * @test - */ - public function getApplicationRootReturnsCoreApplicationRoot() + public function testGetApplicationRootReturnsCoreApplicationRoot(): void { - static::assertSame(dirname(__DIR__, 3), $this->subject->getApplicationRoot()); + self::assertSame(dirname(__DIR__, 3), $this->subject->getApplicationRoot()); } - /** - * @test - */ - public function getCorePackageRootReturnsCorePackageRoot() + public function testGetCorePackageRootReturnsCorePackageRoot(): void { - static::assertSame(dirname(__DIR__, 3), $this->subject->getCorePackageRoot()); + self::assertSame(dirname(__DIR__, 3), $this->subject->getCorePackageRoot()); } } diff --git a/tests/Unit/Core/BootstrapTest.php b/tests/Unit/Core/BootstrapTest.php index 3e92c8cb..4c1385a5 100644 --- a/tests/Unit/Core/BootstrapTest.php +++ b/tests/Unit/Core/BootstrapTest.php @@ -1,4 +1,5 @@ subject = Bootstrap::getInstance(); $this->subject->setEnvironment(Environment::TESTING); } - protected function tearDown() + protected function tearDown(): void { Bootstrap::purgeInstance(); } - /** - * @test - */ - public function getInstanceReturnsBootstrapInstance() + public function testGetInstanceReturnsBootstrapInstance(): void { - static::assertInstanceOf(Bootstrap::class, Bootstrap::getInstance()); + self::assertInstanceOf(Bootstrap::class, Bootstrap::getInstance()); } - /** - * @test - */ - public function classIsSingleton() + public function testClassIsSingleton(): void { - static::assertSame(Bootstrap::getInstance(), Bootstrap::getInstance()); + self::assertSame(Bootstrap::getInstance(), Bootstrap::getInstance()); } - /** - * @test - */ - public function purgeInstancePurgesSingletonInstance() + public function testPurgeInstancePurgesSingletonInstance(): void { $firstInstance = Bootstrap::getInstance(); Bootstrap::purgeInstance(); $secondInstance = Bootstrap::getInstance(); - static::assertNotSame($firstInstance, $secondInstance); + self::assertNotSame($firstInstance, $secondInstance); } - /** - * @test - */ - public function environmentIsProductionByDefault() + public function testEnvironmentIsProductionByDefault(): void { Bootstrap::purgeInstance(); $subject = Bootstrap::getInstance(); - static::assertSame(Environment::PRODUCTION, $subject->getEnvironment()); + self::assertSame(Environment::PRODUCTION, $subject->getEnvironment()); } - /** - * @test - */ - public function setEnvironmentHasFluentInterface() + public function testSetEnvironmentHasFluentInterface(): void { - static::assertSame($this->subject, $this->subject->setEnvironment(Environment::TESTING)); + self::assertSame($this->subject, $this->subject->setEnvironment(Environment::TESTING)); } /** - * @return string[][] + * @return array */ public function validEnvironmentDataProvider(): array { @@ -95,92 +78,66 @@ public function validEnvironmentDataProvider(): array } /** - * @test - * @param string $environment * @dataProvider validEnvironmentDataProvider */ - public function setEnvironmentWithValidEnvironmentSetsEnvironment(string $environment) + public function testSetEnvironmentWithValidEnvironmentSetsEnvironment(string $environment): void { $this->subject->setEnvironment($environment); - static::assertSame($environment, $this->subject->getEnvironment()); + self::assertSame($environment, $this->subject->getEnvironment()); } - /** - * @test - */ - public function setEnvironmentWithInvalidEnvironmentThrowsException() + public function testSetEnvironmentWithInvalidEnvironmentThrowsException(): void { $this->expectException(\UnexpectedValueException::class); $this->subject->setEnvironment('Reckless'); } - /** - * @test - */ - public function configureHasFluentInterface() + public function testConfigureHasFluentInterface(): void { - static::assertSame($this->subject, $this->subject->configure()); + self::assertSame($this->subject, $this->subject->configure()); } - /** - * @test - */ - public function configureCreatesApplicationKernel() + public function testConfigureCreatesApplicationKernel(): void { $this->subject->configure(); - static::assertInstanceOf(ApplicationKernel::class, $this->subject->getApplicationKernel()); + self::assertInstanceOf(ApplicationKernel::class, $this->subject->getApplicationKernel()); } - /** - * @test - */ - public function getApplicationKernelWithoutConfigureThrowsException() + public function testGetApplicationKernelWithoutConfigureThrowsException(): void { $this->expectException(\RuntimeException::class); $this->subject->getApplicationKernel(); } - /** - * @test - */ - public function dispatchWithoutConfigureThrowsException() + public function testDispatchWithoutConfigureThrowsException(): void { $this->expectException(\RuntimeException::class); $this->subject->dispatch(); } - /** - * @test - */ - public function getContainerReturnsContainer() + public function testGetContainerReturnsContainer(): void { $this->subject->configure(); - static::assertInstanceOf(ContainerInterface::class, $this->subject->getContainer()); + self::assertInstanceOf(ContainerInterface::class, $this->subject->getContainer()); } - /** - * @test - */ - public function getEntityManagerWithoutConfigureThrowsException() + public function testGetEntityManagerWithoutConfigureThrowsException(): void { $this->expectException(\RuntimeException::class); $this->subject->getEntityManager(); } - /** - * @test - */ - public function getEntityManagerAfterConfigureReturnsEntityManager() + public function testGetEntityManagerAfterConfigureReturnsEntityManager(): void { $this->subject->configure(); - static::assertInstanceOf(EntityManagerInterface::class, $this->subject->getEntityManager()); + self::assertInstanceOf(EntityManagerInterface::class, $this->subject->getEntityManager()); } } diff --git a/tests/Unit/Core/EnvironmentTest.php b/tests/Unit/Core/EnvironmentTest.php index 8fa1c3b6..7ac06169 100644 --- a/tests/Unit/Core/EnvironmentTest.php +++ b/tests/Unit/Core/EnvironmentTest.php @@ -1,4 +1,5 @@ */ public function validEnvironmentDataProvider(): array { @@ -34,23 +32,17 @@ public function validEnvironmentDataProvider(): array } /** - * @test - * @param string $environment * @dataProvider validEnvironmentDataProvider */ - public function validateEnvironmentForValidEnvironmentPasses(string $environment) + public function testValidateEnvironmentForValidEnvironmentPasses(string $environment): void { Environment::validateEnvironment($environment); - // This is to avoid a warning in PHPUnit that this test has no assertions (as there is no assertion - // for "no exception is thrown"). - static::assertTrue(true); + // Adding an assertion to confirm the method executes without throwing an exception. + self::assertTrue(true); } - /** - * @test - */ - public function validateEnvironmentForInvalidEnvironmentThrowsException() + public function testValidateEnvironmentForInvalidEnvironmentThrowsException(): void { $environment = 'home'; diff --git a/tests/Unit/Domain/Model/Identity/AdministratorTest.php b/tests/Unit/Domain/Model/Identity/AdministratorTest.php index c1d63418..4bdca7dc 100644 --- a/tests/Unit/Domain/Model/Identity/AdministratorTest.php +++ b/tests/Unit/Domain/Model/Identity/AdministratorTest.php @@ -1,4 +1,5 @@ subject = new Administrator(); } - /** - * @test - */ - public function isDomainModel() - { - static::assertInstanceOf(DomainModel::class, $this->subject); - } - - /** - * @test - */ - public function getIdInitiallyReturnsZero() + public function testIsDomainModel(): void { - static::assertSame(0, $this->subject->getId()); + self::assertInstanceOf(DomainModel::class, $this->subject); } - /** - * @test - */ - public function getIdReturnsId() + public function testGetIdReturnsId(): void { $id = 123456; - $this->setSubjectId($id); + $this->setSubjectId($this->subject, $id); - static::assertSame($id, $this->subject->getId()); + self::assertSame($id, $this->subject->getId()); } - /** - * @test - */ - public function getLoginNameInitiallyReturnsEmptyString() + public function testGetLoginNameInitiallyReturnsEmptyString(): void { - static::assertSame('', $this->subject->getLoginName()); + self::assertSame('', $this->subject->getLoginName()); } - /** - * @test - */ - public function setLoginNameSetsLoginName() + public function testSetLoginNameSetsLoginName(): void { $value = 'jane.doe'; $this->subject->setLoginName($value); - static::assertSame($value, $this->subject->getLoginName()); + self::assertSame($value, $this->subject->getLoginName()); } - /** - * @test - */ - public function getEmailAddressInitiallyReturnsEmptyString() + public function testGetEmailAddressInitiallyReturnsEmptyString(): void { - static::assertSame('', $this->subject->getEmailAddress()); + self::assertSame('', $this->subject->getEmailAddress()); } - /** - * @test - */ - public function setEmailAddressSetsEmailAddress() + public function testSetEmailAddressSetsEmailAddress(): void { $value = 'oliver@example.com'; $this->subject->setEmailAddress($value); - static::assertSame($value, $this->subject->getEmailAddress()); + self::assertSame($value, $this->subject->getEmailAddress()); } - /** - * @test - */ - public function getCreationDateInitiallyReturnsNull() + public function testGetCreationDateInitiallyReturnsNull(): void { - static::assertNull($this->subject->getCreationDate()); + self::assertNull($this->subject->getCreationDate()); } - /** - * @test - */ - public function updateCreationDateSetsCreationDateToNow() + public function testUpdateCreationDateSetsCreationDateToNow(): void { $this->subject->updateCreationDate(); - static::assertSimilarDates(new \DateTime(), $this->subject->getCreationDate()); + self::assertSimilarDates(new \DateTime(), $this->subject->getCreationDate()); } - /** - * @test - */ - public function getModificationDateInitiallyReturnsNull() + public function testGetModificationDateInitiallyReturnsNull(): void { - static::assertNull($this->subject->getModificationDate()); + self::assertNull($this->subject->getModificationDate()); } - /** - * @test - */ - public function updateModificationDateSetsModificationDateToNow() + public function testUpdateModificationDateSetsModificationDateToNow(): void { $this->subject->updateModificationDate(); - static::assertSimilarDates(new \DateTime(), $this->subject->getModificationDate()); + self::assertSimilarDates(new \DateTime(), $this->subject->getModificationDate()); } - /** - * @test - */ - public function getPasswordHashInitiallyReturnsEmptyString() + public function testGetPasswordHashInitiallyReturnsEmptyString(): void { - static::assertSame('', $this->subject->getPasswordHash()); + self::assertSame('', $this->subject->getPasswordHash()); } - /** - * @test - */ - public function setPasswordHashSetsPasswordHash() + public function testSetPasswordHashSetsPasswordHash(): void { $value = 'Club-Mate'; $this->subject->setPasswordHash($value); - static::assertSame($value, $this->subject->getPasswordHash()); + self::assertSame($value, $this->subject->getPasswordHash()); } - /** - * @test - */ - public function getPasswordChangeDateInitiallyReturnsNull() + public function testGetPasswordChangeDateInitiallyReturnsNull(): void { - static::assertNull($this->subject->getPasswordChangeDate()); + self::assertNull($this->subject->getPasswordChangeDate()); } - /** - * @test - */ - public function setPasswordHashSetsPasswordChangeDateToNow() + public function testSetPasswordHashSetsPasswordChangeDateToNow(): void { $date = new \DateTime(); $this->subject->setPasswordHash('Zaphod Beeblebrox'); - static::assertSimilarDates($date, $this->subject->getPasswordChangeDate()); + self::assertSimilarDates($date, $this->subject->getPasswordChangeDate()); } - /** - * @test - */ - public function isDisabledInitiallyReturnsFalse() + public function testIsDisabledInitiallyReturnsFalse(): void { - static::assertFalse($this->subject->isDisabled()); + self::assertFalse($this->subject->isDisabled()); } - /** - * @test - */ - public function setDisabledSetsDisabled() + public function testSetDisabledSetsDisabled(): void { $this->subject->setDisabled(true); - static::assertTrue($this->subject->isDisabled()); + self::assertTrue($this->subject->isDisabled()); } - /** - * @test - */ - public function isSuperUserInitiallyReturnsFalse() + public function testIsSuperUserInitiallyReturnsFalse(): void { - static::assertFalse($this->subject->isSuperUser()); + self::assertFalse($this->subject->isSuperUser()); } - /** - * @test - */ - public function setSuperUserSetsSuperUser() + public function testSetSuperUserSetsSuperUser(): void { $this->subject->setSuperUser(true); - static::assertTrue($this->subject->isSuperUser()); + self::assertTrue($this->subject->isSuperUser()); } } diff --git a/tests/Unit/Domain/Model/Identity/AdministratorTokenTest.php b/tests/Unit/Domain/Model/Identity/AdministratorTokenTest.php index b4010c76..f28a2d70 100644 --- a/tests/Unit/Domain/Model/Identity/AdministratorTokenTest.php +++ b/tests/Unit/Domain/Model/Identity/AdministratorTokenTest.php @@ -1,8 +1,10 @@ subject = new AdministratorToken(); } - /** - * @test - */ - public function isDomainModel() - { - static::assertInstanceOf(DomainModel::class, $this->subject); - } - - /** - * @test - */ - public function getIdInitiallyReturnsZero() + public function testIsDomainModel(): void { - static::assertSame(0, $this->subject->getId()); + self::assertInstanceOf(DomainModel::class, $this->subject); } - /** - * @test - */ - public function getIdReturnsId() + public function testGetIdReturnsId(): void { $id = 123456; - $this->setSubjectId($id); + $this->setSubjectId($this->subject, $id); - static::assertSame($id, $this->subject->getId()); + self::assertSame($id, $this->subject->getId()); } - /** - * @test - */ - public function getCreationDateInitiallyReturnsNull() + public function testGetCreationDateInitiallyReturnsNull(): void { - static::assertNull($this->subject->getCreationDate()); + self::assertNull($this->subject->getCreationDate()); } - /** - * @test - */ - public function updateCreationDateSetsCreationDateToNow() + public function testUpdateCreationDateSetsCreationDateToNow(): void { $this->subject->updateCreationDate(); - static::assertSimilarDates(new \DateTime(), $this->subject->getCreationDate()); + self::assertSimilarDates(new DateTime(), $this->subject->getCreationDate()); } - /** - * @test - */ - public function getKeyInitiallyReturnsEmptyString() + public function testGetKeyInitiallyReturnsEmptyString(): void { - static::assertSame('', $this->subject->getKey()); + self::assertSame('', $this->subject->getKey()); } - /** - * @test - */ - public function setKeySetsKey() + public function testSetKeySetsKey(): void { $value = 'Club-Mate'; $this->subject->setKey($value); - static::assertSame($value, $this->subject->getKey()); + self::assertSame($value, $this->subject->getKey()); } - /** - * @test - */ - public function getExpiryInitiallyReturnsDateTime() + public function testGetExpiryInitiallyReturnsDateTime(): void { - static::assertInstanceOf(\DateTime::class, $this->subject->getExpiry()); + self::assertInstanceOf(DateTime::class, $this->subject->getExpiry()); } - /** - * @test - */ - public function generateExpirySetsExpiryOneHourInTheFuture() + public function testGenerateExpirySetsExpiryOneHourInTheFuture(): void { $this->subject->generateExpiry(); - static::assertSimilarDates(new \DateTime('+1 hour'), $this->subject->getExpiry()); + self::assertSimilarDates(new DateTime('+1 hour'), $this->subject->getExpiry()); } - /** - * @test - */ - public function generateKeyCreates32CharacterKey() + public function testGenerateKeyCreates32CharacterKey(): void { $this->subject->generateKey(); - static::assertRegExp('/^[a-z0-9]{32}$/', $this->subject->getKey()); + self::assertMatchesRegularExpression('/^[a-z0-9]{32}$/', $this->subject->getKey()); } - /** - * @test - */ - public function generateKeyCreatesDifferentKeysForEachCall() + public function testGenerateKeyCreatesDifferentKeysForEachCall(): void { $this->subject->generateKey(); $firstKey = $this->subject->getKey(); @@ -133,25 +94,19 @@ public function generateKeyCreatesDifferentKeysForEachCall() $this->subject->generateKey(); $secondKey = $this->subject->getKey(); - static::assertNotSame($firstKey, $secondKey); + self::assertNotSame($firstKey, $secondKey); } - /** - * @test - */ - public function getAdministratorInitiallyReturnsNull() + public function testGetAdministratorInitiallyReturnsNull(): void { - static::assertNull($this->subject->getAdministrator()); + self::assertNull($this->subject->getAdministrator()); } - /** - * @test - */ - public function setAdministratorSetsAdministrator() + public function testSetAdministratorSetsAdministrator(): void { $model = new Administrator(); $this->subject->setAdministrator($model); - static::assertSame($model, $this->subject->getAdministrator()); + self::assertSame($model, $this->subject->getAdministrator()); } } diff --git a/tests/Unit/Domain/Model/Messaging/SubscriberListTest.php b/tests/Unit/Domain/Model/Messaging/SubscriberListTest.php index a762cab7..eb8209c5 100644 --- a/tests/Unit/Domain/Model/Messaging/SubscriberListTest.php +++ b/tests/Unit/Domain/Model/Messaging/SubscriberListTest.php @@ -1,13 +1,17 @@ subject = new SubscriberList(); - } + private SubscriberList $subscriberList; - /** - * @test - */ - public function isDomainModel() + protected function setUp(): void { - static::assertInstanceOf(DomainModel::class, $this->subject); + $this->subscriberList = new SubscriberList(); } - /** - * @test - */ - public function getIdInitiallyReturnsZero() + public function testIsDomainModel(): void { - static::assertSame(0, $this->subject->getId()); + self::assertInstanceOf(DomainModel::class, $this->subscriberList); } - /** - * @test - */ - public function getIdReturnsId() + public function testGetIdReturnsId(): void { $id = 123456; - $this->setSubjectId($id); + $this->setSubjectId($this->subscriberList, $id); - static::assertSame($id, $this->subject->getId()); + self::assertSame($id, $this->subscriberList->getId()); } - /** - * @test - */ - public function getCreationDateInitiallyReturnsNull() + public function testGetCreationDateInitiallyReturnsNull(): void { - static::assertNull($this->subject->getCreationDate()); + self::assertNull($this->subscriberList->getCreationDate()); } - /** - * @test - */ - public function updateCreationDateSetsCreationDateToNow() + public function testUpdateCreationDateSetsCreationDateToNow(): void { - $this->subject->updateCreationDate(); + $this->subscriberList->updateCreationDate(); - static::assertSimilarDates(new \DateTime(), $this->subject->getCreationDate()); + self::assertSimilarDates(new DateTime(), $this->subscriberList->getCreationDate()); } - /** - * @test - */ - public function getModificationDateInitiallyReturnsNull() + public function testGetModificationDateInitiallyReturnsNull(): void { - static::assertNull($this->subject->getModificationDate()); + self::assertNull($this->subscriberList->getModificationDate()); } - /** - * @test - */ - public function updateModificationDateSetsModificationDateToNow() + public function testUpdateModificationDateSetsModificationDateToNow(): void { - $this->subject->updateModificationDate(); + $this->subscriberList->updateModificationDate(); - static::assertSimilarDates(new \DateTime(), $this->subject->getModificationDate()); + self::assertSimilarDates(new DateTime(), $this->subscriberList->getModificationDate()); } - /** - * @test - */ - public function getNameInitiallyReturnsEmptyString() + public function testGetNameInitiallyReturnsEmptyString(): void { - static::assertSame('', $this->subject->getName()); + self::assertSame('', $this->subscriberList->getName()); } - /** - * @test - */ - public function setNameSetsName() + public function testSetNameSetsName(): void { $value = 'phpList releases'; - $this->subject->setName($value); + $this->subscriberList->setName($value); - static::assertSame($value, $this->subject->getName()); + self::assertSame($value, $this->subscriberList->getName()); } - /** - * @test - */ - public function getDescriptionInitiallyReturnsEmptyString() + public function testGetDescriptionInitiallyReturnsEmptyString(): void { - static::assertSame('', $this->subject->getDescription()); + self::assertSame('', $this->subscriberList->getDescription()); } - /** - * @test - */ - public function setDescriptionSetsDescription() + public function testSetDescriptionSetsDescription(): void { $value = 'Subscribe to this list when you would like to be notified of new phpList releases.'; - $this->subject->setDescription($value); + $this->subscriberList->setDescription($value); - static::assertSame($value, $this->subject->getDescription()); + self::assertSame($value, $this->subscriberList->getDescription()); } - /** - * @test - */ - public function getListPositionInitiallyReturnsZero() + public function testGetListPositionInitiallyReturnsZero(): void { - static::assertSame(0, $this->subject->getListPosition()); + self::assertSame(0, $this->subscriberList->getListPosition()); } - /** - * @test - */ - public function setListPositionSetsListPosition() + public function testSetListPositionSetsListPosition(): void { $value = 123456; - $this->subject->setListPosition($value); + $this->subscriberList->setListPosition($value); - static::assertSame($value, $this->subject->getListPosition()); + self::assertSame($value, $this->subscriberList->getListPosition()); } - /** - * @test - */ - public function getSubjectPrefixInitiallyReturnsEmptyString() + public function testGetSubjectPrefixInitiallyReturnsEmptyString(): void { - static::assertSame('', $this->subject->getSubjectPrefix()); + self::assertSame('', $this->subscriberList->getSubjectPrefix()); } - /** - * @test - */ - public function setSubjectPrefixSetsSubjectPrefix() + public function testSetSubjectPrefixSetsSubjectPrefix(): void { $value = 'Club-Mate'; - $this->subject->setSubjectPrefix($value); + $this->subscriberList->setSubjectPrefix($value); - static::assertSame($value, $this->subject->getSubjectPrefix()); + self::assertSame($value, $this->subscriberList->getSubjectPrefix()); } - /** - * @test - */ - public function isPublicInitiallyReturnsFalse() + public function testIsPublicInitiallyReturnsFalse(): void { - static::assertFalse($this->subject->isPublic()); + self::assertFalse($this->subscriberList->isPublic()); } - /** - * @test - */ - public function setPublicSetsPublic() + public function testSetPublicSetsPublic(): void { - $this->subject->setPublic(true); + $this->subscriberList->setPublic(true); - static::assertTrue($this->subject->isPublic()); + self::assertTrue($this->subscriberList->isPublic()); } - /** - * @test - */ - public function getCategoryInitiallyReturnsEmptyString() + public function testGetCategoryInitiallyReturnsEmptyString(): void { - static::assertSame('', $this->subject->getCategory()); + self::assertSame('', $this->subscriberList->getCategory()); } - /** - * @test - */ - public function setCategorySetsCategory() + public function testSetCategorySetsCategory(): void { $value = 'Club-Mate'; - $this->subject->setCategory($value); + $this->subscriberList->setCategory($value); - static::assertSame($value, $this->subject->getCategory()); + self::assertSame($value, $this->subscriberList->getCategory()); } - /** - * @test - */ - public function getOwnerInitiallyReturnsNull() + public function testGetOwnerInitiallyReturnsNull(): void { - static::assertNull($this->subject->getOwner()); + self::assertNull($this->subscriberList->getOwner()); } - /** - * @test - */ - public function setOwnerSetsOwner() + public function testSetOwnerSetsOwner(): void { $model = new Administrator(); - $this->subject->setOwner($model); + $this->subscriberList->setOwner($model); - static::assertSame($model, $this->subject->getOwner()); + self::assertSame($model, $this->subscriberList->getOwner()); } - /** - * @test - */ - public function getSubscriptionsByDefaultReturnsEmptyCollection() + public function testGetSubscriptionsByDefaultReturnsEmptyCollection(): void { - $result = $this->subject->getSubscriptions(); + $result = $this->subscriberList->getSubscriptions(); - static::assertInstanceOf(Collection::class, $result); - static::assertTrue($result->isEmpty()); + self::assertInstanceOf(Collection::class, $result); + self::assertTrue($result->isEmpty()); } - /** - * @test - */ - public function setSubscriptionsSetsSubscriptions() + public function testAddSubscriptionsSetsSubscriptions(): void { - $subscriptions = new ArrayCollection(); + $subscription = new Subscription(); - $this->subject->setSubscriptions($subscriptions); + $this->subscriberList->addSubscription($subscription); - static::assertSame($subscriptions, $this->subject->getSubscriptions()); + self::assertTrue($this->subscriberList->getSubscriptions()->contains($subscription)); } - /** - * @test - */ - public function getSubscribersByDefaultReturnsEmptyCollection() + public function testGetSubscribersByDefaultReturnsEmptyCollection(): void { - $result = $this->subject->getSubscribers(); + $result = $this->subscriberList->getSubscribers(); - static::assertInstanceOf(Collection::class, $result); - static::assertTrue($result->isEmpty()); + self::assertInstanceOf(Collection::class, $result); + self::assertTrue($result->isEmpty()); } - /** - * @test - */ - public function setSubscribersSetsSubscribers() + public function testSetSubscribersSetsSubscribers(): void { - $subscriptions = new ArrayCollection(); + $subscriber = new Subscriber(); + $subscription = new Subscription(); + $subscription->setSubscriber($subscriber); - $this->subject->setSubscribers($subscriptions); + $this->subscriberList->addSubscription($subscription); - static::assertSame($subscriptions, $this->subject->getSubscribers()); + self::assertTrue($this->subscriberList->getSubscribers()->contains($subscriber)); } } diff --git a/tests/Unit/Domain/Model/Subscription/SubscriberTest.php b/tests/Unit/Domain/Model/Subscription/SubscriberTest.php index 193a5955..edac5790 100644 --- a/tests/Unit/Domain/Model/Subscription/SubscriberTest.php +++ b/tests/Unit/Domain/Model/Subscription/SubscriberTest.php @@ -1,4 +1,5 @@ subject = new Subscriber(); - } + private Subscriber $subscriber; - /** - * @test - */ - public function isDomainModel() + protected function setUp(): void { - static::assertInstanceOf(DomainModel::class, $this->subject); + $this->subscriber = new Subscriber(); } - /** - * @test - */ - public function getIdInitiallyReturnsZero() + public function testIsDomainModel(): void { - static::assertSame(0, $this->subject->getId()); + self::assertInstanceOf(DomainModel::class, $this->subscriber); } - /** - * @test - */ - public function getIdReturnsId() + public function testGetIdReturnsId(): void { $id = 123456; - $this->setSubjectId($id); + $this->setSubjectId($this->subscriber, $id); - static::assertSame($id, $this->subject->getId()); + self::assertSame($id, $this->subscriber->getId()); } - /** - * @test - */ - public function getCreationDateInitiallyReturnsNull() + public function testGetCreationDateInitiallyReturnsNull(): void { - static::assertNull($this->subject->getCreationDate()); + self::assertNull($this->subscriber->getCreationDate()); } - /** - * @test - */ - public function updateCreationDateSetsCreationDateToNow() + public function testUpdateCreationDateSetsCreationDateToNow(): void { - $this->subject->updateCreationDate(); + $this->subscriber->updateCreationDate(); - static::assertSimilarDates(new \DateTime(), $this->subject->getCreationDate()); + self::assertSimilarDates(new \DateTime(), $this->subscriber->getCreationDate()); } - /** - * @test - */ - public function getModificationDateInitiallyReturnsNull() + public function testGetModificationDateInitiallyReturnsNull(): void { - static::assertNull($this->subject->getModificationDate()); + self::assertNull($this->subscriber->getModificationDate()); } - /** - * @test - */ - public function updateModificationDateSetsModificationDateToNow() + public function testUpdateModificationDateSetsModificationDateToNow(): void { - $this->subject->updateModificationDate(); + $this->subscriber->updateModificationDate(); - static::assertSimilarDates(new \DateTime(), $this->subject->getModificationDate()); + self::assertSimilarDates(new \DateTime(), $this->subscriber->getModificationDate()); } - /** - * @test - */ - public function getEmailInitiallyReturnsEmptyString() + public function testGetEmailInitiallyReturnsEmptyString(): void { - static::assertSame('', $this->subject->getEmail()); + self::assertSame('', $this->subscriber->getEmail()); } - /** - * @test - */ - public function setEmailSetsEmail() + public function testSetEmailSetsEmail(): void { $value = 'Club-Mate'; - $this->subject->setEmail($value); + $this->subscriber->setEmail($value); - static::assertSame($value, $this->subject->getEmail()); + self::assertSame($value, $this->subscriber->getEmail()); } - /** - * @test - */ - public function isConfirmedInitiallyReturnsFalse() + public function testIsConfirmedInitiallyReturnsFalse(): void { - static::assertFalse($this->subject->isConfirmed()); + self::assertFalse($this->subscriber->isConfirmed()); } - /** - * @test - */ - public function setConfirmedSetsConfirmed() + public function testSetConfirmedSetsConfirmed(): void { - $this->subject->setConfirmed(true); + $this->subscriber->setConfirmed(true); - static::assertTrue($this->subject->isConfirmed()); + self::assertTrue($this->subscriber->isConfirmed()); } - /** - * @test - */ - public function isBlacklistedInitiallyReturnsFalse() + public function testIsBlacklistedInitiallyReturnsFalse(): void { - static::assertFalse($this->subject->isBlacklisted()); + self::assertFalse($this->subscriber->isBlacklisted()); } - /** - * @test - */ - public function setBlacklistedSetsBlacklisted() + public function testSetBlacklistedSetsBlacklisted(): void { - $this->subject->setBlacklisted(true); + $this->subscriber->setBlacklisted(true); - static::assertTrue($this->subject->isBlacklisted()); + self::assertTrue($this->subscriber->isBlacklisted()); } - /** - * @test - */ - public function getBounceCountInitiallyReturnsZero() + public function testGetBounceCountInitiallyReturnsZero(): void { - static::assertSame(0, $this->subject->getBounceCount()); + self::assertSame(0, $this->subscriber->getBounceCount()); } - /** - * @test - */ - public function setBounceCountSetsBounceCount() + public function testSetBounceCountSetsBounceCount(): void { $value = 123456; - $this->subject->setBounceCount($value); + $this->subscriber->setBounceCount($value); - static::assertSame($value, $this->subject->getBounceCount()); + self::assertSame($value, $this->subscriber->getBounceCount()); } - /** - * @test - */ - public function addToBounceCountAddsToBounceCount() + public function testAddToBounceCountAddsToBounceCount(): void { $initialValue = 4; - $this->subject->setBounceCount($initialValue); + $this->subscriber->setBounceCount($initialValue); $delta = 2; - $this->subject->addToBounceCount($delta); + $this->subscriber->addToBounceCount($delta); - static::assertSame($initialValue + $delta, $this->subject->getBounceCount()); + self::assertSame($initialValue + $delta, $this->subscriber->getBounceCount()); } - /** - * @test - */ - public function getUniqueIdInitiallyReturnsEmptyString() + public function testGetUniqueIdInitiallyReturnsEmptyString(): void { - static::assertSame('', $this->subject->getUniqueId()); + self::assertSame('', $this->subscriber->getUniqueId()); } - /** - * @test - */ - public function setUniqueIdSetsUniqueId() + public function testSetUniqueIdSetsUniqueId(): void { $value = 'Club-Mate'; - $this->subject->setUniqueId($value); + $this->subscriber->setUniqueId($value); - static::assertSame($value, $this->subject->getUniqueId()); + self::assertSame($value, $this->subscriber->getUniqueId()); } - /** - * @test - */ - public function generateUniqueIdGeneratesUniqueId() + public function testGenerateUniqueIdGeneratesUniqueId(): void { - $this->subject->generateUniqueId(); + $this->subscriber->generateUniqueId(); - static::assertRegExp('/^[0-9a-f]{32}$/', $this->subject->getUniqueId()); + self::assertMatchesRegularExpression('/^[0-9a-f]{32}$/', $this->subscriber->getUniqueId()); } - /** - * @test - */ - public function hasHtmlEmailInitiallyReturnsFalse() + public function testHasHtmlEmailInitiallyReturnsFalse(): void { - static::assertFalse($this->subject->hasHtmlEmail()); + self::assertFalse($this->subscriber->hasHtmlEmail()); } - /** - * @test - */ - public function setHtmlEmailSetsWantsHtmlEmail() + public function testSetHtmlEmailSetsWantsHtmlEmail(): void { - $this->subject->setHtmlEmail(true); + $this->subscriber->setHtmlEmail(true); - static::assertTrue($this->subject->hasHtmlEmail()); + self::assertTrue($this->subscriber->hasHtmlEmail()); } - /** - * @test - */ - public function isDisabledInitiallyReturnsFalse() + public function testIsDisabledInitiallyReturnsFalse(): void { - static::assertFalse($this->subject->isDisabled()); + self::assertFalse($this->subscriber->isDisabled()); } - /** - * @test - */ - public function setDisabledSetsDisabled() + public function testSetDisabledSetsDisabled(): void { - $this->subject->setDisabled(true); + $this->subscriber->setDisabled(true); - static::assertTrue($this->subject->isDisabled()); + self::assertTrue($this->subscriber->isDisabled()); } - /** - * @test - */ - public function getExtraDataInitiallyReturnsEmptyString() + public function testGetExtraDataInitiallyReturnsEmptyString(): void { - static::assertSame('', $this->subject->getExtraData()); + self::assertSame('', $this->subscriber->getExtraData()); } - /** - * @test - */ - public function setExtraDataSetsExtraData() + public function testSetExtraDataSetsExtraData(): void { $value = 'This is one of our favourite subscribers.'; - $this->subject->setExtraData($value); + $this->subscriber->setExtraData($value); - static::assertSame($value, $this->subject->getExtraData()); + self::assertSame($value, $this->subscriber->getExtraData()); } - /** - * @test - */ - public function getSubscriptionsByDefaultReturnsEmptyCollection() + public function testGetSubscriptionsByDefaultReturnsEmptyCollection(): void { - $result = $this->subject->getSubscriptions(); + $result = $this->subscriber->getSubscriptions(); - static::assertInstanceOf(Collection::class, $result); - static::assertTrue($result->isEmpty()); + self::assertInstanceOf(Collection::class, $result); + self::assertTrue($result->isEmpty()); } - /** - * @test - */ - public function setSubscriptionsSetsSubscriptions() + public function testSetSubscriptionsSetsSubscriptions(): void { - $subscriptions = new ArrayCollection(); + $subscription = new Subscription(); + + $this->subscriber->addSubscription($subscription); - $this->subject->setSubscriptions($subscriptions); + $expectedSubscriptions = new ArrayCollection([$subscription]); - static::assertSame($subscriptions, $this->subject->getSubscriptions()); + self::assertEquals($expectedSubscriptions, $this->subscriber->getSubscriptions()); } - /** - * @test - */ - public function getSubscribedListsByDefaultReturnsEmptyCollection() + public function testGetSubscribedListsByDefaultReturnsEmptyCollection(): void { - $result = $this->subject->getSubscribedLists(); + $result = $this->subscriber->getSubscribedLists(); - static::assertInstanceOf(Collection::class, $result); - static::assertTrue($result->isEmpty()); + self::assertInstanceOf(Collection::class, $result); + self::assertTrue($result->isEmpty()); } - /** - * @test - */ - public function setSubscribedListsSetsSubscribedLists() + public function testSetSubscribedListsSetsSubscribedLists(): void { - $subscriptions = new ArrayCollection(); + $subscriberList = new SubscriberList(); + $subscription = new Subscription(); + $subscription->setSubscriberList($subscriberList); + + $this->subscriber->addSubscription($subscription); - $this->subject->setSubscribedLists($subscriptions); + $expectedSubscribedLists = new ArrayCollection([$subscriberList]); - static::assertSame($subscriptions, $this->subject->getSubscribedLists()); + self::assertEquals($expectedSubscribedLists, $this->subscriber->getSubscribedLists()); } } diff --git a/tests/Unit/Domain/Model/Subscription/SubscriptionTest.php b/tests/Unit/Domain/Model/Subscription/SubscriptionTest.php index eb0b864c..af1aff86 100644 --- a/tests/Unit/Domain/Model/Subscription/SubscriptionTest.php +++ b/tests/Unit/Domain/Model/Subscription/SubscriptionTest.php @@ -1,8 +1,10 @@ subject = new Subscription(); } - /** - * @test - */ - public function isDomainModel() + public function testIsDomainModel(): void { - static::assertInstanceOf(DomainModel::class, $this->subject); + self::assertInstanceOf(DomainModel::class, $this->subject); } - /** - * @test - */ - public function getSubscriberInitiallyReturnsNull() + public function testGetSubscriberInitiallyReturnsNull(): void { - static::assertNull($this->subject->getSubscriber()); + self::assertNull($this->subject->getSubscriber()); } - /** - * @test - */ - public function setSubscriberSetsSubscriber() + public function testSetSubscriberSetsSubscriber(): void { $model = new Subscriber(); $this->subject->setSubscriber($model); - static::assertSame($model, $this->subject->getSubscriber()); + self::assertSame($model, $this->subject->getSubscriber()); } - /** - * @test - */ - public function getSubscriberListInitiallyReturnsNull() + public function testGetSubscriberListInitiallyReturnsNull(): void { - static::assertNull($this->subject->getSubscriberList()); + self::assertNull($this->subject->getSubscriberList()); } - /** - * @test - */ - public function setSubscriberListSetsSubscriberList() + public function testSetSubscriberListSetsSubscriberList(): void { $model = new SubscriberList(); $this->subject->setSubscriberList($model); - static::assertSame($model, $this->subject->getSubscriberList()); + self::assertSame($model, $this->subject->getSubscriberList()); } - /** - * @test - */ - public function getCreationDateInitiallyReturnsNull() + public function testGetCreationDateInitiallyReturnsNull(): void { - static::assertNull($this->subject->getCreationDate()); + self::assertNull($this->subject->getCreationDate()); } - /** - * @test - */ - public function updateCreationDateSetsCreationDateToNow() + public function testUpdateCreationDateSetsCreationDateToNow(): void { $this->subject->updateCreationDate(); - static::assertSimilarDates(new \DateTime(), $this->subject->getCreationDate()); + self::assertSimilarDates(new DateTime(), $this->subject->getCreationDate()); } - /** - * @test - */ - public function getModificationDateInitiallyReturnsNull() + public function testGetModificationDateInitiallyReturnsNull(): void { - static::assertNull($this->subject->getModificationDate()); + self::assertNull($this->subject->getModificationDate()); } - /** - * @test - */ - public function updateModificationDateSetsModificationDateToNow() + public function testUpdateModificationDateSetsModificationDateToNow(): void { $this->subject->updateModificationDate(); - static::assertSimilarDates(new \DateTime(), $this->subject->getModificationDate()); + self::assertSimilarDates(new DateTime(), $this->subject->getModificationDate()); } } diff --git a/tests/Unit/Domain/Repository/Identity/AdministratorRepositoryTest.php b/tests/Unit/Domain/Repository/Identity/AdministratorRepositoryTest.php index 42a03e0c..9acce7cf 100644 --- a/tests/Unit/Domain/Repository/Identity/AdministratorRepositoryTest.php +++ b/tests/Unit/Domain/Repository/Identity/AdministratorRepositoryTest.php @@ -1,4 +1,5 @@ prophesize(EntityManager::class)->reveal(); - /** @var ClassMetadata|ProphecySubjectInterface $classDescriptor */ - $classDescriptor = $this->prophesize(ClassMetadata::class)->reveal(); - $this->subject = new AdministratorRepository($entityManager, $classDescriptor); + $entityManager = $this->createMock(EntityManager::class); + $classMetadata = $this->createMock(ClassMetadata::class); + $classMetadata->name = 'PhpList\Core\Domain\Model\Identity\Administrator'; + + $this->subject = new AdministratorRepository($entityManager, $classMetadata); } - /** - * @test - */ - public function classIsEntityRepository() + public function testClassIsEntityRepository(): void { - static::assertInstanceOf(EntityRepository::class, $this->subject); + self::assertInstanceOf(EntityRepository::class, $this->subject); } } diff --git a/tests/Unit/Domain/Repository/Identity/AdministratorTokenRepositoryTest.php b/tests/Unit/Domain/Repository/Identity/AdministratorTokenRepositoryTest.php index 38f15d7d..1b913b40 100644 --- a/tests/Unit/Domain/Repository/Identity/AdministratorTokenRepositoryTest.php +++ b/tests/Unit/Domain/Repository/Identity/AdministratorTokenRepositoryTest.php @@ -1,4 +1,5 @@ prophesize(EntityManager::class)->reveal(); - /** @var ClassMetadata|ProphecySubjectInterface $classDescriptor */ - $classDescriptor = $this->prophesize(ClassMetadata::class)->reveal(); - $this->subject = new AdministratorTokenRepository($entityManager, $classDescriptor); + $entityManager = $this->createMock(EntityManager::class); + $classMetadata = $this->createMock(ClassMetadata::class); + $classMetadata->name = 'PhpList\Core\Domain\Model\Identity\AdministratorToken'; + + $this->subject = new AdministratorTokenRepository($entityManager, $classMetadata); } - /** - * @test - */ - public function classIsEntityRepository() + public function testClassIsEntityRepository(): void { - static::assertInstanceOf(EntityRepository::class, $this->subject); + self::assertInstanceOf(EntityRepository::class, $this->subject); } } diff --git a/tests/Unit/Domain/Repository/Messaging/SubscriberListRepositoryTest.php b/tests/Unit/Domain/Repository/Messaging/SubscriberListRepositoryTest.php index d4c0698c..e4cf7c19 100644 --- a/tests/Unit/Domain/Repository/Messaging/SubscriberListRepositoryTest.php +++ b/tests/Unit/Domain/Repository/Messaging/SubscriberListRepositoryTest.php @@ -1,4 +1,5 @@ prophesize(EntityManager::class)->reveal(); - /** @var ClassMetadata|ProphecySubjectInterface $classDescriptor */ - $classDescriptor = $this->prophesize(ClassMetadata::class)->reveal(); - $this->subject = new SubscriberListRepository($entityManager, $classDescriptor); + $entityManager = $this->createMock(EntityManager::class); + + $classMetadata = $this->createMock(ClassMetadata::class); + $classMetadata->name = 'PhpList\Core\Domain\Model\Messaging\SubscriberList'; + + $this->subject = new SubscriberListRepository($entityManager, $classMetadata); } - /** - * @test - */ - public function classIsEntityRepository() + public function testClassIsEntityRepository(): void { - static::assertInstanceOf(EntityRepository::class, $this->subject); + self::assertInstanceOf(EntityRepository::class, $this->subject); } } diff --git a/tests/Unit/Domain/Repository/Subscription/SubscriberRepositoryTest.php b/tests/Unit/Domain/Repository/Subscription/SubscriberRepositoryTest.php index 7f07318f..03048703 100644 --- a/tests/Unit/Domain/Repository/Subscription/SubscriberRepositoryTest.php +++ b/tests/Unit/Domain/Repository/Subscription/SubscriberRepositoryTest.php @@ -1,4 +1,5 @@ prophesize(EntityManager::class)->reveal(); - /** @var ClassMetadata|ProphecySubjectInterface $classDescriptor */ - $classDescriptor = $this->prophesize(ClassMetadata::class)->reveal(); - $this->subject = new SubscriberRepository($entityManager, $classDescriptor); + $entityManager = $this->createMock(EntityManager::class); + + $classMetadata = $this->createMock(ClassMetadata::class); + $classMetadata->name = 'PhpList\Core\Domain\Model\Subscription\Subscriber'; + + $this->subject = new SubscriberRepository($entityManager, $classMetadata); } - /** - * @test - */ - public function classIsEntityRepository() + public function testClassIsEntityRepository(): void { - static::assertInstanceOf(EntityRepository::class, $this->subject); + self::assertInstanceOf(EntityRepository::class, $this->subject); } } diff --git a/tests/Unit/Domain/Repository/Subscription/SubscriptionRepositoryTest.php b/tests/Unit/Domain/Repository/Subscription/SubscriptionRepositoryTest.php index 65cde658..fff307c0 100644 --- a/tests/Unit/Domain/Repository/Subscription/SubscriptionRepositoryTest.php +++ b/tests/Unit/Domain/Repository/Subscription/SubscriptionRepositoryTest.php @@ -1,4 +1,5 @@ prophesize(EntityManager::class)->reveal(); - /** @var ClassMetadata|ProphecySubjectInterface $classDescriptor */ - $classDescriptor = $this->prophesize(ClassMetadata::class)->reveal(); - $this->subject = new SubscriptionRepository($entityManager, $classDescriptor); + $entityManager = $this->createMock(EntityManager::class); + + $classMetadata = $this->createMock(ClassMetadata::class); + $classMetadata->name = 'PhpList\Core\Domain\Model\Subscription\Subscription'; + + $this->subject = new SubscriptionRepository($entityManager, $classMetadata); } - /** - * @test - */ - public function classIsEntityRepository() + public function testClassIsEntityRepository(): void { - static::assertInstanceOf(EntityRepository::class, $this->subject); + self::assertInstanceOf(EntityRepository::class, $this->subject); } } diff --git a/tests/Unit/EmptyStartPageBundle/Controller/DefaultControllerTest.php b/tests/Unit/EmptyStartPageBundle/Controller/DefaultControllerTest.php index 87659e9b..6ae434d2 100644 --- a/tests/Unit/EmptyStartPageBundle/Controller/DefaultControllerTest.php +++ b/tests/Unit/EmptyStartPageBundle/Controller/DefaultControllerTest.php @@ -1,11 +1,12 @@ subject = new DefaultController(); } - /** - * @test - */ - public function classIsController() + public function testClassIsController(): void { - static::assertInstanceOf(Controller::class, $this->subject); + self::assertInstanceOf(AbstractController::class, $this->subject); } - /** - * @test - */ - public function indexActionReturnsResponseWithHelloWorld() + public function testIndexActionReturnsResponseWithHelloWorld(): void { - $result = $this->subject->indexAction(); + $result = $this->subject->index(); $expectedResult = new Response('This page has been intentionally left empty.'); - static::assertEquals($expectedResult, $result); + self::assertEquals($expectedResult, $result); } } diff --git a/tests/Unit/EmptyStartPageBundle/PhpListEmptyStartPageBundleTest.php b/tests/Unit/EmptyStartPageBundle/PhpListEmptyStartPageBundleTest.php index 013bec0b..266a2ede 100644 --- a/tests/Unit/EmptyStartPageBundle/PhpListEmptyStartPageBundleTest.php +++ b/tests/Unit/EmptyStartPageBundle/PhpListEmptyStartPageBundleTest.php @@ -1,9 +1,10 @@ subject = new PhpListEmptyStartPageBundle(); + $this->subject = new EmptyStartPageBundle(); } - /** - * @test - */ - public function classIsBundle() + public function testClassIsBundle(): void { - static::assertInstanceOf(Bundle::class, $this->subject); + self::assertInstanceOf(Bundle::class, $this->subject); } } diff --git a/tests/Unit/Routing/ExtraLoaderTest.php b/tests/Unit/Routing/ExtraLoaderTest.php index 8b06a406..10aa3bb0 100644 --- a/tests/Unit/Routing/ExtraLoaderTest.php +++ b/tests/Unit/Routing/ExtraLoaderTest.php @@ -1,4 +1,5 @@ subject = new ExtraLoader(new ApplicationStructure()); } - protected function tearDown() + protected function tearDown(): void { Bootstrap::purgeInstance(); } - /** - * @test - */ - public function classIsLoader() + public function testClassIsLoader(): void { - static::assertInstanceOf(Loader::class, $this->subject); + self::assertInstanceOf(Loader::class, $this->subject); } - /** - * @test - */ - public function supportsExtraType() + public function testSupportsExtraType(): void { - static::assertTrue($this->subject->supports('', 'extra')); + self::assertTrue($this->subject->supports('', 'extra')); } - /** - * @test - */ - public function notSupportsOtherType() + public function testNotSupportsOtherType(): void { - static::assertFalse($this->subject->supports('', 'foo')); + self::assertFalse($this->subject->supports('', 'foo')); } } diff --git a/tests/Unit/Security/AuthenticationTest.php b/tests/Unit/Security/AuthenticationTest.php index b308cdec..86883763 100644 --- a/tests/Unit/Security/AuthenticationTest.php +++ b/tests/Unit/Security/AuthenticationTest.php @@ -1,4 +1,5 @@ tokenRepositoryProphecy = $this->prophesize(AdministratorTokenRepository::class); - /** @var AdministratorTokenRepository|ProphecySubjectInterface $tokenRepository */ - $tokenRepository = $this->tokenRepositoryProphecy->reveal(); - $this->subject = new Authentication($tokenRepository); + $this->tokenRepository = $this->createMock(AdministratorTokenRepository::class); + $this->subject = new Authentication($this->tokenRepository); } - /** - * @test - */ - public function authenticateByApiKeyWithValidApiKeyInBasicAuthReturnsMatchingAdministrator() + public function testAuthenticateByApiKeyWithValidApiKeyInBasicAuthReturnsMatchingAdministrator(): void { $apiKey = 'biuzaswcefblkjuzq43wtw2413'; $request = new Request(); @@ -51,15 +39,16 @@ public function authenticateByApiKeyWithValidApiKeyInBasicAuthReturnsMatchingAdm $administrator->setSuperUser(true); $token->setAdministrator($administrator); - $this->tokenRepositoryProphecy->findOneUnexpiredByKey($apiKey)->willReturn($token)->shouldBeCalled(); + $this->tokenRepository + ->expects($this->any()) + ->method('findOneUnexpiredByKey') + ->with($apiKey) + ->willReturn($token); - static::assertSame($administrator, $this->subject->authenticateByApiKey($request)); + self::assertSame($administrator, $this->subject->authenticateByApiKey($request)); } - /** - * @test - */ - public function authenticateByApiKeyWithValidApiKeyInBasicAuthWithoutAdministratorReturnsNull() + public function testAuthenticateByApiKeyWithValidApiKeyInBasicAuthWithoutAdministratorReturnsNull(): void { $apiKey = 'biuzaswcefblkjuzq43wtw2413'; $request = new Request(); @@ -67,43 +56,42 @@ public function authenticateByApiKeyWithValidApiKeyInBasicAuthWithoutAdministrat $token = new AdministratorToken(); - $this->tokenRepositoryProphecy->findOneUnexpiredByKey($apiKey)->willReturn($token)->shouldBeCalled(); + $this->tokenRepository + ->expects($this->any()) + ->method('findOneUnexpiredByKey') + ->with($apiKey) + ->willReturn($token); - static::assertNull($this->subject->authenticateByApiKey($request)); + self::assertNull($this->subject->authenticateByApiKey($request)); } - /** - * @test - */ - public function authenticateByApiKeyWithInvalidApiKeyInBasicAuthReturnsNull() + public function testAuthenticateByApiKeyWithInvalidApiKeyInBasicAuthReturnsNull(): void { $apiKey = 'biuzaswcefblkjuzq43wtw2413'; $request = new Request(); $request->headers->add(['php-auth-pw' => $apiKey]); - $this->tokenRepositoryProphecy->findOneUnexpiredByKey($apiKey)->willReturn(null)->shouldBeCalled(); + $this->tokenRepository + ->expects($this->any()) + ->method('findOneUnexpiredByKey') + ->with($apiKey) + ->willReturn(null); - static::assertNull($this->subject->authenticateByApiKey($request)); + self::assertNull($this->subject->authenticateByApiKey($request)); } - /** - * @test - */ - public function authenticateByApiKeyWithEmptyApiKeyInBasicAuthReturnsNull() + public function testAuthenticateByApiKeyWithEmptyApiKeyInBasicAuthReturnsNull(): void { $request = new Request(); $request->headers->add(['php-auth-pw' => '']); - static::assertNull($this->subject->authenticateByApiKey($request)); + self::assertNull($this->subject->authenticateByApiKey($request)); } - /** - * @test - */ - public function authenticateByApiKeyWithMissingApiKeyInBasicAuthReturnsNull() + public function testAuthenticateByApiKeyWithMissingApiKeyInBasicAuthReturnsNull(): void { $request = new Request(); - static::assertNull($this->subject->authenticateByApiKey($request)); + self::assertNull($this->subject->authenticateByApiKey($request)); } } diff --git a/tests/Unit/Security/HashGeneratorTest.php b/tests/Unit/Security/HashGeneratorTest.php index a2cb8c66..b8bd956b 100644 --- a/tests/Unit/Security/HashGeneratorTest.php +++ b/tests/Unit/Security/HashGeneratorTest.php @@ -1,4 +1,5 @@ subject = new HashGenerator(); } - /** - * @test - */ - public function createPasswordHashCreates32ByteHash() + public function testCreatePasswordHashCreates64CharacterHash(): void { - static::assertRegExp('/^[a-z0-9]{64}$/', $this->subject->createPasswordHash('Portal')); + $hash = $this->subject->createPasswordHash('Portal'); + self::assertMatchesRegularExpression('/^[a-z0-9]{64}$/', $hash); } - /** - * @test - */ - public function createPasswordHashCalledTwoTimesWithSamePasswordCreatesSameHash() + public function testCreatePasswordHashCalledTwoTimesWithSamePasswordCreatesSameHash(): void { $password = 'Aperture Science'; - static::assertSame( - $this->subject->createPasswordHash($password), - $this->subject->createPasswordHash($password) - ); + $hash1 = $this->subject->createPasswordHash($password); + $hash2 = $this->subject->createPasswordHash($password); + + self::assertSame($hash1, $hash2); } - /** - * @test - */ - public function createPasswordHashCalledTwoTimesWithDifferentPasswordsCreatesDifferentHashes() + public function testCreatePasswordHashCalledTwoTimesWithDifferentPasswordsCreatesDifferentHashes(): void { - static::assertNotSame( - $this->subject->createPasswordHash('Mel'), - $this->subject->createPasswordHash('Cave Johnson') - ); + $hash1 = $this->subject->createPasswordHash('Mel'); + $hash2 = $this->subject->createPasswordHash('Cave Johnson'); + + self::assertNotSame($hash1, $hash2); } }