Skip to content

Commit ea34834

Browse files
committed
[make:registration] tests
1 parent d33269c commit ea34834

File tree

3 files changed

+147
-0
lines changed

3 files changed

+147
-0
lines changed

src/Maker/MakeRegistrationForm.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,21 @@
1212
namespace Symfony\Bundle\MakerBundle\Maker;
1313

1414
use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
15+
use Doctrine\ORM\EntityManager;
1516
use Doctrine\ORM\EntityManagerInterface;
1617
use Doctrine\ORM\Mapping\Column;
1718
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
1819
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
1920
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
21+
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
2022
use Symfony\Bundle\MakerBundle\ConsoleStyle;
2123
use Symfony\Bundle\MakerBundle\DependencyBuilder;
2224
use Symfony\Bundle\MakerBundle\Doctrine\DoctrineHelper;
2325
use Symfony\Bundle\MakerBundle\Exception\RuntimeCommandException;
2426
use Symfony\Bundle\MakerBundle\FileManager;
2527
use Symfony\Bundle\MakerBundle\Generator;
2628
use Symfony\Bundle\MakerBundle\InputConfiguration;
29+
use Symfony\Bundle\MakerBundle\Maker\Common\CanGenerateTestsTrait;
2730
use Symfony\Bundle\MakerBundle\Renderer\FormTypeRenderer;
2831
use Symfony\Bundle\MakerBundle\Security\InteractiveSecurityHelper;
2932
use Symfony\Bundle\MakerBundle\Security\Model\Authenticator;
@@ -68,6 +71,8 @@
6871
*/
6972
final class MakeRegistrationForm extends AbstractMaker
7073
{
74+
use CanGenerateTestsTrait;
75+
7176
private string $userClass;
7277
private string $usernameField;
7378
private string $passwordField;
@@ -104,6 +109,8 @@ public function configureCommand(Command $command, InputConfiguration $inputConf
104109
$command
105110
->setHelp(file_get_contents(__DIR__.'/../Resources/help/MakeRegistrationForm.txt'))
106111
;
112+
113+
$this->addWithTestsOption($command);
107114
}
108115

109116
public function interact(InputInterface $input, ConsoleStyle $io, Command $command): void
@@ -180,6 +187,8 @@ public function interact(InputInterface $input, ConsoleStyle $io, Command $comma
180187
$routeNames = array_keys($this->router->getRouteCollection()->all());
181188
$this->redirectRouteName = $io->choice('What route should the user be redirected to after registration?', $routeNames);
182189
}
190+
191+
$this->interactSetGenerateTests($input, $io);
183192
}
184193

185194
/** @param array<string, mixed> $securityData */
@@ -400,6 +409,34 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
400409
$this->fileManager->dumpFile($classDetails->getPath(), $userManipulator->getSourceCode());
401410
}
402411

412+
// Generate PHPUnit Tests
413+
if ($this->shouldGenerateTests()) {
414+
$testClassDetails = $generator->createClassNameDetails(
415+
'RegistrationControllerTest',
416+
'Test\\'
417+
);
418+
419+
$useStatements = new UseStatementGenerator([
420+
EntityManager::class,
421+
TemplatedEmail::class,
422+
WebTestCase::class,
423+
$userRepoVars['repository_full_class_name'],
424+
]);
425+
426+
$generator->generateFile(
427+
targetPath: sprintf('tests/%s.php', $testClassDetails->getShortName()),
428+
templateName: 'registration/Test.WithVerify.tpl.php',
429+
variables: array_merge([
430+
'use_statements' => $useStatements,
431+
'from_email' => $this->fromEmailAddress,
432+
], $userRepoVars)
433+
);
434+
435+
if (!class_exists(WebTestCase::class)) {
436+
$io->caution('You\'ll need to install the `symfony/test-pack` to execute the tests for your new controller.');
437+
}
438+
}
439+
403440
$generator->writeChanges();
404441

