顺便说一句,我使用Laravel作为后端制作应用程序。
我正在测试User
角色为admin
的{{1}}可以创建'设施'对象,但其他用户不能。非常基本的东西。
在测试端点时,它允许具有角色user
(常规端点)的用户创建对象。但是当我尝试使用Postman测试它时,它应该是:阻止请求。
使用Laratrust软件包来管理acl(它运行良好,已经测试过了)。
routes / api.php //这已经有了中间件:auth& API
Route::post('api/v1/facilities', 'FacilityController@store');
应用\ HTPP \控制器\ FacilityController.php
use App\Http\Requests\Facility\CreateFacilityRequest;
use App\Http\Resources\FacilityResource;
use App\Repositories\FacilityRepository;
use App\Services\ImageService;
use Illuminate\Http\Response;
// some code
/**
* Create a new Facility
*
* @param CreateFacilityRequest $request
* @return \Illuminate\Http\JsonResponse
*/
public function store(CreateFacilityRequest $request)
{
$data = $request->only(['name']);
$file = $request->file('image');
$data['image'] = ImageService::storeAs('images/facilities', $file, 'friendly', $data['name']);
$facility = $this->facilityRepository->create($data);
return response()->json([
"message" => "The facility has been added.",
"data" => new FacilityResource($facility)
], Response::HTTP_CREATED);
}
应用\ HTTP \请求\设施\ CreateFacilityRequest.php
class CreateFacilityRequest extends FormRequest {
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return auth()->user()->can('create-facilities');
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string|unique:facilities,name',
'image' => 'required|image'
];
}
}
最后,这是我的测试:
测试\特征\ FacilityTest.php
/**
* @test
* Test for: a Facility can be registered only by an admin.
*/
public function a_facility_can_be_registered_only_by_an_admin()
{
/** Given a correct information for a facility */
\Storage::fake('public');
$data = ["name" => "Facility A", 'image' => UploadedFile::fake()->image('facility-a.jpg') ];
/** When the request is made by an admin */
$admin = $this->createUser([], 'admin');
$response = $this->apiAs($admin, 'POST','/api/v1/facilities', $data);
/** Then the facility should be registered */
$response->assertStatus(Response::HTTP_CREATED); // 201
/** When the request is made by somebody else */
$data = ["name" => "Facility B", 'image' =>UploadedFile::fake()->image('facility-b.jpg') ];
$regular_user = $this->createUser([], 'user');
$response = $this->apiAs($regular_user, 'POST','/api/v1/facilities', $data);
/** Then the request should be declined */
$this->assertTrue($regular_user->hasRole('user'));
$this->assertFalse($regular_user->can('create-facilities'));
$response->assertStatus(Response::HTTP_FORBIDDEN); // 403
\Storage::disk('facilities')->assertMissing('facility-b.jpg');
}
除了这一个之外,所有的断言都被确认了:
$response->assertStatus(Response::HTTP_FORBIDDEN); // 403
输出是这样的:
预期状态代码403但收到201。
声明false为真的失败。
时间:447毫秒,内存:20.00MB
FAILURES!测试:1,断言:4,失败:1。
使用退出代码1完成处理
当我dd($response->json())
时,它返回成功通话的常规json。但在邮递员中,它会返回正确的一个:
{
"message" : "Unauthorized" // with status code 403
}
受保护的功能apiAs()
protected function apiAs($user, $method, $uri, array $data = [], array $headers = []) : TestResponse
{
$headers = array_merge([
'Authorization' => 'Bearer '.\JWTAuth::fromUser($user),
'Accept' => 'application/json'
], $headers);
return $this->api($method, $uri, $data, $headers);
}
protected function api($method, $uri, array $data = [], array $headers = [])
{
return $this->json($method, $uri, $data, $headers);
}
答案 0 :(得分:2)
这是因为您正在使用jwt-auth apiAs()
方法缓存与此行上的响应相关联的用户标识符:
'Authorization' => 'Bearer '.\JWTAuth::fromUser($user),
这会导致您的$response
变量(第二次以普通用户身份获取API)返回管理员的第一个缓存数据。
我会将这些断言分成单独的测试,以及您的命名当前是a_facility_can_be_registered_only_by_an_admin()
。 a_facility_cannot_be_registered_by_a_user_that_is_not_an_admin()
可能是一个适用的名称,可以绕过此缓存。