0

Im writing phpunit tests. I write this test:

public function testValidationFailure(){
    $new_item_data = ['bad_param' => 'fancy_name'];
    $response = 
    $this->withHeaders(['identifier' => "identifier"])
    ->post("localhost/item", $new_item_data);
    $response->assertStatus(Response::HTTP_FOUND);
    echo "status:" . $response->status();
}

And I have this in api.php

Route::middleware('ensure.token')->resource('item', ItemController::class)->only(['store', 'destroy', 'update']);   

The controller looks like this:

class ItemController extends Controller{
    public function store(Request $request): JsonResponse{
    try{
        $request->validate(['name' => 'required']);
        //code to insert new row in table
    } catch(Exception $e){
        return response()->json(['error' => "could_not_save_item"], Response::HTTP_INTERNAL_SERVER_ERROR);
    }

Now, why is the status returned equals to "302"? i would expect another code, more like "validation-failed"-like. 302 is "HTTP_FOUND", which to me does not sound like an error.
How can I take over when validation fails and send an http code that makes more sense? Or why is laravel returning this strange http code?

oderfla
  • 1,695
  • 4
  • 24
  • 49
  • 1
    Actually Laravel automatically redirects. This is the feature they provided to not worry about redirecting manually if validation fails. – nice_dev Dec 06 '22 at 07:52
  • 1
    Does this answer your question? [Disable request validation redirect in Laravel 5.4](https://stackoverflow.com/questions/46350307/disable-request-validation-redirect-in-laravel-5-4) – nice_dev Dec 06 '22 at 07:52

1 Answers1

0

This is because you are using ->post(), rather than ->jsonPost() in your test. Using post does a request with Accept: text/html and jsonPost does a request with Accept: application/json.

When encountering a validation failure, laravel internally conditionally asks if it should return json. If it should return json, it'll generate a 422 Unprocessable Entity response. If it shouldn't, it'll instead redirect using a 302 Found to the previous url by default.

Changing your ->post() to ->jsonPost() should fix your test.

jgawrych
  • 3,322
  • 1
  • 28
  • 38