由于从电子邮件中提取的令牌损坏,功能测试失败

Functional test fails due to corrupted token extracted from email

在 Symfony 5 项目中,当从电子邮件中提取的确认令牌损坏时,用户注册的功能测试失败。 (电子邮件是用 SwiftMailer 完成的,因为它能够发送日志。)

测试从填写包含用户名和电子邮件地址的表格开始。在保存时发送电子邮件。因为测试包括 $this->client->followRedirects(false);,所以测试可以访问电子邮件的内容。当从电子邮件中提取令牌时,它包含额外的字符。因此,当测试尝试 $this->client->request('GET', '/register/reset/' . $token); 时,由于注册数据无效,测试失败。

这是一个测试版本:

    public function testReplacementEmail() {
        $this->client->clickLink('Staff');
        $this->client->clickLink('Replace');
        $this->client->followRedirects(false);
        $this->client->submitForm('Save', [
            'user[fname]' => 'Useless',
            'user[sname]' => 'Garbage',
            'user[email]' => 'ugar@bogus.info'
        ]);
        $mailCollector = $this->client->getProfile()->getCollector('swiftmailer');

        $this->assertSame(1, $mailCollector->getMessageCount());
        $collectedMessages = $mailCollector->getMessages();
        $message = $collectedMessages[0];
        $this->assertStringContainsString('has been asked to designate', $message);

        $string = 'register/reset/';
        $offset = strlen($string);
        $pos = strpos($message, $string) + $offset;
        $token = substr($message, $pos, 32);
        var_dump($token);

        $this->client->followRedirects(true);
        $this->client->request('GET', '/logout');
        $this->client->request('GET', '/register/reset/' . $token);
        $this->client->submitForm('Save', [
            'new_password[plainPassword][first]' => '123Abc',
            'new_password[plainPassword][second]' => '123Abc',
        ]);

        $this->assertStringContainsString('You are now the registered representative', $this->client->getResponse()->getContent());
    }

我已经在处理 Replace link 行 $token = md5(uniqid(rand(), true));var_dump($token); 的控制器中包含了为了获得一个纯粹的令牌。当测试为 运行 时,这些行会产生如下内容:

string(32) "ad47260162194f9ab6deb55eb4f38178"

如果我在测试中使用 var_dump($message); 访问电子邮件的内容,我会看到类似这样的内容:

href="http://localhost/register/reset/ad47260162194f9ab6deb55eb4f38178"

然而,在测试包括 var_dump($token); 的地方,我看到的却是这样的:

string(32) "7260162194f9ab6d=
eb55eb4f38178"

=\r\n 的存在(在 Windows 系统上)导致 link 失败。

我想知道为什么会出现这些额外的字符,以及如何尽可能避免它们。

您的字符串中存在 =\r\n 表明该消息是 MIME-encoded 和 quoted printable 并且您的 link 跨越了一行结尾。 SwiftMailer 消息对象似乎有一个神奇的 __toString() 方法(奇怪的是,IMO)产生消息的 encoded 形式。如果你想要原始的原始消息字符串,你可以调用消息对象的 getBody() 方法,然后只使用你的 strpos() 测试结果。