From 1252d1ec0ab73ce1e1f2a202c70eedc235675ec5 Mon Sep 17 00:00:00 2001 From: Nicolas PHILIPPE Date: Tue, 17 Dec 2024 18:16:35 +0100 Subject: [PATCH] tests: transform "migrate" testsuite into "reset database" testsuite --- .github/workflows/ci.yml | 31 ++-- .gitignore | 1 - README.md | 4 +- composer.json | 12 +- phpunit-10.xml.dist | 6 +- phpunit-paratest.xml.dist | 2 +- phpunit.xml.dist | 6 +- .../Fixture/EntityInAnotherSchema/Article.php | 2 +- tests/Fixture/FoundryTestKernel.php | 143 ++++++++++++++++++ .../MigrationTests/TestMigrationKernel.php | 119 --------------- .../ResetDatabase/ResetDatabaseTestKernel.php | 73 +++++++++ .../migration-configuration-transactional.php | 2 +- .../migration-configuration.php | 2 +- tests/Fixture/TestKernel.php | 129 +--------------- .../ORM/EdgeCasesRelationshipTest.php | 28 ---- tests/Integration/Persistence/StoryTest.php | 43 ------ .../ResetDatabase/GlobalStoryTest.php | 44 ++++++ .../ResetDatabase/OrmEdgeCaseTest.php | 49 ++++++ .../ResetDatabaseTest.php} | 59 ++++---- .../ResetDatabase/ResetDatabaseTestCase.php | 35 +++++ tests/bootstrap-migrate.php | 45 ------ tests/bootstrap-reset-database.php | 49 ++++++ 22 files changed, 465 insertions(+), 419 deletions(-) create mode 100644 tests/Fixture/FoundryTestKernel.php delete mode 100644 tests/Fixture/MigrationTests/TestMigrationKernel.php create mode 100644 tests/Fixture/ResetDatabase/ResetDatabaseTestKernel.php rename tests/Fixture/{MigrationTests/configs => ResetDatabase/migration-configs}/migration-configuration-transactional.php (74%) rename tests/Fixture/{MigrationTests/configs => ResetDatabase/migration-configs}/migration-configuration.php (73%) create mode 100644 tests/Integration/ResetDatabase/GlobalStoryTest.php create mode 100644 tests/Integration/ResetDatabase/OrmEdgeCaseTest.php rename tests/Integration/{Migration/ResetDatabaseWithMigrationTest.php => ResetDatabase/ResetDatabaseTest.php} (53%) create mode 100644 tests/Integration/ResetDatabase/ResetDatabaseTestCase.php delete mode 100644 tests/bootstrap-migrate.php create mode 100644 tests/bootstrap-reset-database.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 954bf3061..6f1f91acd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -90,27 +90,32 @@ jobs: shell: bash test-reset-database-with-migration: - name: Test migration - D:${{ matrix.database }} ${{ matrix.use-dama == 1 && ' (dama)' || '' }} ${{ contains(matrix.with-migration-configuration-file, 'transactional') && '(configuration file transactional)' || contains(matrix.with-migration-configuration-file, 'configuration') && '(configuration file)' || '' }} + name: Test migration - D:${{ matrix.database }} ${{ matrix.use-dama == 1 && ' (dama)' || '' }} ${{ matrix.reset-database-mode == 'migrate' && ' (migrate)' || '' }} ${{ contains(matrix.with-migration-configuration-file, 'transactional') && '(configuration file transactional)' || contains(matrix.with-migration-configuration-file, 'configuration') && '(configuration file)' || '' }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: - database: [ mysql, pgsql, sqlite ] + database: [ mysql, pgsql, sqlite, mysql|mongo ] use-dama: [ 0, 1 ] - with-migration-configuration-file: - - '' - - 'tests/Fixture/MigrationTests/configs/migration-configuration.php' - - 'tests/Fixture/MigrationTests/configs/migration-configuration-transactional.php' + reset-database-mode: [ schema, migrate ] + migration-configuration-file: ['no', 'migration-configuration', 'migration-configuration-transactional'] + include: + - { database: mongo, migration-configuration-file: 'no', use-dama: 0, reset-database-mode: schema } exclude: # there is currently a bug with MySQL and transactional migrations - database: mysql - with-migration-configuration-file: 'tests/Fixture/MigrationTests/configs/migration-configuration-transactional.php' + migration-configuration-file: 'migration-configuration-transactional' + - reset-database-mode: schema + migration-configuration-file: 'migration-configuration' + - reset-database-mode: schema + migration-configuration-file: 'migration-configuration-transactional' env: DATABASE_URL: ${{ contains(matrix.database, 'mysql') && 'mysql://root:root@localhost:3306/foundry?serverVersion=5.7.42' || contains(matrix.database, 'pgsql') && 'postgresql://root:root@localhost:5432/foundry?serverVersion=15' || 'sqlite:///%kernel.project_dir%/var/data.db' }} - MONGO_URL: '' + MONGO_URL: ${{ contains(matrix.database, 'mongo') && 'mongodb://127.0.0.1:27017/dbName?compressors=disabled&gssapiServiceName=mongodb' || '' }} USE_DAMA_DOCTRINE_TEST_BUNDLE: ${{ matrix.use-dama == 1 && 1 || 0 }} - WITH_MIGRATION_CONFIGURATION_FILE: ${{ matrix.with-migration-configuration-file }} - PHPUNIT_VERSION: 9 + DATABASE_RESET_MODE: ${{ matrix.reset-database-mode == 1 && 1 || 0 }} + MIGRATION_CONFIGURATION_FILE: ${{ matrix.migration-configuration-file == 'no' && '' || format('tests/Fixture/MigrationTests/configs/{0}.php', matrix.migration-configuration-file) }} + PHPUNIT_VERSION: 11 services: postgres: image: ${{ contains(matrix.database, 'pgsql') && 'postgres:15' || '' }} @@ -125,6 +130,10 @@ jobs: --health-interval 10s --health-timeout 5s --health-retries 5 + mongo: + image: ${{ contains(matrix.database, 'mongo') && 'mongo:4' || '' }} + ports: + - 27017:27017 steps: - name: Checkout code uses: actions/checkout@v3 @@ -149,7 +158,7 @@ jobs: run: sudo /etc/init.d/mysql start - name: Test - run: ./phpunit --testsuite migrate --bootstrap tests/bootstrap-migrate.php + run: ./phpunit --testsuite reset-database --bootstrap tests/bootstrap-reset-database.php shell: bash test-with-paratest: diff --git a/.gitignore b/.gitignore index 6d5aba94f..5ce100385 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,4 @@ /docker/.makefile /.env.local /docker-compose.override.yaml -/tests/Fixture/MigrationTests/Migrations/ /tests/Fixture/Maker/tmp/ diff --git a/README.md b/README.md index ba954bc3d..1205ac720 100644 --- a/README.md +++ b/README.md @@ -74,9 +74,9 @@ MONGO_URL="" # disables Mongo USE_DAMA_DOCTRINE_TEST_BUNDLE="1" # enables dama/doctrine-test-bundle PHPUNIT_VERSION="11" # possible values: 9, 10, 11, 11.4 -# test reset database with configuration migration, +# test reset database with configuration migration, # only relevant for "migrate" testsuite -WITH_MIGRATION_CONFIGURATION_FILE="tests/Fixture/MigrationTests/configs/migration-configuration.php" +MIGRATION_CONFIGURATION_FILE="tests/Fixture/MigrationTests/configs/migration-configuration.php" # run test suite with postgreSQL $ vendor/bin/phpunit diff --git a/composer.json b/composer.json index 6b74cfb10..0b55de8b3 100644 --- a/composer.json +++ b/composer.json @@ -86,15 +86,15 @@ }, "scripts": { "test": [ - "@test-schema", - "@test-migrate" + "@test-main", + "@test-reset-database" ], - "test-schema": "./phpunit", - "test-migrate": "./phpunit --testsuite migrate --bootstrap tests/bootstrap-migrate.php" + "test-main": "./phpunit --testsuite main", + "test-reset-database": "./phpunit --testsuite reset-database --bootstrap tests/bootstrap-reset-database.php" }, "scripts-descriptions": { - "test-schema": "Test with schema reset", - "test-migrate": "Test with migrations reset" + "test-main": "Main test suite", + "test-reset-database": "Test reset database test suite" }, "minimum-stability": "dev", "prefer-stable": true diff --git a/phpunit-10.xml.dist b/phpunit-10.xml.dist index b97581549..43f815cc7 100644 --- a/phpunit-10.xml.dist +++ b/phpunit-10.xml.dist @@ -17,10 +17,10 @@ tests - tests/Integration/Migration/ResetDatabaseWithMigrationTest.php + tests/Integration/ResetDatabase - - tests/Integration/Migration/ResetDatabaseWithMigrationTest.php + + tests/Integration/ResetDatabase diff --git a/phpunit-paratest.xml.dist b/phpunit-paratest.xml.dist index 387352e86..1f6aee78d 100644 --- a/phpunit-paratest.xml.dist +++ b/phpunit-paratest.xml.dist @@ -16,7 +16,7 @@ tests - tests/Integration/Migration/ResetDatabaseWithMigrationTest.php + tests/Integration/ResetDatabase diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c6b9f26cb..95f1c3e92 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -19,10 +19,10 @@ tests - tests/Integration/Migration/ResetDatabaseWithMigrationTest.php + tests/Integration/ResetDatabase - - tests/Integration/Migration/ResetDatabaseWithMigrationTest.php + + tests/Integration/ResetDatabase diff --git a/tests/Fixture/EntityInAnotherSchema/Article.php b/tests/Fixture/EntityInAnotherSchema/Article.php index e95aa52b2..62fcf3c3c 100644 --- a/tests/Fixture/EntityInAnotherSchema/Article.php +++ b/tests/Fixture/EntityInAnotherSchema/Article.php @@ -18,7 +18,7 @@ /** * Create custom "cms" schema ({@see Article}) to ensure "migrate" mode is still working with multiple schemas. - * Note: this entity is added to mapping only for PostgreSQ, as it is the only supported DBMS which handles multiple schemas. + * Note: this entity is added to mapping only for PostgreSQL, as it is the only supported DBMS which handles multiple schemas. * * @see https://github.com/zenstruck/foundry/issues/618 */ diff --git a/tests/Fixture/FoundryTestKernel.php b/tests/Fixture/FoundryTestKernel.php new file mode 100644 index 000000000..cbaf88453 --- /dev/null +++ b/tests/Fixture/FoundryTestKernel.php @@ -0,0 +1,143 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Zenstruck\Foundry\Tests\Fixture; + +use DAMA\DoctrineTestBundle\DAMADoctrineTestBundle; +use Doctrine\Bundle\DoctrineBundle\DoctrineBundle; +use Doctrine\Bundle\MongoDBBundle\DoctrineMongoDBBundle; +use Psr\Log\NullLogger; +use Symfony\Bundle\FrameworkBundle\FrameworkBundle; +use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; +use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpKernel\Kernel; +use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; +use Zenstruck\Foundry\Persistence\PersistenceManager; +use Zenstruck\Foundry\Tests\Fixture\DoctrineCascadeRelationship\ChangeCascadePersistOnLoadClassMetadataListener; +use Zenstruck\Foundry\ZenstruckFoundryBundle; + +/** + * @author Nicolas PHILIPPE + */ +abstract class FoundryTestKernel extends Kernel +{ + use MicroKernelTrait; + + public function registerBundles(): iterable + { + yield new FrameworkBundle(); + + if (\getenv('DATABASE_URL')) { + yield new DoctrineBundle(); + } + + if (\getenv('MONGO_URL')) { + yield new DoctrineMongoDBBundle(); + } + + yield new ZenstruckFoundryBundle(); + + if (\getenv('USE_DAMA_DOCTRINE_TEST_BUNDLE')) { + yield new DAMADoctrineTestBundle(); + } + } + + protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader): void + { + $c->loadFromExtension('framework', [ + 'http_method_override' => false, + 'secret' => 'S3CRET', + 'router' => ['utf8' => true], + 'test' => true, + ]); + + if (\getenv('DATABASE_URL')) { + $c->loadFromExtension('doctrine', [ + 'dbal' => ['url' => '%env(resolve:DATABASE_URL)%', 'use_savepoints' => true], + 'orm' => [ + 'auto_generate_proxy_classes' => true, + 'auto_mapping' => true, + 'mappings' => [ + 'Entity' => [ + 'is_bundle' => false, + 'type' => 'attribute', + 'dir' => '%kernel.project_dir%/tests/Fixture/Entity', + 'prefix' => 'Zenstruck\Foundry\Tests\Fixture\Entity', + 'alias' => 'Entity', + ], + 'Model' => [ + 'is_bundle' => false, + 'type' => 'attribute', + 'dir' => '%kernel.project_dir%/tests/Fixture/Model', + 'prefix' => 'Zenstruck\Foundry\Tests\Fixture\Model', + 'alias' => 'Model', + ], + + // postgres acts weirdly with multiple schemas + // @see https://github.com/doctrine/DoctrineBundle/issues/548 + ...(\str_starts_with(\getenv('DATABASE_URL') ?: '', 'postgresql') // @phpstan-ignore ternary.alwaysTrue + ? [ + 'EntityInAnotherSchema' => [ + 'is_bundle' => false, + 'type' => 'attribute', + 'dir' => '%kernel.project_dir%/tests/Fixture/EntityInAnotherSchema', + 'prefix' => 'Zenstruck\Foundry\Tests\Fixture\EntityInAnotherSchema', + 'alias' => 'Migrate', + ], + ] + : [] + ), + ], + 'controller_resolver' => ['auto_mapping' => false], + ], + ]); + + $c->register(ChangeCascadePersistOnLoadClassMetadataListener::class) + ->setAutowired(true) + ->setAutoconfigured(true); + $c->setAlias(PersistenceManager::class, '.zenstruck_foundry.persistence_manager') + ->setPublic(true); + } + + if (\getenv('MONGO_URL')) { + $c->loadFromExtension('doctrine_mongodb', [ + 'connections' => [ + 'default' => ['server' => '%env(resolve:MONGO_URL)%'], + ], + 'default_database' => 'mongo', + 'document_managers' => [ + 'default' => [ + 'auto_mapping' => true, + 'mappings' => [ + 'Document' => [ + 'is_bundle' => false, + 'type' => 'attribute', + 'dir' => '%kernel.project_dir%/tests/Fixture/Document', + 'prefix' => 'Zenstruck\Foundry\Tests\Fixture\Document', + 'alias' => 'Document', + ], + 'Model' => [ + 'is_bundle' => false, + 'type' => 'attribute', + 'dir' => '%kernel.project_dir%/tests/Fixture/Model', + 'prefix' => 'Zenstruck\Foundry\Tests\Fixture\Model', + 'alias' => 'Model', + ], + ], + ], + ], + ]); + } + + $c->register('logger', NullLogger::class); + } +} diff --git a/tests/Fixture/MigrationTests/TestMigrationKernel.php b/tests/Fixture/MigrationTests/TestMigrationKernel.php deleted file mode 100644 index 2038bb906..000000000 --- a/tests/Fixture/MigrationTests/TestMigrationKernel.php +++ /dev/null @@ -1,119 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Zenstruck\Foundry\Tests\Fixture\MigrationTests; - -use DAMA\DoctrineTestBundle\DAMADoctrineTestBundle; -use Doctrine\Bundle\DoctrineBundle\DoctrineBundle; -use Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle; -use Psr\Log\NullLogger; -use Symfony\Bundle\FrameworkBundle\FrameworkBundle; -use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; -use Symfony\Component\Config\Loader\LoaderInterface; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\HttpKernel\Kernel; -use Zenstruck\Foundry\ORM\ResetDatabase\ResetDatabaseMode; -use Zenstruck\Foundry\Tests\Fixture\Stories\GlobalInvokableService; -use Zenstruck\Foundry\Tests\Fixture\Stories\GlobalStory; -use Zenstruck\Foundry\ZenstruckFoundryBundle; - -/** - * @author Nicolas PHILIPPE - */ -final class TestMigrationKernel extends Kernel -{ - use MicroKernelTrait; - - public function registerBundles(): iterable - { - yield new FrameworkBundle(); - yield new DoctrineBundle(); - yield new DoctrineMigrationsBundle(); - - yield new ZenstruckFoundryBundle(); - - if (\getenv('USE_DAMA_DOCTRINE_TEST_BUNDLE')) { - yield new DAMADoctrineTestBundle(); - } - } - - protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader): void - { - $c->loadFromExtension('framework', [ - 'http_method_override' => false, - 'secret' => 'S3CRET', - 'router' => ['utf8' => true], - 'test' => true, - ]); - - $c->loadFromExtension('zenstruck_foundry', [ - 'global_state' => [ - GlobalStory::class, - GlobalInvokableService::class, - ], - 'orm' => [ - 'reset' => [ - 'mode' => ResetDatabaseMode::MIGRATE, - 'migrations' => [ - 'configurations' => ($configFile = \getenv('WITH_MIGRATION_CONFIGURATION_FILE')) ? [$configFile] : [], - ], - ], - ], - ]); - - if (!\getenv('WITH_MIGRATION_CONFIGURATION_FILE')) { - $c->loadFromExtension('doctrine_migrations', include __DIR__.'/configs/migration-configuration.php'); - } - - $c->loadFromExtension('doctrine', [ - 'dbal' => ['url' => '%env(resolve:DATABASE_URL)%', 'use_savepoints' => true], - 'orm' => [ - 'auto_generate_proxy_classes' => true, - 'auto_mapping' => true, - 'mappings' => [ - 'Entity' => [ - 'is_bundle' => false, - 'type' => 'attribute', - 'dir' => '%kernel.project_dir%/tests/Fixture/Entity', - 'prefix' => 'Zenstruck\Foundry\Tests\Fixture\Entity', - 'alias' => 'Entity', - ], - 'Model' => [ - 'is_bundle' => false, - 'type' => 'attribute', - 'dir' => '%kernel.project_dir%/tests/Fixture/Model', - 'prefix' => 'Zenstruck\Foundry\Tests\Fixture\Model', - 'alias' => 'Model', - ], - - // postgres acts weirdly with multiple schemas - // @see https://github.com/doctrine/DoctrineBundle/issues/548 - ...(\str_starts_with(\getenv('DATABASE_URL') ?: '', 'postgresql') - ? [ - 'EntityInAnotherSchema' => [ - 'is_bundle' => false, - 'type' => 'attribute', - 'dir' => '%kernel.project_dir%/tests/Fixture/EntityInAnotherSchema', - 'prefix' => 'Zenstruck\Foundry\Tests\Fixture\EntityInAnotherSchema', - 'alias' => 'Migrate', - ], - ] - : [] - ), - ], - 'controller_resolver' => ['auto_mapping' => false], - ], - ]); - - $c->register('logger', NullLogger::class); - $c->register(GlobalInvokableService::class); - } -} diff --git a/tests/Fixture/ResetDatabase/ResetDatabaseTestKernel.php b/tests/Fixture/ResetDatabase/ResetDatabaseTestKernel.php new file mode 100644 index 000000000..fbfd900ce --- /dev/null +++ b/tests/Fixture/ResetDatabase/ResetDatabaseTestKernel.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Zenstruck\Foundry\Tests\Fixture\ResetDatabase; + +use Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle; +use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Zenstruck\Foundry\ORM\ResetDatabase\ResetDatabaseMode; +use Zenstruck\Foundry\Tests\Fixture\FoundryTestKernel; +use Zenstruck\Foundry\Tests\Fixture\Stories\GlobalInvokableService; +use Zenstruck\Foundry\Tests\Fixture\Stories\GlobalStory; + +/** + * @author Nicolas PHILIPPE + */ +final class ResetDatabaseTestKernel extends FoundryTestKernel +{ + public function registerBundles(): iterable + { + yield from parent::registerBundles(); + + if (self::useMigrations()) { + yield new DoctrineMigrationsBundle(); + } + } + + protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader): void + { + parent::configureContainer($c, $loader); + + $c->loadFromExtension('zenstruck_foundry', [ + 'global_state' => [ + GlobalStory::class, + GlobalInvokableService::class, + ], + 'orm' => [ + 'reset' => + self::useMigrations() + ? [ + 'mode' => ResetDatabaseMode::MIGRATE, + 'migrations' => [ + 'configurations' => ($configFile = \getenv('MIGRATION_CONFIGURATION_FILE')) ? [$configFile] : [], + ], + ] + : ['mode' => ResetDatabaseMode::SCHEMA], + ], + ]); + + if (self::useMigrations() && !\getenv('MIGRATION_CONFIGURATION_FILE')) { + // if no configuration file was given in Foundry's config, let's use the main one as default. + $c->loadFromExtension( + 'doctrine_migrations', + include __DIR__ . '/migration-configs/migration-configuration.php' + ); + } + + $c->register(GlobalInvokableService::class); + } + + public static function useMigrations(): bool + { + return \getenv('DATABASE_RESET_MODE') === 'migrate'; + } +} diff --git a/tests/Fixture/MigrationTests/configs/migration-configuration-transactional.php b/tests/Fixture/ResetDatabase/migration-configs/migration-configuration-transactional.php similarity index 74% rename from tests/Fixture/MigrationTests/configs/migration-configuration-transactional.php rename to tests/Fixture/ResetDatabase/migration-configs/migration-configuration-transactional.php index cb0928594..c8f5232f7 100644 --- a/tests/Fixture/MigrationTests/configs/migration-configuration-transactional.php +++ b/tests/Fixture/ResetDatabase/migration-configs/migration-configuration-transactional.php @@ -11,7 +11,7 @@ return [ 'migrations_paths' => [ - 'Zenstruck\\Foundry\\Tests\\Fixture\\MigrationTests\\Migrations' => \dirname(__DIR__).'/Migrations', + 'Zenstruck\\Foundry\\Tests\\Fixture\\ResetDatabase\\Migrations' => \dirname(__DIR__).'/Migrations', ], 'transactional' => true, ]; diff --git a/tests/Fixture/MigrationTests/configs/migration-configuration.php b/tests/Fixture/ResetDatabase/migration-configs/migration-configuration.php similarity index 73% rename from tests/Fixture/MigrationTests/configs/migration-configuration.php rename to tests/Fixture/ResetDatabase/migration-configs/migration-configuration.php index def58e6f5..b897fc47c 100644 --- a/tests/Fixture/MigrationTests/configs/migration-configuration.php +++ b/tests/Fixture/ResetDatabase/migration-configs/migration-configuration.php @@ -11,7 +11,7 @@ return [ 'migrations_paths' => [ - 'Zenstruck\\Foundry\\Tests\\Fixture\\MigrationTests\\Migrations' => \dirname(__DIR__).'/Migrations', + 'Zenstruck\\Foundry\\Tests\\Fixture\\ResetDatabase\\Migrations' => \dirname(__DIR__, 4).'/var/Migrations', ], 'transactional' => false, ]; diff --git a/tests/Fixture/TestKernel.php b/tests/Fixture/TestKernel.php index 50ae9529c..edb4ddfa5 100644 --- a/tests/Fixture/TestKernel.php +++ b/tests/Fixture/TestKernel.php @@ -11,68 +11,31 @@ namespace Zenstruck\Foundry\Tests\Fixture; -use DAMA\DoctrineTestBundle\DAMADoctrineTestBundle; -use Doctrine\Bundle\DoctrineBundle\DoctrineBundle; -use Doctrine\Bundle\MongoDBBundle\DoctrineMongoDBBundle; -use Psr\Log\NullLogger; -use Symfony\Bundle\FrameworkBundle\FrameworkBundle; -use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Bundle\MakerBundle\MakerBundle; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\HttpKernel\Kernel; -use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; use Zenstruck\Foundry\ORM\ResetDatabase\ResetDatabaseMode; -use Zenstruck\Foundry\Persistence\PersistenceManager; -use Zenstruck\Foundry\Tests\Fixture\DoctrineCascadeRelationship\ChangeCascadePersistOnLoadClassMetadataListener; use Zenstruck\Foundry\Tests\Fixture\Factories\ArrayFactory; use Zenstruck\Foundry\Tests\Fixture\Factories\Object1Factory; -use Zenstruck\Foundry\Tests\Fixture\Stories\GlobalInvokableService; -use Zenstruck\Foundry\Tests\Fixture\Stories\GlobalStory; use Zenstruck\Foundry\Tests\Fixture\Stories\ServiceStory; -use Zenstruck\Foundry\ZenstruckFoundryBundle; /** * @author Kevin Bond */ -final class TestKernel extends Kernel +final class TestKernel extends FoundryTestKernel { - use MicroKernelTrait; - public function registerBundles(): iterable { - yield new FrameworkBundle(); - yield new MakerBundle(); - - if (\getenv('DATABASE_URL')) { - yield new DoctrineBundle(); - } - - if (\getenv('MONGO_URL')) { - yield new DoctrineMongoDBBundle(); - } - - yield new ZenstruckFoundryBundle(); + yield from parent::registerBundles(); - if (\getenv('USE_DAMA_DOCTRINE_TEST_BUNDLE')) { - yield new DAMADoctrineTestBundle(); - } + yield new MakerBundle(); } protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader): void { - $c->loadFromExtension('framework', [ - 'http_method_override' => false, - 'secret' => 'S3CRET', - 'router' => ['utf8' => true], - 'test' => true, - ]); + parent::configureContainer($c, $loader); $c->loadFromExtension('zenstruck_foundry', [ - 'global_state' => [ - GlobalStory::class, - GlobalInvokableService::class, - ], 'orm' => [ 'reset' => [ 'mode' => ResetDatabaseMode::SCHEMA, @@ -80,92 +43,8 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load ], ]); - if (\getenv('DATABASE_URL')) { - $c->loadFromExtension('doctrine', [ - 'dbal' => ['url' => '%env(resolve:DATABASE_URL)%', 'use_savepoints' => true], - 'orm' => [ - 'auto_generate_proxy_classes' => true, - 'auto_mapping' => true, - 'mappings' => [ - 'Entity' => [ - 'is_bundle' => false, - 'type' => 'attribute', - 'dir' => '%kernel.project_dir%/tests/Fixture/Entity', - 'prefix' => 'Zenstruck\Foundry\Tests\Fixture\Entity', - 'alias' => 'Entity', - ], - 'Model' => [ - 'is_bundle' => false, - 'type' => 'attribute', - 'dir' => '%kernel.project_dir%/tests/Fixture/Model', - 'prefix' => 'Zenstruck\Foundry\Tests\Fixture\Model', - 'alias' => 'Model', - ], - - // postgres acts weirdly with multiple schemas - // @see https://github.com/doctrine/DoctrineBundle/issues/548 - ...(\str_starts_with(\getenv('DATABASE_URL'), 'postgresql') - ? [ - 'EntityInAnotherSchema' => [ - 'is_bundle' => false, - 'type' => 'attribute', - 'dir' => '%kernel.project_dir%/tests/Fixture/EntityInAnotherSchema', - 'prefix' => 'Zenstruck\Foundry\Tests\Fixture\EntityInAnotherSchema', - 'alias' => 'Migrate', - ], - ] - : [] - ), - ], - 'controller_resolver' => ['auto_mapping' => false], - ], - ]); - - $c->register(ChangeCascadePersistOnLoadClassMetadataListener::class) - ->setAutowired(true) - ->setAutoconfigured(true); - $c->setAlias(PersistenceManager::class, '.zenstruck_foundry.persistence_manager') - ->setPublic(true); - } - - if (\getenv('MONGO_URL')) { - $c->loadFromExtension('doctrine_mongodb', [ - 'connections' => [ - 'default' => ['server' => '%env(resolve:MONGO_URL)%'], - ], - 'default_database' => 'mongo', - 'document_managers' => [ - 'default' => [ - 'auto_mapping' => true, - 'mappings' => [ - 'Document' => [ - 'is_bundle' => false, - 'type' => 'attribute', - 'dir' => '%kernel.project_dir%/tests/Fixture/Document', - 'prefix' => 'Zenstruck\Foundry\Tests\Fixture\Document', - 'alias' => 'Document', - ], - 'Model' => [ - 'is_bundle' => false, - 'type' => 'attribute', - 'dir' => '%kernel.project_dir%/tests/Fixture/Model', - 'prefix' => 'Zenstruck\Foundry\Tests\Fixture\Model', - 'alias' => 'Model', - ], - ], - ], - ], - ]); - } - - $c->register('logger', NullLogger::class); - $c->register(GlobalInvokableService::class); $c->register(ArrayFactory::class)->setAutowired(true)->setAutoconfigured(true); $c->register(Object1Factory::class)->setAutowired(true)->setAutoconfigured(true); $c->register(ServiceStory::class)->setAutowired(true)->setAutoconfigured(true); } - - protected function configureRoutes(RoutingConfigurator $routes): void - { - } } diff --git a/tests/Integration/ORM/EdgeCasesRelationshipTest.php b/tests/Integration/ORM/EdgeCasesRelationshipTest.php index 1bf563f33..618132fc6 100644 --- a/tests/Integration/ORM/EdgeCasesRelationshipTest.php +++ b/tests/Integration/ORM/EdgeCasesRelationshipTest.php @@ -31,7 +31,6 @@ use Zenstruck\Foundry\Tests\Fixture\Stories\GlobalStory; use Zenstruck\Foundry\Tests\Integration\RequiresORM; -use function Zenstruck\Foundry\Persistence\flush_after; use function Zenstruck\Foundry\Persistence\persistent_factory; /** @@ -41,33 +40,6 @@ final class EdgeCasesRelationshipTest extends KernelTestCase { use ChangesEntityRelationshipCascadePersist, Factories, RequiresORM, ResetDatabase; - /** @test */ - #[Test] - #[DataProvider('provideCascadeRelationshipsCombinations')] - #[UsingRelationships(RelationshipWithGlobalEntity\RelationshipWithGlobalEntity::class, ['globalEntity'])] - #[RequiresPhpunit('^11.4')] - public function it_can_use_flush_after_and_entity_from_global_state(): void - { - $relationshipWithGlobalEntityFactory = persistent_factory(RelationshipWithGlobalEntity\RelationshipWithGlobalEntity::class); - $globalEntitiesCount = persistent_factory(GlobalEntity::class)::repository()->count(); - - flush_after(function() use ($relationshipWithGlobalEntityFactory) { - $relationshipWithGlobalEntityFactory->create(['globalEntity' => GlobalStory::globalEntityProxy()]); - $relationshipWithGlobalEntityFactory->create(['globalEntity' => GlobalStory::globalEntity()]); - }); - - // assert no extra GlobalEntity have been created - persistent_factory(GlobalEntity::class)::assert()->count($globalEntitiesCount); - - $relationshipWithGlobalEntityFactory::assert()->count(2); - - $entity = $relationshipWithGlobalEntityFactory::repository()->first(); - self::assertSame(GlobalStory::globalEntity(), $entity?->getGlobalEntity()); - - $entity = $relationshipWithGlobalEntityFactory::repository()->last(); - self::assertSame(GlobalStory::globalEntity(), $entity?->getGlobalEntity()); - } - /** @test */ #[Test] #[DataProvider('provideCascadeRelationshipsCombinations')] diff --git a/tests/Integration/Persistence/StoryTest.php b/tests/Integration/Persistence/StoryTest.php index 573288aa9..0d17f9b61 100644 --- a/tests/Integration/Persistence/StoryTest.php +++ b/tests/Integration/Persistence/StoryTest.php @@ -16,9 +16,7 @@ use Zenstruck\Foundry\Story; use Zenstruck\Foundry\Test\Factories; use Zenstruck\Foundry\Test\ResetDatabase; -use Zenstruck\Foundry\Tests\Fixture\Document\GlobalDocument; use Zenstruck\Foundry\Tests\Fixture\Entity\GenericEntity; -use Zenstruck\Foundry\Tests\Fixture\Entity\GlobalEntity; use Zenstruck\Foundry\Tests\Fixture\Factories\Document\GenericDocumentFactory; use Zenstruck\Foundry\Tests\Fixture\Factories\Entity\GenericEntityFactory; use Zenstruck\Foundry\Tests\Fixture\Model\GenericModel; @@ -27,12 +25,9 @@ use Zenstruck\Foundry\Tests\Fixture\Stories\DocumentStory; use Zenstruck\Foundry\Tests\Fixture\Stories\EntityPoolStory; use Zenstruck\Foundry\Tests\Fixture\Stories\EntityStory; -use Zenstruck\Foundry\Tests\Fixture\Stories\GlobalStory; use Zenstruck\Foundry\Tests\Fixture\Stories\ObjectStory; use Zenstruck\Foundry\Tests\Fixture\Stories\PersistenceDisabledStory; -use function Zenstruck\Foundry\Persistence\repository; - /** * @author Kevin Bond */ @@ -72,44 +67,6 @@ public function stories_only_loaded_once(string $story, string $factory): void $factory::repository()->assert()->count(2); } - /** - * @test - */ - public function global_stories_are_loaded(): void - { - if (!\getenv('DATABASE_URL') && !\getenv('MONGO_URL')) { - $this->markTestSkipped('No persistence enabled.'); - } - - if (\getenv('DATABASE_URL')) { - repository(GlobalEntity::class)->assert()->count(2); - } - - if (\getenv('MONGO_URL')) { - repository(GlobalDocument::class)->assert()->count(2); - } - } - - /** - * @test - */ - public function global_stories_cannot_be_loaded_again(): void - { - if (!\getenv('DATABASE_URL') && !\getenv('MONGO_URL')) { - $this->markTestSkipped('No persistence enabled.'); - } - - GlobalStory::load(); - - if (\getenv('DATABASE_URL')) { - repository(GlobalEntity::class)->assert()->count(2); - } - - if (\getenv('MONGO_URL')) { - repository(GlobalDocument::class)->assert()->count(2); - } - } - /** * @param class-string $story * diff --git a/tests/Integration/ResetDatabase/GlobalStoryTest.php b/tests/Integration/ResetDatabase/GlobalStoryTest.php new file mode 100644 index 000000000..7d59f5e78 --- /dev/null +++ b/tests/Integration/ResetDatabase/GlobalStoryTest.php @@ -0,0 +1,44 @@ +assert()->count(2); + } + + if (self::hasMongo()) { + repository(GlobalDocument::class)->assert()->count(2); + } + } + + /** + * @test + */ + public function global_stories_cannot_be_loaded_again(): void + { + GlobalStory::load(); + + if (self::hasORM()) { + repository(GlobalEntity::class)->assert()->count(2); + } + + if (self::hasMongo()) { + repository(GlobalDocument::class)->assert()->count(2); + } + } +} diff --git a/tests/Integration/ResetDatabase/OrmEdgeCaseTest.php b/tests/Integration/ResetDatabase/OrmEdgeCaseTest.php new file mode 100644 index 000000000..7657be1b1 --- /dev/null +++ b/tests/Integration/ResetDatabase/OrmEdgeCaseTest.php @@ -0,0 +1,49 @@ +count(); + + flush_after(function() use ($relationshipWithGlobalEntityFactory) { + $relationshipWithGlobalEntityFactory->create(['globalEntity' => GlobalStory::globalEntityProxy()]); + $relationshipWithGlobalEntityFactory->create(['globalEntity' => GlobalStory::globalEntity()]); + }); + + // assert no extra GlobalEntity have been created + persistent_factory(GlobalEntity::class)::assert()->count($globalEntitiesCount); + + $relationshipWithGlobalEntityFactory::assert()->count(2); + + $entity = $relationshipWithGlobalEntityFactory::repository()->first(); + self::assertSame(GlobalStory::globalEntity(), $entity?->getGlobalEntity()); + + $entity = $relationshipWithGlobalEntityFactory::repository()->last(); + self::assertSame(GlobalStory::globalEntity(), $entity?->getGlobalEntity()); + } +} diff --git a/tests/Integration/Migration/ResetDatabaseWithMigrationTest.php b/tests/Integration/ResetDatabase/ResetDatabaseTest.php similarity index 53% rename from tests/Integration/Migration/ResetDatabaseWithMigrationTest.php rename to tests/Integration/ResetDatabase/ResetDatabaseTest.php index eb07f3cc7..849734948 100644 --- a/tests/Integration/Migration/ResetDatabaseWithMigrationTest.php +++ b/tests/Integration/ResetDatabase/ResetDatabaseTest.php @@ -11,18 +11,16 @@ * file that was distributed with this source code. */ -namespace Zenstruck\Foundry\Tests\Integration\Migration; +namespace Zenstruck\Foundry\Tests\Integration\ResetDatabase; use Symfony\Bundle\FrameworkBundle\Console\Application; -use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\BufferedOutput; use Zenstruck\Foundry\Test\Factories; use Zenstruck\Foundry\Test\ResetDatabase; -use Zenstruck\Foundry\Tests\Fixture\Entity\GlobalEntity; use Zenstruck\Foundry\Tests\Fixture\EntityInAnotherSchema\Article; -use Zenstruck\Foundry\Tests\Fixture\Factories\Entity\Contact\ContactFactory; -use Zenstruck\Foundry\Tests\Fixture\MigrationTests\TestMigrationKernel; +use Zenstruck\Foundry\Tests\Fixture\Factories\Document\GenericDocumentFactory; +use Zenstruck\Foundry\Tests\Fixture\Factories\Entity\GenericEntityFactory; use Zenstruck\Foundry\Tests\Integration\RequiresORM; use function Zenstruck\Foundry\Persistence\persist; @@ -31,7 +29,7 @@ /** * @author Nicolas PHILIPPE */ -final class ResetDatabaseWithMigrationTest extends KernelTestCase +final class ResetDatabaseTest extends ResetDatabaseTestCase { use Factories; use RequiresORM; @@ -50,11 +48,15 @@ public function it_generates_valid_schema(): void $output = new BufferedOutput() ); - // The command actually fails, because of a bug in doctrine ORM 3! - // https://github.com/doctrine/migrations/issues/1406 - self::assertSame(2, $exit, \sprintf('Schema is not valid: %s', $commandOutput = $output->fetch())); - self::assertStringContainsString('1 schema diff(s) detected', $commandOutput); - self::assertStringContainsString('DROP TABLE doctrine_migration_versions', $commandOutput); + if (self::usesMigrations()) { + // The command actually fails, because of a bug in doctrine ORM 3! + // https://github.com/doctrine/migrations/issues/1406 + self::assertSame(2, $exit, \sprintf('Schema is not valid: %s', $commandOutput = $output->fetch())); + self::assertStringContainsString('1 schema diff(s) detected', $commandOutput); + self::assertStringContainsString('DROP TABLE doctrine_migration_versions', $commandOutput); + } else { + self::assertSame(0, $exit, \sprintf('Schema is not valid: %s', $output->fetch())); + } } /** @@ -62,28 +64,32 @@ public function it_generates_valid_schema(): void */ public function it_can_store_object(): void { - ContactFactory::assert()->count(0); - - ContactFactory::createOne(); + if (self::hasORM()) { + GenericEntityFactory::assert()->count(0); + GenericEntityFactory::createOne(); + GenericEntityFactory::assert()->count(1); + } - ContactFactory::assert()->count(1); + if (self::hasMongo()) { + GenericDocumentFactory::assert()->count(0); + GenericDocumentFactory::createOne(); + GenericDocumentFactory::assert()->count(1); + } } /** * @test * @depends it_can_store_object */ - public function it_starts_from_fresh_db(): void + public function it_still_starts_from_fresh_db(): void { - ContactFactory::assert()->count(0); - } + if (self::hasORM()) { + GenericEntityFactory::assert()->count(0); + } - /** - * @test - */ - public function global_objects_are_created(): void - { - repository(GlobalEntity::class)->assert()->count(2); + if (self::hasMongo()) { + GenericDocumentFactory::assert()->count(0); + } } /** @@ -98,9 +104,4 @@ public function can_create_object_in_another_schema(): void persist(Article::class, ['title' => 'Hello World!']); repository(Article::class)->assert()->count(1); } - - protected static function getKernelClass(): string - { - return TestMigrationKernel::class; - } } diff --git a/tests/Integration/ResetDatabase/ResetDatabaseTestCase.php b/tests/Integration/ResetDatabase/ResetDatabaseTestCase.php new file mode 100644 index 000000000..2cc05ce3c --- /dev/null +++ b/tests/Integration/ResetDatabase/ResetDatabaseTestCase.php @@ -0,0 +1,35 @@ + - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Component\Dotenv\Dotenv; -use Symfony\Component\Filesystem\Filesystem; -use Zenstruck\Foundry\Tests\Fixture\MigrationTests\TestMigrationKernel; - -use function Zenstruck\Foundry\application; -use function Zenstruck\Foundry\runCommand; - -require \dirname(__DIR__).'/vendor/autoload.php'; - -$fs = new Filesystem(); - -$fs->remove(__DIR__.'/../var'); - -(new Dotenv())->usePutenv()->loadEnv(__DIR__.'/../.env'); - -$fs->remove(__DIR__.'/Fixture/MigrationTests/Migrations'); -$fs->mkdir(__DIR__.'/Fixture/MigrationTests/Migrations'); - -$kernel = new TestMigrationKernel('test', true); -$kernel->boot(); - -$application = application($kernel); - -runCommand($application, 'doctrine:database:drop --if-exists --force', canFail: true); -runCommand($application, 'doctrine:database:create', canFail: true); - -$configuration = ''; -if (\getenv('WITH_MIGRATION_CONFIGURATION_FILE')) { - $configuration = '--configuration '.\getcwd().'/'.\getenv('WITH_MIGRATION_CONFIGURATION_FILE'); -} -runCommand($application, "doctrine:migrations:diff {$configuration}"); -runCommand($application, 'doctrine:database:drop --force', canFail: true); - -$kernel->shutdown(); diff --git a/tests/bootstrap-reset-database.php b/tests/bootstrap-reset-database.php new file mode 100644 index 000000000..384722628 --- /dev/null +++ b/tests/bootstrap-reset-database.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Component\Dotenv\Dotenv; +use Symfony\Component\Filesystem\Filesystem; + +use Zenstruck\Foundry\Tests\Fixture\ResetDatabase\ResetDatabaseTestKernel; + +use Zenstruck\Foundry\Tests\Integration\ResetDatabase\ResetDatabaseTestCase; + +use function Zenstruck\Foundry\application; +use function Zenstruck\Foundry\runCommand; + +require \dirname(__DIR__).'/vendor/autoload.php'; + +$fs = new Filesystem(); + +$fs->remove(__DIR__.'/../var'); + +(new Dotenv())->usePutenv()->loadEnv(__DIR__.'/../.env'); + +if (ResetDatabaseTestCase::usesMigrations()) { + $fs->mkdir(__DIR__ . '/../var/Migrations'); + + $kernel = new ResetDatabaseTestKernel('test', true); + $kernel->boot(); + + $application = application($kernel); + + runCommand($application, 'doctrine:database:drop --if-exists --force', canFail: true); + runCommand($application, 'doctrine:database:create', canFail: true); + + $configuration = ''; + if (\getenv('MIGRATION_CONFIGURATION_FILE')) { + $configuration = '--configuration ' . \getcwd() . '/' . \getenv('MIGRATION_CONFIGURATION_FILE'); + } + runCommand($application, "doctrine:migrations:diff {$configuration}"); + runCommand($application, 'doctrine:database:drop --force', canFail: true); + + $kernel->shutdown(); +}