Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Symfony upgrade 5.4 -> 6.4 brokes my tests #152

Closed
badmansan opened this issue Dec 4, 2023 · 2 comments
Closed

Symfony upgrade 5.4 -> 6.4 brokes my tests #152

badmansan opened this issue Dec 4, 2023 · 2 comments
Labels
Status: Waiting Feedback Needs feedback from the author

Comments

@badmansan
Copy link

I have some functional tests that check the registration process with email confirmation. It looks like this:

use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Bundle\FrameworkBundle\Test\MailerAssertionsTrait;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

final class RegisterUserAndLoginTest extends WebTestCase
{
    use MailerAssertionsTrait;

    private const SIGN_UP_FORM_NAME = 'sign_up_by_email_form';

    public function testRegisterForm(): void
    {
        $browser = self::createClient();
        $this->registerTheUser($browser);

        self::assertEmailCount(1);

        /** @var TemplatedEmail $email */
        $email = self::getMailerMessage();
        $context = $email->getContext();
        $emailBody = $email->getHtmlBody();

        self::assertArrayHasKey('signedUrl', $context);
        self::assertIsString($context['signedUrl']);
        self::assertStringContainsString(htmlspecialchars($context['signedUrl']), $emailBody);
        // ... other checks
    }

    private function registerTheUser(KernelBrowser $kernelBrowser): void
    {
        $kernelBrowser->request('GET', '/sign-up');

        $kernelBrowser->submitForm('Submit', [
            self::SIGN_UP_FORM_NAME . '[email]' => '[email protected]',
            self::SIGN_UP_FORM_NAME . '[plainPassword][password]' => '1234567890',
            self::SIGN_UP_FORM_NAME . '[plainPassword][confirmation]' => '1234567890',
            self::SIGN_UP_FORM_NAME . '[agreeTerms]' => 1,
        ]);
    }
}

In test signedUrl is confirmation link that I generate from service during registration process:

// EmailConfirmationService
public function sendEmailConfirmation(string $verifyEmailRouteName, User $user, TemplatedEmail $templatedEmail): void
{
    $verifyEmailSignatureComponents = $this->verifyEmailHelper->generateSignature(
        $verifyEmailRouteName,
        $user->getId(),
        $user->getEmail(),
        ['id' => $user->getId()],
    );

    $context = $templatedEmail->getContext();
    $context['signedUrl'] = $verifyEmailSignatureComponents->getSignedUrl();

    $templatedEmail->context($context);

    $this->mailer->send($templatedEmail);
}

In symfony 5.4 this test works fine. But at 6.4 it brakes because of empty $email->getContext(). In the same time the body of email is ok, with correct link and all things works actually.

The problem is how email is rendered in later symfony. In 6.4 context erases after render. Here is BodyRenderer.php (6.4) and here BodyRenderer.php from 5.4. As you can see in 6.4 $message->markAsRendered() calls where context erases:

class TemplatedEmail extends Email
{
    // ...

    public function markAsRendered(): void
    {
        $this->textTemplate = null;
        $this->htmlTemplate = null;
        $this->context = [];
    }

Now I'm confused. What test should be written for such a check? Ok, I can parse raw html email body with regex. But how can I check that this link is the same I generated before in service?

@jrushlow
Copy link
Collaborator

jrushlow commented Apr 17, 2024

Howdy @badmansan! sorry for the late reply to this. I'm working on the ability to generate tests over in maker-bundle for make:registration (symfony/maker-bundle#1497). But in the meantime, here is an early WIP of what we'll generate over in maker:

class RegistrationFormTest extends WebTestCase
{
    public function testRegister(): void
    {
        $client = static::createClient();

        $container = static::getContainer();
        $em = $container->get('doctrine.orm.entity_manager');
        $userRepository = $container->get(UserRepository::class);

        foreach ($userRepository->findAll() as $user) {
            $em->remove($user);
        }

        $em->flush();

        self::assertCount(0, $userRepository->findAll());

        $client->request('GET', '/register');
        self::assertResponseIsSuccessful();

        $client->submitForm('Register', [
            'registration_form[email]' => '[email protected]',
            'registration_form[plainPassword]' => 'password',
            'registration_form[agreeTerms]' => true,
        ]);

        self::assertResponseRedirects('/');
        self::assertCount(1, $userRepository->findAll());
        self::assertFalse(($user = $userRepository->findAll()[0])->isVerified());

        // Use either assertQueuedEmailCount() || assertEmailCount() depending on your mailer setup
        self::assertQueuedEmailCount(1);
        // self::assertEmailCount(1);

        self::assertCount(1, $messages = $this->getMailerMessages());
        self::assertEmailTextBodyContains($messages[0], 'This link will expire in 1 hour.');

        $client->followRedirect();
        $client->loginUser($user);

        /** @var TemplatedEmail $templatedEmail */
        $templatedEmail = $messages[0];
        $messageBody = $templatedEmail->getHtmlBody();

        preg_match('#(http://localhost/verify/email.+)">#', $messageBody, $resetLink);

        $client->request('GET', $resetLink[1]);
        $client->followRedirect();

        self::assertTrue(static::getContainer()->get(UserRepository::class)->findAll()[0]->isVerified());
    }
}

Let me know if you this helps!

@jrushlow jrushlow added the Status: Waiting Feedback Needs feedback from the author label Apr 17, 2024
@bocharsky-bw
Copy link
Member

Closing as no further feedback from the author.

If you still have this issue - please, feel free to reopen it again with more details

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Waiting Feedback Needs feedback from the author
Projects
None yet
Development

No branches or pull requests

3 participants