[Laravel]メール確認の単体テスト
環境
Ubuntu 18.04(WSL)
Laravel 5.8
VerifiesEmails
トレイトのverify()
メソッドをVerificationController
でオーバーライドしたので単体テストが必要になりました。
Controllers/Auth/VerificationController.php
protected $redirectTo = '/';
public function verify(Request $request)
{
if ($request->route('id') == $request->user()->getKey() && $request->user()->markEmailAsVerified()) {
event(new Verified($request->user()));
}
return redirect($this->redirectPath())->with('my_status', __('Registration completed.'));
}
メール確認に成功するとトップページにリダイレクトして
Registration completed.
というフラッシュメッセージを表示します。
メール確認は/email/verify/{id}?expires=xxxxx&signature=xxxxx
にGETまたはHEADでリクエストを送ると成功します。
{id}はメール確認をするユーザーのIDです。
expiresとsignatureがついたURLをどうやって作っているかは
/vendor/laravel/framework/src/Illuminate/Auth/Notifications.php
に書いてあります。
/vendor/laravel/framework/src/Illuminate/Auth/Notifications.php
/**
* Get the verification URL for the given notifiable.
*
* @param mixed $notifiable
* @return string
*/
protected function verificationUrl($notifiable)
{
return URL::temporarySignedRoute(
'verification.verify',
Carbon::now()->addMinutes(Config::get('auth.verification.expire', 60)),
['id' => $notifiable->getKey()]
);
}
URL::temporarySignedRoute()
を使えばいい事が分かりました。
第一引数はルーティングの名前、第二引数はexipiresの数字、第三引数はemail/verify/{id}
の{id}
に入れる文字列が値に入った配列です。
参考
単体テストのコード
/tests/Unit/VerificationControllerTest.php
<?php
namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\User;
use Illuminate\Support\Carbon;
class VerificationControllerTest extends TestCase
{
use RefreshDatabase;
/**
* A basic unit test example.
*
* @return void
*/
public function testExample()
{
$user = factory(User::class)->create(
['email_verified_at' => null]
);
$response = $this->actingAs($user)
->get(\URL::temporarySignedRoute(
'verification.verify',
Carbon::now()->addMinutes(\Config::get('auth.verification.expire', 60)),
['id' => $user->id]
))
->assertRedirect('/');
}
}