I have manually tested the scenario I want:
Admin Users can go to the /codes
section of the site.
Normal users are redirected (302) back to the /dashboard
and have a message Sorry you are not allowed there
when they go to /qr
.
Manual testing passes, yet laravel testing fails.
I am using laravel 5.1
Test for the admin user:
public function testAdminViewCodes()
{
//create an admin user
$user = factory(App\User::class, 'admin')->create();
$this->actingAs($user)
->visit('/codes')
->seePageIs('/codes')
->see('Codes');
}
Test for normal user:
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');
}
test results;
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'
I think there may be an issue with the factories, seems to be always creating an admin user:
$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]);
});
My apologies for how long this question is, but there is another pertanent issue. I am using middleware
to test whether the user is admin:
<?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);
}
}
In 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,
];
And applied to routes:
Route::group(['middleware' => ['auth', 'isadmin']], function()
{
Route::resource('user', 'UserController');
});
Is Middleware ignored? I was sure not to add the use WithoutMiddleware;
statement.
Redirecting to Controller Actions Not only named route but we can also redirect to controller actions. We need to simply pass the controller and name of the action to the action method as shown in the following example. If you want to pass a parameter, you can pass it as the second argument of the action method.
Redirect to a Controller Action The last piece of the puzzle is that you can redirect to a specific Method of a specific Controller, no matter what its Route or URL is – use method action(): return redirect()->action('App\Http\Controllers\BooksController@index');
You have two options:
I recommend you to create tests, beacuse you have doubt now, and in future there is a chance of accidently breaking the factory code, since it's not so obvious.
As an aside: unit tests are not meant to be user experience
tests. For that is would be acceptance
or functional
testing. One of the more popular tools for that is codeception. It combined with phantomjs or selenium can emulate a browser session and get full user experience rendering.
Per docs available at http://codeception.com/docs/01-Introduction docs:
Acceptance Tests : 'Acceptance tests can cover standard but complex scenarios from a user’s perspective. With acceptance tests you can be confident that users, following all defined scenarios, won’t get errors.'
Functional Tests : 'functional tests you emulate a web request ($_GET and $_POST variables) and send it into your application which returns HTML response. '
Unit Tests : 'Testing pieces of code before coupling them together is highly important as well. This way you can be sure that some deeply hidden feature still works, even if it was not covered by functional or acceptance tests. This also proves that you produced stable and testable code.'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With