Как протестировать перенаправление авторизации с помощью Laravel?


Я вручную протестировал нужный мне сценарий:

Пользователи с правами администратора могут перейти в раздел /codes сайта. Обычные пользователи перенаправляются (302) обратно на /dashboard и получают сообщение Sorry you are not allowed there, когда они переходят на /qr.

Ручное тестирование проходит, но тестирование laravel завершается неудачей.

Я использую laravel 5.1

Тест для пользователя-администратора:

public function testAdminViewCodes()
    {
        //create an admin user
        $user = factory(App\User::class, 'admin')->create();

        $this->actingAs($user)
            ->visit('/codes')
            ->seePageIs('/codes')
            ->see('Codes');
    }

Тест для обычного пользователя:

    public function testNormalViewCodesFail()
    {
        //create a normal user
        $normal_user = factory(App\User::class)->create();

        //TODO: Fix this failing test FFS

        $this->actingAs($normal_user)
             ->visit('/qr')
             ->seePageIs('/dashboard')
             ->see('Sorry you are not allowed there');
}

Результаты испытаний;

There was 1 failure:

1) AdminTest::testNormalViewQRCodesFail
Did not land on expected page [http://localhost/dashboard].

Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'http://localhost/dashboard'
+'http://localhost/codes'

Я думаю может возникнуть проблема с фабриками, похоже, всегда создается пользователь с правами администратора:

$factory->define(App\User::class, function (Faker\Generator $faker) {
    return [
        'email' => $faker->email,
        'password' => bcrypt(str_random(10)),
        'remember_token' => str_random(10),
        'is_admin' => false,
    ];
});

$factory->defineAs(App\User::class, 'admin', function ($faker) use ($factory) {
    $user = $factory->raw(App\User::class);

    return array_merge($user, ['is_admin' => true]);
});

Приношу свои извинения за то, как долго длится этот вопрос, но есть еще одна важная проблема. Я использую middleware, чтобы проверить, является ли пользователь администратором:

<?php

namespace RMS\Http\Middleware;

use Closure;

class IsAdminMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (app()->env === 'testing') {
            return $next($request);
        }

        if (! $request->user()->isAdmin()) {
          return redirect()->route('dashboard')
              ->with('message', 'Sorry you are not allowed there');
        }

        return $next($request);
    }
}

В Kernel.php:

protected $routeMiddleware = [
        'auth' => \RMS\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'guest' => \RMS\Http\Middleware\RedirectIfAuthenticated::class,
        'isadmin' => \RMS\Http\Middleware\IsAdminMiddleware::class,
    ];

И применяется к маршрутам:

Route::group(['middleware' => ['auth', 'isadmin']], function()
{
    Route::resource('user', 'UserController');
});

Игнорируется ли промежуточное программное обеспечение? Я был уверен, что не буду добавлять оператор use WithoutMiddleware;.

Author: maytham-ɯɐɥʇʎɐɯ, 2016-08-07

3 answers

У вас есть два варианта:

  • лучше создавать тесты для фабрики пользователей, например, она может создавать нужные вам типы пользователей
  • прервите работу с отладчиком после создания пользователя, чтобы проверить его вручную

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

 6
Author: Mikhail Zhuravlev, 2016-08-13 09:18:08

В качестве отступления: модульные тесты не предназначены для user experience тестов. Для этого было бы acceptance или functional тестирование. Одним из наиболее популярных инструментов для этого является кодирование. Он в сочетании с phantomjs или selenium может эмулировать сеанс браузера и получать полную визуализацию пользовательского интерфейса.

Согласно документам, доступным по адресу http://codeception.com/docs/01-Introduction документы:

Приемочные испытания: "Приемочные испытания могут охватывать стандартные, но сложные сценарии с точки зрения пользователя. С помощью приемочных тестов вы можете быть уверены, что пользователи, следуя всем определенным сценариям, не получат ошибок"

.

Функциональные тесты: "Функциональные тесты вы эмулируете веб-запрос (переменные $_GET и $_POST) и отправляете его в свое приложение, которое возвращает HTML-ответ".

Модульные тесты: "Тестирование фрагментов кода перед их объединением также очень важно. Таким образом, вы можете быть уверены, что некоторые глубоко скрытая функция все еще работает, даже если она не была охвачена функциональными или приемочными тестами. Это также доказывает, что вы создали стабильный и проверяемый код"

.
 6
Author: David J Eddy, 2016-08-17 13:14:39

Я бы предложил использовать аутентификацию экземпляра пользователя Auth::login($user); для получения более подробной информации прочитайте здесь.

Этот метод действителен для Laravel 5.x и выше

 4
Author: maytham-ɯɐɥʇʎɐɯ, 2016-08-13 10:14:08