AuthPasswordBrokerTest.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. namespace Illuminate\Tests\Auth;
  3. use Illuminate\Auth\Passwords\PasswordBroker;
  4. use Illuminate\Auth\Passwords\TokenRepositoryInterface;
  5. use Illuminate\Contracts\Auth\CanResetPassword;
  6. use Illuminate\Contracts\Auth\PasswordBroker as PasswordBrokerContract;
  7. use Illuminate\Contracts\Auth\UserProvider;
  8. use Illuminate\Support\Arr;
  9. use Mockery as m;
  10. use PHPUnit\Framework\TestCase;
  11. use UnexpectedValueException;
  12. class AuthPasswordBrokerTest extends TestCase
  13. {
  14. protected function tearDown(): void
  15. {
  16. m::close();
  17. }
  18. public function testIfUserIsNotFoundErrorRedirectIsReturned()
  19. {
  20. $mocks = $this->getMocks();
  21. $broker = $this->getMockBuilder(PasswordBroker::class)
  22. ->onlyMethods(['getUser'])
  23. ->addMethods(['makeErrorRedirect'])
  24. ->setConstructorArgs(array_values($mocks))
  25. ->getMock();
  26. $broker->expects($this->once())->method('getUser')->willReturn(null);
  27. $this->assertSame(PasswordBrokerContract::INVALID_USER, $broker->sendResetLink(['credentials']));
  28. }
  29. public function testIfTokenIsRecentlyCreated()
  30. {
  31. $mocks = $this->getMocks();
  32. $broker = $this->getMockBuilder(PasswordBroker::class)->addMethods(['emailResetLink', 'getUri'])->setConstructorArgs(array_values($mocks))->getMock();
  33. $mocks['users']->shouldReceive('retrieveByCredentials')->once()->with(['foo'])->andReturn($user = m::mock(CanResetPassword::class));
  34. $mocks['tokens']->shouldReceive('recentlyCreatedToken')->once()->with($user)->andReturn(true);
  35. $user->shouldReceive('sendPasswordResetNotification')->with('token');
  36. $this->assertSame(PasswordBrokerContract::RESET_THROTTLED, $broker->sendResetLink(['foo']));
  37. }
  38. public function testGetUserThrowsExceptionIfUserDoesntImplementCanResetPassword()
  39. {
  40. $this->expectException(UnexpectedValueException::class);
  41. $this->expectExceptionMessage('User must implement CanResetPassword interface.');
  42. $broker = $this->getBroker($mocks = $this->getMocks());
  43. $mocks['users']->shouldReceive('retrieveByCredentials')->once()->with(['foo'])->andReturn('bar');
  44. $broker->getUser(['foo']);
  45. }
  46. public function testUserIsRetrievedByCredentials()
  47. {
  48. $broker = $this->getBroker($mocks = $this->getMocks());
  49. $mocks['users']->shouldReceive('retrieveByCredentials')->once()->with(['foo'])->andReturn($user = m::mock(CanResetPassword::class));
  50. $this->assertEquals($user, $broker->getUser(['foo']));
  51. }
  52. public function testBrokerCreatesTokenAndRedirectsWithoutError()
  53. {
  54. $mocks = $this->getMocks();
  55. $broker = $this->getMockBuilder(PasswordBroker::class)->addMethods(['emailResetLink', 'getUri'])->setConstructorArgs(array_values($mocks))->getMock();
  56. $mocks['users']->shouldReceive('retrieveByCredentials')->once()->with(['foo'])->andReturn($user = m::mock(CanResetPassword::class));
  57. $mocks['tokens']->shouldReceive('recentlyCreatedToken')->once()->with($user)->andReturn(false);
  58. $mocks['tokens']->shouldReceive('create')->once()->with($user)->andReturn('token');
  59. $user->shouldReceive('sendPasswordResetNotification')->with('token');
  60. $this->assertSame(PasswordBrokerContract::RESET_LINK_SENT, $broker->sendResetLink(['foo']));
  61. }
  62. public function testRedirectIsReturnedByResetWhenUserCredentialsInvalid()
  63. {
  64. $broker = $this->getBroker($mocks = $this->getMocks());
  65. $mocks['users']->shouldReceive('retrieveByCredentials')->once()->with(['creds'])->andReturn(null);
  66. $this->assertSame(PasswordBrokerContract::INVALID_USER, $broker->reset(['creds'], function () {
  67. //
  68. }));
  69. }
  70. public function testRedirectReturnedByRemindWhenRecordDoesntExistInTable()
  71. {
  72. $creds = ['token' => 'token'];
  73. $broker = $this->getBroker($mocks = $this->getMocks());
  74. $mocks['users']->shouldReceive('retrieveByCredentials')->once()->with(Arr::except($creds, ['token']))->andReturn($user = m::mock(CanResetPassword::class));
  75. $mocks['tokens']->shouldReceive('exists')->with($user, 'token')->andReturn(false);
  76. $this->assertSame(PasswordBrokerContract::INVALID_TOKEN, $broker->reset($creds, function () {
  77. //
  78. }));
  79. }
  80. public function testResetRemovesRecordOnReminderTableAndCallsCallback()
  81. {
  82. unset($_SERVER['__password.reset.test']);
  83. $broker = $this->getMockBuilder(PasswordBroker::class)
  84. ->onlyMethods(['validateReset'])
  85. ->addMethods(['getPassword', 'getToken'])
  86. ->setConstructorArgs(array_values($mocks = $this->getMocks()))
  87. ->getMock();
  88. $broker->expects($this->once())->method('validateReset')->willReturn($user = m::mock(CanResetPassword::class));
  89. $mocks['tokens']->shouldReceive('delete')->once()->with($user);
  90. $callback = function ($user, $password) {
  91. $_SERVER['__password.reset.test'] = compact('user', 'password');
  92. return 'foo';
  93. };
  94. $this->assertSame(PasswordBrokerContract::PASSWORD_RESET, $broker->reset(['password' => 'password', 'token' => 'token'], $callback));
  95. $this->assertEquals(['user' => $user, 'password' => 'password'], $_SERVER['__password.reset.test']);
  96. }
  97. public function testExecutesCallbackInsteadOfSendingNotification()
  98. {
  99. $executed = false;
  100. $closure = function () use (&$executed) {
  101. $executed = true;
  102. };
  103. $mocks = $this->getMocks();
  104. $broker = $this->getMockBuilder(PasswordBroker::class)->addMethods(['emailResetLink', 'getUri'])->setConstructorArgs(array_values($mocks))->getMock();
  105. $mocks['users']->shouldReceive('retrieveByCredentials')->once()->with(['foo'])->andReturn($user = m::mock(CanResetPassword::class));
  106. $mocks['tokens']->shouldReceive('recentlyCreatedToken')->once()->with($user)->andReturn(false);
  107. $mocks['tokens']->shouldReceive('create')->once()->with($user)->andReturn('token');
  108. $user->shouldReceive('sendPasswordResetNotification')->with('token');
  109. $this->assertEquals(PasswordBrokerContract::RESET_LINK_SENT, $broker->sendResetLink(['foo'], $closure));
  110. $this->assertTrue($executed);
  111. }
  112. protected function getBroker($mocks)
  113. {
  114. return new PasswordBroker($mocks['tokens'], $mocks['users']);
  115. }
  116. protected function getMocks()
  117. {
  118. return [
  119. 'tokens' => m::mock(TokenRepositoryInterface::class),
  120. 'users' => m::mock(UserProvider::class),
  121. ];
  122. }
  123. }