Postmark es una plataforma de envío de emails transaccionales que cuenta con una API muy fácil de implementar, especialmente si trabajas con Laravel. En este post veremos cómo implementar este servicio a nuestras aplicaciones de Laravel utiilzando Mailbles y aplicando Test Driven Development.
Importante antes de continuar: para poder usar Postmark es requerido poseer una dirección de email bajo un dominio privado [email protected], cuentas de correo de gmail, hotmail, etc. no son permitidas con postmark.
Registro en Postmark
Lo primero que tienes que hacer es crear tu cuenta de usuario en https://postmarkapp.com. Una vez que hayas creado y confirmado tu cuenta podrás configurar un nuevo «servidor» de emails para tu aplicación.
Aquí vas a usar el dominio de tu aplicación, si estas usando, recuerda que siempre es recomendable crear un hostname para tus proyectos locales. Para este proyecto estoy usando «laravel-project.dev».
Luego de hacer click en el botón «Create Server» puedes ver el API KEY que se ha generado, más adelante usaremos este dato para configurar Postmark en Laravel.
Antes de continuar, hay un último paso que debes realizar y se trata de configurar tus «Sender Signatures», de esta manera Postmark verifica que la cuenta de correo que intenta enviar un email utilizando el API KEY especificado, tenga los permisos necesarios para hacerlo.
Para crear una nueva firma puedes hacer click en el botón «Add Sender Signature» y completar los campos requeridos
Si todo va bien hasta ahora, debes haber recibido un correo electrónico similar a este
Envio de Emails en Laravel
Lo primero que debemos hacer es agregar el token generado por Postmark para el servidor que creamos (laravel-project.dev en mi caso) en el archivo .env del proyecto de la siguiente manera:
MAIL_HOST=smtp.postmarkapp.com MAIL_USERNAME=postmark_token_value MAIL_PASSWORD=postmark_token_value
Debes cambiar también el MAIL_HOST usando el valor descrito anteriormente.
De igual forma, puedes especificar la cuenta de correo y el nombre que verán los usuarios que reciban los emails enviados por la aplicación
[email protected] MAIL_FROM_NAME="your name"
Usando TDD
Ya tenemos toda la configuración necesaria para comenzar con el desarrollo. Podemos iniciar creando una nueva clase de prueba para verificar el envío de correos.
<?php namespace Tests\Unit; use Tests\TestCase; use Illuminate\Foundation\Testing\WithoutMiddleware; use Illuminate\Foundation\Testing\DatabaseMigrations; use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Support\Facades\Mail; use App\Mail\UserCreated; class EmailTest extends TestCase { use DatabaseMigrations; use DatabaseTransactions; /** @test */ public function send_email_after_registration() { $this->withoutMiddleware(); $user = factory(\App\User::class)->create([ 'email' => '[email protected]', 'name' => 'jeff' ]); Mail::to($user)->send(new UserCreated($user)); } }
Cambia la dirección de correo de la prueba ([email protected]) por un email real para que verifiques que todo funciona al 100%.
Si ejecutas las pruebas desde la consola, por supuesto van a fallar debido a que no hemos creado el Mailable «UserCreated«. Para generar un nuevo Mailable ejecutamos desde la consola
Creando un nuevo Mailable
En Laravel 5.3 fueron presentados los Mailables como una forma mucho más clara de manejar el envío de emails en el framework.
$ php artisan make:mail UserCreated
Para más información visita este post sobre Enviar emails con Mailables en Laravel 5.3.
Podemos editar el Mailable UserCreated de la siguiente manera:
<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; use Illuminate\Contracts\Queue\ShouldQueue; use App\User; class UserCreated extends Mailable { use Queueable, SerializesModels; public $user; public function __construct(User $user) { $this->user = $user; } public function build() { return $this->markdown('emails.welcome') ->with(['name' => $this->user->email]); } }
En Laravel 5.4 existe soporte para emails con markdown, para más información visita este post sobre Uso de Markdown en los Mailables en Laravel 5.4.
Ahora escribimos la vista welcome.blade.php
dentro de resources/views/emails
:
@component('mail::message') # Welcome {{ $name }} This is a welcome email! Thanks,<br> {{ config('app.name') }} @endcomponent
Probando el envío de emails con Postmark
Nuevamente ejecutamos las pruebas desde la consola:
$ vendor/bin/phpunit --filter=EmailTest
En este punto, el resultado debería ser algo similar a esto:
PHPUnit 5.7.8 by Sebastian Bergmann and contributors. . 1 / 1 (100%) Time: 3.34 seconds, Memory: 16.00MB OK (1 test, 0 assertions)
Y si revisas tu bandeja de entrada en tu cuenta de email podrás ver algo similar a esto:
Refactorizando los Tests
En primer lugar, las pruebas están siendo ejecutadas correctamente, pero no tenemos ningún método de aserción que nos permita saber si el email se está enviando, por ahora solo estamos ejecutando el código necesario para enviar el email y por otro lado, no es muy conveniente realizar envío de correos durante las prueba, veamos cómo podemos «simular» esto:
Editamos el archivo EmailTest de la siguiente manera
public function send_email_after_registration() { $this->withoutMiddleware(); Mail::fake(); $user = factory(\App\User::class)->create([ 'email' => '[email protected]', 'name' => 'jeff' ]); Mail::to($user)->send(new UserCreated($user)); Mail::assertSent(UserCreated::class, function ($mail) use ($user) { return $mail->user->email === $user['email']; }); }
El método Mail::fake() simula el comportamiento real de «Mail» pero sin ejecutar concretamente el envío.
Ejecutando nuevamente las pruebas:
$ vendor/bin/phpunit --filter=EmailTest PHPUnit 5.7.8 by Sebastian Bergmann and contributors. ... 3 / 3 (100%) Time: 1.08 seconds, Memory: 14.00MB OK (3 tests, 3 assertions)
Aprende más sobre desarrollo orientado a pruebas en nuestro curso Crea una aplicación con Laravel.
Envío de emails
Finalmente podemos usar el siguiente código donde sea requerido el envío de este email a través del mailable UserCreated enviando una instancia de App\User.php como parámetro:
Mail::to($user)->send(new UserCreated($user));
Material relacionado
- Mailables con TDD en Laravel 5.3Curso de Eventos y Jobs con Laravel
- Uso de fakes para comprobar el envío de mailables y notificaciones con PHPUnit en Laravel 5.3
Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.