Laravel PHP Unit test.Знакомые тесты, но один провал - PullRequest
0 голосов
/ 17 мая 2018

Эти 2 теста предназначены для сброса пароля. Я использую базовую аутентификацию, которая вышла из коробки с Laravel. Первый тест не пройден. Второй тест проходит. Они очень похожи. Я не понимаю, почему первый тест не пройден.

В первом тесте:

  1. Я создаю пользователя.
  2. Получение токена сброса пароля
  3. Отправка запроса на изменение моего пароля с использованием правильных данных.
  4. Мне постоянно говорят, что у меня ошибка с электронной почтой. Я не понимаю почему.

    <?php
    
    namespace Tests\Controllers\Unit;
    
    use Tests\TestCase;
    use Illuminate\Support\Facades\DB;
    use Illuminate\Support\Facades\Hash;
    use Illuminate\Foundation\Testing\RefreshDatabase;
    
    class ResetPasswordTest extends TestCase
    {
    
        use RefreshDatabase;
    
    
        // This test is currently failing. It's saying I have error with email.
    
        public function test_does_change_a_users_password()
        {
            // Create user 
            $user = factory('App\User')->create();
    
            // This post route creates a new password reset token and stores it into the database.
            $this->post(route('password.email'), ['email' => $user->email]);
    
            // I get the token
            $token = DB::table('password_resets')->whereEmail($user->email)->first()->token;
    
            $this->from(route('password.reset', $token));
    
            // Change password with the correct data
            $response = $this->post('password/reset', [
                'token'                 => $token,
                'email'                 => $user->email,
                'password'              => 'password',
                'password_confirmation' => 'password'
            ]);
    
            // This is true... It tells me I have an error with my email.
            $reponse->assertSessionHasErrors('email');
    
            // This is false. The password is not changed to the new password.
            $this->assertTrue(Hash::check('password', $user->fresh()->password));
        }
    
    
        // This test is the working one.
    
        public function test_does_change_a_users_password2()
        {
            $user = factory('App\User')->create();
    
            $token = Password::createToken($user);
            $new_password = 'bestpassword99';
    
            DB::table('password_resets')->insert([
                'token'   => $token,
                'email'   => $user->email,
            ]);
    
            $this->from(route('password.reset', $token));
    
            $response = $this->post('password/reset', [
                'token'                 => $token,
                'email'                 => $user->email,
                'password'              => $new_password,
                'password_confirmation' => $new_password
            ]);
    
    
            $this->assertTrue(Hash::check($new_password, $user->fresh()->password));
        }
    
    }  
    

1 Ответ

0 голосов
/ 17 мая 2018

Если вы проверите ответ с помощью dd($response), вы увидите, что Laravel жалуется на недействительный токен.

Но почему?- Laravel не хранит точный токен в базе данных.Он хранит хэш токена.Это сделано для того, чтобы тот, кто получил доступ для чтения к базе данных, не мог (легко) сбросить пароли пользователей.

Поэтому вместо получения хеша из базы данных вы хотите получить токен, отправляемый пользователю.

Давайте попробуем извлечь токен из уведомления:

$bag = new \stdClass();

Notification::assertSentTo($user, \Illuminate\Auth\Notifications\ResetPassword::class, function ($notification) use ($bag) {
    $bag->token = $notification->token;
    return true;
});

$token = $bag->token;

и поставить его в тест:

/** @test */
public function does_change_a_users_password()
{
    Notification::fake();

    // Create user
    $user = factory(User::class)->create();

    // This post route creates a new password reset token and stores it into the database.
    $this->post(route('password.email'), ['email' => $user->email]);

    // get the password reset token
    $bag = new \stdClass();
    Notification::assertSentTo($user, ResetPassword::class, function ($notification) use ($bag) {
        $bag->token = $notification->token;
        return true;
    });
    $token = $bag->token;

    $this->from(route('password.reset', $token));

    // Change password with the correct data
    $response = $this->post('password/reset', [
        'token'                 => urlencode($token),
        'email'                 => $user->email,
        'password'              => 'password',
        'password_confirmation' => 'password'
    ]);

    //$response->assertSessionHasErrors('password');

    // Ensure password is changed.
    $this->assertTrue(Hash::check('password', $user->fresh()->password));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...