diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 51dfbdf8..d0e25622 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -2,6 +2,9 @@ security: password_hashers: App\Entity\User: algorithm: native + encoders: + App\Entity\User: + algorithm: native providers: user: entity: diff --git a/config/packages/test/security.yaml b/config/packages/test/security.yaml index 7825ad10..8f9c2ac3 100644 --- a/config/packages/test/security.yaml +++ b/config/packages/test/security.yaml @@ -1,4 +1,10 @@ security: + encoders: + App\Entity\User: + algorithm: native + cost: 4 + time_cost: 3 + memory_cost: 10 password_hashers: App\Entity\User: algorithm: native diff --git a/tasks.py b/tasks.py index dba6e637..c685a478 100644 --- a/tasks.py +++ b/tasks.py @@ -153,6 +153,7 @@ def tests(c): Launch unit and functional tests """ with Builder(c): + reset(c) docker_compose_run(c, 'php ./vendor/bin/simple-phpunit') diff --git a/tests/Controller/UserAccount/AbstractBaseFactories.php b/tests/Controller/UserAccount/AbstractBaseFactories.php new file mode 100644 index 00000000..772809fb --- /dev/null +++ b/tests/Controller/UserAccount/AbstractBaseFactories.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, + * please view the LICENSE file that was distributed with this source code. + */ + +namespace App\Tests\Controller\UserAccount; + +use App\Entity\User; +use App\Factory\UserFactory; +use Doctrine\Common\DataFixtures\Purger\ORMPurger; +use Symfony\Bundle\FrameworkBundle\KernelBrowser; +use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; +use Zenstruck\Foundry\Test\Factories; + +abstract class AbstractBaseFactories extends WebTestCase +{ + use Factories; + + private ?KernelBrowser $client = null; + + protected function setUp(): void + { + $purger = new ORMPurger($this->getEntityManager()); + $purger->purge(); + $this->generateData(); + } + + protected function getClient(?User $user = null) + { + if (!$this->client) { + $user = $user ?: $this->getTestUser(); + $this->ensureKernelShutdown(); + $this->client = $this->createClient(); + $this->client->followRedirects(); + $this->client->loginUser($user); + } + + return $this->client; + } + + protected function getTestUser() + { + $user = UserFactory::repository()->findOneBy([ + 'email' => 'user@starfleet.app', + ]); + + if (!$user) { + $user = UserFactory::createOne([ + 'name' => 'Starfleet User', + 'email' => 'user@starfleet.app', + 'password' => 'password', + ]); + } + + $user = $user->object(); + + return $user; + } + + protected function getAdminUser() + { + $user = $this->getTestUser() + ->addRole('ROLE_ADMIN') + ->setName('Starfleet Admin') + ->setEmail('admin@starfleet.app') + ->setPassword('password') + ; + + $this->getEntityManager()->flush(); + + return $user; + } + + /** + * This method must create all the entities your test will need. + */ + abstract protected function generateData(); + + private function getEntityManager() + { + return $this->getContainer()->get('doctrine')->getManager(); + } +} diff --git a/tests/Controller/UserAccount/BaseFactories.php b/tests/Controller/UserAccount/BaseFactories.php deleted file mode 100644 index 014368f7..00000000 --- a/tests/Controller/UserAccount/BaseFactories.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * For the full copyright and license information, - * please view the LICENSE file that was distributed with this source code. - */ - -namespace App\Tests\Controller\UserAccount; - -use App\Entity\User; -use App\Factory\UserFactory; -use Symfony\Bundle\FrameworkBundle\KernelBrowser; -use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; -use Zenstruck\Foundry\Proxy; -use Zenstruck\Foundry\Test\Factories; -use Zenstruck\Foundry\Test\ResetDatabase; - -class BaseFactories extends WebTestCase -{ - use Factories; - use ResetDatabase; - - private ?Proxy $user = null; - private ?KernelBrowser $client = null; - - protected function getTestUser(): User - { - if (!$this->user) { - $user = UserFactory::createOne([ - 'name' => 'My Test User', - 'email' => 'user@starfleet.app', - 'password' => 'user', - ]); - - $this->user = $user; - } - - return $this->user->object(); - } - - protected function getClient(): KernelBrowser - { - if (!$this->client) { - $this->ensureKernelShutdown(); - $this->client = $this->createClient(); - $this->client->followRedirects(); - $this->client->loginUser($this->getTestUser()); - } - - return $this->client; - } - - protected function getAdminUser(): User - { - $this->getTestUser() - ->addRole('ROLE_ADMIN') - ->setName('My Admin User') - ->setEmail('admin@starfleet.app') - ->setPassword('admin') - ; - $this->user->save(); - - return $this->user->object(); - } -} diff --git a/tests/Controller/UserAccount/FutureConferencesControllerTest.php b/tests/Controller/UserAccount/FutureConferencesControllerTest.php index a7938d7f..378fe7ad 100644 --- a/tests/Controller/UserAccount/FutureConferencesControllerTest.php +++ b/tests/Controller/UserAccount/FutureConferencesControllerTest.php @@ -13,7 +13,10 @@ use App\Factory\ConferenceFactory; -class FutureConferencesControllerTest extends BaseFactories +/** + * @group user_account + */ +class FutureConferencesControllerTest extends AbstractBaseFactories { private string $conferencesUrl = '/user/future-conferences'; @@ -25,31 +28,22 @@ public function testFutureConferencesPageLoad() public function testConferencesAreDisplayed() { - ConferenceFactory::createMany(3, [ + $crawler = $this->getClient()->request('GET', $this->conferencesUrl); + + $featuredConferencesCount = \count(ConferenceFactory::findBy([ 'featured' => true, - 'startAt' => new \DateTime('+2 days'), - 'endAt' => new \DateTime('+5 days'), - ]); + ])); - ConferenceFactory::createMany(5, [ + $regularConferencesCount = \count(ConferenceFactory::findBy([ 'featured' => false, - 'startAt' => new \DateTime('+2 days'), - 'endAt' => new \DateTime('+5 days'), - ]); + ])); - $crawler = $this->getClient()->request('GET', $this->conferencesUrl); - - self::assertCount(3, $crawler->filter('div#featured-conferences-block div.conference-card')); - self::assertCount(5, $crawler->filter('div#regular-conferences-block div.conference-card')); + self::assertCount($featuredConferencesCount, $crawler->filter('div#featured-conferences-block div.conference-card')); + self::assertCount($regularConferencesCount, $crawler->filter('div#regular-conferences-block div.conference-card')); } public function testAskParticipationWork() { - ConferenceFactory::createOne([ - 'startAt' => new \DateTime('+2 days'), - 'endAt' => new \DateTime('+5 days'), - ]); - $this->getClient()->request('GET', $this->conferencesUrl); $this->getClient()->submitForm('Ask Participation'); @@ -58,15 +52,24 @@ public function testAskParticipationWork() public function testSubmitTalkWork() { - ConferenceFactory::createOne([ - 'startAt' => new \DateTime('+2 days'), - 'endAt' => new \DateTime('+5 days'), - 'cfpEndAt' => new \DateTime('+5 days'), - ]); - $this->getClient()->request('GET', $this->conferencesUrl); $this->getClient()->submitForm('Submit a Talk'); self::assertResponseIsSuccessful(); } + + protected function generateData() + { + ConferenceFactory::createMany(3, [ + 'featured' => true, + 'startAt' => new \DateTime('+1 days'), + 'endAt' => new \DateTime('+1 days'), + ]); + + ConferenceFactory::createMany(3, [ + 'featured' => false, + 'startAt' => new \DateTime('+1 days'), + 'endAt' => new \DateTime('+1 days'), + ]); + } } diff --git a/tests/Controller/UserAccount/HomepageControllerTest.php b/tests/Controller/UserAccount/HomepageControllerTest.php index 293d06fe..7d8129a2 100644 --- a/tests/Controller/UserAccount/HomepageControllerTest.php +++ b/tests/Controller/UserAccount/HomepageControllerTest.php @@ -11,7 +11,10 @@ namespace App\Tests\Controller\UserAccount; -class HomepageControllerTest extends BaseFactories +/** + * @group user_account + */ +class HomepageControllerTest extends AbstractBaseFactories { public function testUserPageForUsers() { @@ -25,10 +28,15 @@ public function testUserPageForUsers() public function testUserPageForAdmins() { $user = $this->getAdminUser(); - $crawler = $this->getClient()->request('GET', '/user/account'); + $crawler = $this->getClient($user)->request('GET', '/user/account'); self::assertResponseIsSuccessful(); self::assertSelectorTextContains('.username', $user->getName()); self::assertCount(1, $crawler->filter('#admin-button')); } + + protected function generateData() + { + // No specific data needed for these tests + } } diff --git a/tests/Controller/UserAccount/ParticipationControllerTest.php b/tests/Controller/UserAccount/ParticipationControllerTest.php index 4694aa23..02dae2a7 100644 --- a/tests/Controller/UserAccount/ParticipationControllerTest.php +++ b/tests/Controller/UserAccount/ParticipationControllerTest.php @@ -19,7 +19,10 @@ use Symfony\Bundle\FrameworkBundle\KernelBrowser; use Symfony\Component\DomCrawler\Crawler; -class ParticipationControllerTest extends BaseFactories +/** + * @group user_account + */ +class ParticipationControllerTest extends AbstractBaseFactories { /** @dataProvider provideRoutes */ public function testAllPagesLoad(string $route) @@ -31,8 +34,6 @@ public function testAllPagesLoad(string $route) public function testParticipationsPageWork() { - $this->createTestData(); - $crawler = $this->getClient()->request('GET', '/user/participations'); self::assertCount(2, $crawler->filter('#pending-participations-block .card')); @@ -50,6 +51,7 @@ public function testParticipationsFormWork() 'startAt' => new \DateTime('+10 days'), 'endAt' => new \DateTime('+12 days'), ]); + $preSubmitCount = \count(ParticipationFactory::all()); $this->getClient()->request('GET', '/user/participations'); $this->getClient()->submitForm('submit_participation', [ @@ -59,8 +61,10 @@ public function testParticipationsFormWork() 'participation[conferenceTicketStatus]' => Participation::STATUS_NOT_NEEDED, ]); - self::assertCount(1, ParticipationFactory::all()); - self::assertSame($this->getTestUser(), ParticipationFactory::find(1)->getParticipant()); + $allParticipations = ParticipationFactory::all(); + + self::assertCount($preSubmitCount + 1, $allParticipations); + self::assertSame($this->getTestUser(), $allParticipations[$preSubmitCount]->getParticipant()); } public function testEditParticipationPageWork() @@ -94,8 +98,6 @@ public function testEditParticipationPageWork() /** @dataProvider provideActionRoutes */ public function testAllEditParticipationLinksWork(string $route) { - $this->createTestData(); - $this->getClient()->request('GET', $route); $this->getClient()->submitForm('Edit Participation'); @@ -105,7 +107,6 @@ public function testAllEditParticipationLinksWork(string $route) /** @dataProvider provideActionRoutes */ public function testAllCancelParticipationLinksWork(string $route) { - $this->createTestData(); $crawler = $this->getClient()->request('GET', $route); if ('/user/participations' === $route) { @@ -173,7 +174,7 @@ public function testParticipationCancelCsrfProtection() private function mainPageCancelLink(KernelBrowser $client, Crawler $crawler) { - $participationRepository = static::$container->get(ParticipationRepository::class); + $participationRepository = $this->getContainer()->get(ParticipationRepository::class); $participations = $participationRepository->findPendingParticipationsByUser($this->getTestUser()); $preCancelCount = \count($participations); @@ -187,7 +188,7 @@ private function mainPageCancelLink(KernelBrowser $client, Crawler $crawler) self::assertCount(--$preCancelCount, $participationRepository->findPendingParticipationsByUser($this->getTestUser())); } - private function createTestData() + protected function generateData() { ParticipationFactory::createMany(2, [ 'participant' => $this->getTestUser(), diff --git a/tests/Controller/UserAccount/SubmitControllerTest.php b/tests/Controller/UserAccount/SubmitControllerTest.php index b5227307..b88bafb0 100644 --- a/tests/Controller/UserAccount/SubmitControllerTest.php +++ b/tests/Controller/UserAccount/SubmitControllerTest.php @@ -17,7 +17,10 @@ use App\Factory\TalkFactory; use App\Factory\UserFactory; -class SubmitControllerTest extends BaseFactories +/** + * @group user_account + */ +class SubmitControllerTest extends AbstractBaseFactories { /** @dataProvider provideRoutes */ public function testAllPagesLoad(string $route) @@ -38,7 +41,6 @@ public function provideRoutes(): iterable public function testSubmitsPageWork() { - $this->createTestData(); $crawler = $this->getClient()->request('GET', '/user/submits'); self::assertCount(1, $crawler->filter('#pending-submits-block .card')); @@ -65,6 +67,8 @@ public function testSubmitsFormWork() 'conference' => $conference, ]); + $preSubmitCount = \count(SubmitFactory::all()); + $this->getClient()->request('GET', '/user/submits'); $this->getClient()->submitForm('submit_submit', [ 'submit[conference]' => $conference->getName(), @@ -72,15 +76,15 @@ public function testSubmitsFormWork() 'submit[users]' => $this->getTestUser()->getId(), ]); - self::assertCount(2, SubmitFactory::all()); - self::assertSame($this->getTestUser(), SubmitFactory::find(2)->getUsers()[0]); + $allSubmits = SubmitFactory::all(); + + self::assertCount($preSubmitCount + 1, $allSubmits); + self::assertSame($this->getTestUser(), $allSubmits[$preSubmitCount]->getUsers()[0]); } /** @dataProvider provideActions */ public function testSubmitActions(string $action) { - $this->createTestData(); - foreach (['accepted', 'pending'] as $pageName) { if ($pageName === $action || ('accept' === $action && 'accepted' === $pageName)) { continue; @@ -107,8 +111,6 @@ public function testSubmitActions(string $action) /** @dataProvider provideActions */ public function mainPageActions(string $action): void { - $this->createTestData(); - if ('cancel' === $action) { $submits = SubmitFactory::repository()->findUserSubmitsByStatus($this->getTestUser(), Submit::STATUS_DONE); } else { @@ -176,7 +178,7 @@ public function provideButtonsText() yield ['Edit Profile']; } - private function createTestData() + protected function generateData() { UserFactory::createMany(2); ConferenceFactory::createMany(5); diff --git a/tests/Controller/UserAccount/TalkControllerTest.php b/tests/Controller/UserAccount/TalkControllerTest.php index d02e8544..b0a8dca3 100644 --- a/tests/Controller/UserAccount/TalkControllerTest.php +++ b/tests/Controller/UserAccount/TalkControllerTest.php @@ -16,7 +16,10 @@ use App\Factory\TalkFactory; use App\Factory\UserFactory; -class TalkControllerTest extends BaseFactories +/** + * @group user_account + */ +class TalkControllerTest extends AbstractBaseFactories { /** @dataProvider provideRoutes */ public function testPagesLoad(string $route) @@ -33,7 +36,6 @@ public function provideRoutes(): iterable public function testTalksPageWork() { - $this->createTestData(); $crawler = $this->getClient()->request('GET', '/user/talks'); self::assertSelectorExists('#all-talks-block a', '...Show more'); @@ -48,6 +50,8 @@ public function testTalksFormWork() 'endAt' => new \DateTime('+12 days'), ]); + $preSubmitCount = \count(TalkFactory::all()); + $this->getClient()->request('GET', '/user/talks'); $this->getClient()->submitForm('submit_talk', [ 'new_talk[title]' => 'My Amazing Test Title', @@ -56,7 +60,7 @@ public function testTalksFormWork() 'new_talk[users]' => $this->getTestUser()->getId(), ]); - self::assertCount(1, ConferenceFactory::all()); + self::assertCount($preSubmitCount + 1, TalkFactory::all()); } public function testEditTalkPageWork() @@ -85,7 +89,6 @@ public function testEditTalkPageWork() /** @dataProvider provideRoutes */ public function testAllEditTalkLinksWork(string $route) { - $this->createTestData(); $this->getClient()->request('GET', $route); $this->getClient()->submitForm('Edit'); @@ -111,16 +114,15 @@ public function provideButtonsText() yield ['Edit Profile']; } - private function createTestData() + protected function generateData() { UserFactory::createMany(2); ConferenceFactory::createMany(5); - TalkFactory::createMany(10); - foreach (range(1, 4) as $id) { + foreach (TalkFactory::createMany(4) as $talk) { SubmitFactory::createOne([ 'users' => [$this->getTestUser()], - 'talk' => TalkFactory::find($id), + 'talk' => $talk, ]); } }