405442
$this->writeSuccessMessage($io);
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?= "<?php\n" ?>
2+
namespace App\Tests;
3+
4+
<?= $use_statements ?>
5+
6+
class RegistrationControllerTest extends WebTestCase
7+
{
8+
public function testRegister(): void
9+
{
10+
$client = static::createClient();
11+
12+
$container = static::getContainer();
13+
$em = $container->get('doctrine.orm.entity_manager');
14+
$userRepository = $container->get(<?= $repository_class_name ?>::class);
15+
16+
foreach ($userRepository->findAll() as $user) {
17+
$em->remove($user);
18+
}
19+
20+
$em->flush();
21+
22+
self::assertCount(0, $userRepository->findAll());
23+
24+
// Register a new user
25+
$client->request('GET', '/register');
26+
self::assertResponseIsSuccessful();
27+
28+
$client->submitForm('Register', [
29+
'registration_form[email]' => '[email protected]',
30+
'registration_form[plainPassword]' => 'password',
31+
'registration_form[agreeTerms]' => true,
32+
]);
33+
34+
// Ensure the response redirects after submitting the form, the user exists, and is not verified
35+
// self::assertResponseRedirects('/');
36+
self::assertCount(1, $userRepository->findAll());
37+
self::assertFalse(($user = $userRepository->findAll()[0])->isVerified());
38+
39+
// Ensure the verification email was sent
40+
// Use either assertQueuedEmailCount() || assertEmailCount() depending on your mailer setup
41+
// self::assertQueuedEmailCount(1);
42+
self::assertEmailCount(1);
43+
44+
self::assertCount(1, $messages = $this->getMailerMessages());
45+
self::assertEmailAddressContains($messages[0], 'from', '<?= $from_email ?>');
46+
self::assertEmailAddressContains($messages[0], 'to', '[email protected]');
47+
self::assertEmailTextBodyContains($messages[0], 'This link will expire in 1 hour.');
48+
49+
// Login the new user
50+
$client->followRedirect();
51+
$client->loginUser($user);
52+
53+
// Get the verification link from the email
54+
/** @var TemplatedEmail $templatedEmail */
55+
$templatedEmail = $messages[0];
56+
$messageBody = $templatedEmail->getHtmlBody();
57+
58+
preg_match('#(http://localhost/verify/email.+)">#', $messageBody, $resetLink);
59+
60+
// "Click" the link, and see if the user is verified
61+
$client->request('GET', $resetLink[1]);
62+
$client->followRedirect();
63+
64+
self::assertTrue(static::getContainer()->get(UserRepository::class)->findAll()[0]->isVerified());
65+
}
66+
}

tests/Maker/MakeRegistrationFormTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,50 @@ public function getTestDetails(): \Generator
225225
$this->runRegistrationTest($runner, 'it_generates_registration_form_with_verification.php');
226226
}),
227227
];
228+
229+
yield 'it_generates_registration_form_with_verification_and_with_tests' => [$this->createRegistrationFormTest()
230+
->addExtraDependencies('symfonycasts/verify-email-bundle')
231+
// needed for internal functional test
232+
->addExtraDependencies('symfony/web-profiler-bundle', 'mailer')
233+
->run(function (MakerTestRunner $runner) {
234+
$runner->writeFile(
235+
'config/packages/mailer.yaml',
236+
Yaml::dump(['framework' => [
237+
'mailer' => ['dsn' => 'null://null'],
238+
]])
239+
);
240+
241+
$this->makeUser($runner);
242+
243+
$output = $runner->runMaker([
244+
'n', // add UniqueEntity
245+
'y', // verify user
246+
'y', // require authentication to verify user email
247+
'[email protected]', // from email address
248+
'SymfonyCasts', // From Name
249+
'n', // no authenticate after
250+
'app_anonymous', // route number to redirect to
251+
'y', // Generate tests
252+
]);
253+
254+
$this->assertStringContainsString('Success', $output);
255+
256+
$generatedFiles = [
257+
'src/Security/EmailVerifier.php',
258+
'templates/registration/confirmation_email.html.twig',
259+
'tests/RegistrationControllerTest.php',
260+
];
261+
262+
foreach ($generatedFiles as $file) {
263+
$this->assertFileExists($runner->getPath($file));
264+
}
265+
266+
$runner->runConsole('cache:clear', [], '--env=test');
267+
268+
$runner->configureDatabase();
269+
$runner->runTests();
270+
}),
271+
];
228272
}
229273

230274
private function makeUser(MakerTestRunner $runner, string $identifier = 'email'): void

0 commit comments

Comments
 (0)