mercredi 21 février 2018

Test failing to assert request correctly even when Postman does it right

Good night, I'm having a little trouble here. I'm doing TDD for the first time so I don't know the root of this behavior. This post seems long but mainly because I've copied the mayority of the related code.

Case

Btw, I'm using Laravel as a backend to make an app.

I'm testing that a User with the role admin can create 'Facility' objects but the rest of the users can't. Something really basic.

The problem

When testing the endpoint it let users with the role user (the regular one) to create the object. But when I tried to test it using Postman it worked as it should be: blocking the request.

To manage acl I'm using Laratrust package (it works well, already test it).

Code

routes/api.php // this already has the middlewares: auth & api

Route::post('api/v1/facilities', 'FacilityController@store');

App\Htpp\Controllers\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);
}

App\Http\Requests\Facility\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'
        ];
    }
}

Finally, this is my test:

test\Feature\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');
    }

All the assertions are confirmed except this one:

$response->assertStatus(Response::HTTP_FORBIDDEN); // 403

When I dd($response->json()) it return the regular json of a successfull call. But in Postman it returns the correct one:

{
    "message" : "Unauthorized" // with status code 403
}


Someone know why?

Aucun commentaire:

Enregistrer un commentaire