laravel / ideas

Issues board used for Laravel internals discussions.
938 stars 28 forks source link

Add assertions to MailFake #2548

Open Arkitecht opened 3 years ago

Arkitecht commented 3 years ago

I have seen this asked and discussed elsewhere, but was not sure why this would not be considered desirable behavior.

With the new assertions added to Laravel 8, I think it would be helpful to extend these to MailFakes as well, so one could fake the Mailer and still make assertions on the subject, content, etc.

I believe this could be accomplished fairly easily like so:

/**
     * Render the HTML and plain-text version of the mailable into views for assertions.
     *
     * @return array
     *
     * @throws \ReflectionException
     */
    protected function renderForAssertions()
    {
        if ($this->assertionableRenderStrings) {
            return $this->assertionableRenderStrings;
        }

        return $this->assertionableRenderStrings = $this->withLocale($this->locale, function () {
            Container::getInstance()->call([$this, 'build']);

            $mailer = Container::getInstance()->make('mailer');

            if (is_a($mailer, MailFake::class)) {
                $mailer = (new MailManager(app()))->mailer();
            }

            $html = $mailer->render(
                $view = $this->buildView(), $this->buildViewData()
            );

            if (is_array($view) && isset($view[1])) {
                $text = $view[1];
            }

            $text = $text ?? $view['text'] ?? '';

            if (!empty($text) && !$text instanceof Htmlable) {
                $text = $mailer->render(
                    $text, $this->buildViewData()
                );
            }

            return [(string)$html, (string)$text];
        });
    }

I would be happy to create a PR for this, if it is acceptable