create(['is_active' => true]); LivewireVolt::test('auth.login') ->set('email', $user->email) ->call('sendMagicLink') ->assertHasNoErrors(); Mail::assertSent(MagicLoginLink::class, function (MagicLoginLink $mail) use ($user) { return $mail->user->is($user) && str_contains($mail->loginUrl, '/magic-login/'); }); $magicLink = MagicLink::query()->firstOrFail(); expect($magicLink->user_id)->toBe($user->id); expect($magicLink->token_hash)->toHaveLength(64); }); test('admin can login with a valid magic link and lands on admin dashboard', function () { /** @var TestCase $this */ $this->seed(RolesAndPermissionsSeeder::class); Mail::fake(); $user = User::factory()->create(['is_active' => true]); $user->assignRole('admin'); LivewireVolt::test('auth.login') ->set('email', $user->email) ->call('sendMagicLink'); $sentMail = null; Mail::assertSent(MagicLoginLink::class, function (MagicLoginLink $mail) use (&$sentMail) { $sentMail = $mail; return true; }); expect($sentMail)->not->toBeNull(); /** @var MagicLoginLink $sentMail */ $this->get($sentMail->loginUrl) ->assertRedirect(route('dashboard', absolute: false)); $this->assertAuthenticatedAs($user); expect(MagicLink::query()->firstOrFail()->consumed_at)->not->toBeNull(); $user->refresh(); expect($user->last_login_at)->not->toBeNull(); expect($user->last_login_ip)->toBe('127.0.0.1'); }); test('customer is redirected to me dashboard after magic link login', function () { /** @var TestCase $this */ $this->seed(RolesAndPermissionsSeeder::class); Mail::fake(); $customer = User::factory()->create(['is_active' => true]); $customer->assignRole('customer'); LivewireVolt::test('auth.login') ->set('email', $customer->email) ->call('sendMagicLink'); $sentMail = null; Mail::assertSent(MagicLoginLink::class, function (MagicLoginLink $mail) use (&$sentMail) { $sentMail = $mail; return true; }); /** @var MagicLoginLink $sentMail */ $this->get($sentMail->loginUrl) ->assertRedirect(route('me.dashboard', absolute: false)); $this->assertAuthenticatedAs($customer); }); test('expired magic link can not be used', function () { /** @var TestCase $this */ $user = User::factory()->create(['is_active' => true]); $plainToken = 'expired-token'; MagicLink::query()->create([ 'user_id' => $user->id, 'token_hash' => hash('sha256', $plainToken), 'purpose' => 'login', 'expires_at' => now()->subMinute(), ]); $this->get(route('magic-links.consume', ['token' => $plainToken])) ->assertRedirect(route('login', absolute: false)); $this->assertGuest(); }); test('consumed magic link can not be reused', function () { /** @var TestCase $this */ $user = User::factory()->create(['is_active' => true]); $plainToken = 'consumed-token'; MagicLink::query()->create([ 'user_id' => $user->id, 'token_hash' => hash('sha256', $plainToken), 'purpose' => 'login', 'expires_at' => now()->addMinutes(5), 'consumed_at' => now()->subMinute(), ]); $this->get(route('magic-links.consume', ['token' => $plainToken])) ->assertRedirect(route('login', absolute: false)); $this->assertGuest(); });