php - Laravel6 + AdminLTE3 我想知道为什么左侧菜单的授权测试只有在某些情况下才会失败
问题描述
概括
我想测试一下AdminLTE3(jeroennoten/laravel-adminlte)左侧菜单的显示,所以写了下面两个测试。
- 答:以管理员用户身份查看时会出现“测试”菜单。
- B:普通用户查看时不出现“测试”菜单。
如果你只运行其中一个测试,它会成功,但如果你连续运行它们,它会失败。
第二个测试将以 A->B 或 B->A 的顺序失败。
- 如果 B 较晚,将显示“测试”菜单(不显示为正确)。
- 如果 A 较晚,则不会显示“测试”菜单(应该显示)。
如果您将测试方法分开,则每种方法都会成功。
我想知道为什么我不能将两者都放在一种测试方法中。
由于我在创建 Laravel 项目后立即安装了 AdminLTE3 并确认了上述现象,很难相信我的代码正在影响它。很难相信我自己的代码正在影响它。
版本/环境
- 操作系统 Windows10/Mac10.15.7
- php 7.2.20
作曲家.json
"jeroennoten/laravel-adminlte": "^3.5",
"laravel/framework": "^6.20",
确认
确认 | 结果 |
---|---|
如果您实际以普通用户身份登录,请注销,然后以管理员用户身份登录。 | 工作正常。 |
如果两者都使用,测试目标(HomeController)会被调用两次吗? | 它被调用了两次。 |
如果两者都使用,“Gate::define('system-only',~~”的内容会被调用两次吗? | 它只被调用一次。原因不明。 |
代码
侧边菜单部分的代码(摘录)
adminlte.php
<?php
//omitted
[
'text' => 'Test',
'url' => 'admin/pages',
'icon' => 'far fa-fw fa-file',
'label' => 4,
'label_color' => 'success',
'can' => 'system-only'
],
//omitted
授权部分
AuthServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
// 'App\Model' => 'App\Policies\ModelPolicy',
];
public function boot()
{
$this->registerPolicies();
Gate::define("system-only", function ($user) {
return $user->is_admin == 1;
});
}
}
测试目标
家庭控制器.php
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
class HomeController extends Controller
{
public function index()
{
return view("admin.home");
}
}
主页.blade.php
@extends('adminlte::page')
@section('title', 'Dashboard')
@section('content_header')
<h1>Dashboard</h1>
@stop
@section('content')
<p>Welcome to this beautiful admin panel.</p>
@stop
@section('css')
<link rel="stylesheet" href="/css/admin_custom.css">
@stop
@section('js')
<script> console.log('Hi!'); </script>
@stop
测试代码(失败的例子)
<?php
namespace Tests\Feature\Admin;
use App\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\TestCase;
class HomeControllerTest extends TestCase
{
use DatabaseTransactions;
protected $url = "/admin/home";
public function testIndex()
{
$normalUser = factory(User::class)->create([
"id" => 1,
"is_admin" => 0
]);
$adminUser = factory(User::class)->create([
"id" => 2,
"is_admin" => 1
]);
$this->actingAs($adminUser)
->get($this->url)
->assertSuccessful()
->assertSee("Test");
$this->actingAs($normalUser)
->get($this->url)
->assertSuccessful()
->assertDontSee("Test");//failed
}
}
测试代码(成功示例)
<?php
//omitted
//I just split the testIndex into two.
public function testIndexNormal()
{
$normalUser = factory(User::class)->create([
"id" => 1,
"is_admin" => 0
]);
$this->actingAs($normalUser)
->get($this->url)
->assertSuccessful()
->assertDontSee("Test");
}
public function testIndexAdmin()
{
$adminUser = factory(User::class)->create([
"id" => 2,
"is_admin" => 1
]);
$this->actingAs($adminUser)
->get($this->url)
->assertSuccessful()
->assertSee("Test");
}
//omitted
解决方案
推荐阅读
- react-native - 如何从屏幕组件访问 createStackNavigator 中定义的默认路由参数
- video-streaming - 有没有办法识别流视频的编解码器?
- ios - Swift/Regex:如何使用 stringByReplacingMatches(withTemplate) 格式化字符串?
- reactjs - 流类型和多态性
- json - 如何在 go 中构建一个抽象的 json unmarshaller
- javascript - 异步添加元素
- ios - 使用 Apple 登录 - 不同行为模拟器 VS iPhone
- azure - 如何为特定的 windowStartTime 运行管道
- c# - c# 查找列表中最接近的两个数字,其中包含两个数字参数的两列
- elasticsearch - 在尊重 ACL 的同时使用 janusgraph 进行搜索