Home > Blockchain >  Laravel 9 Validation: array is optional but its keys are required: required_array_keys and nullable
Laravel 9 Validation: array is optional but its keys are required: required_array_keys and nullable

Time:11-22

Summary

  1. Context

  2. Sources

    2.1. Unit test

    2.2. FormRequest's rules method

  3. Behaviors

    3.1. Actual behavior

    3.2. Expected behavior

  4. Question


Context

In a Unit test, I want to send data to a FormRequest in a REST call. I am testing the behavior of the validation rules I've written in the rules method of the FormRequest.

Sources

Unit test

    public function test_detach_user_job_status()
    {
        $response = $this->put(route('users.update', ['user' => $this->applier['id']], [
            'job' => [
            ]
        ]));
        $response->assertStatus(200);
    }

FormRequest's rules method

    public function rules()
    {
        return [
            'name' => 'nullable|string',

            'job' => 'nullable|array:id,attach_or_detach,message|required_array_keys:id,attach_or_detach',
            'job.id' => 'integer|gt:0',
            'job.attach_or_detach' => 'boolean',
            'job.message' => 'required_if:job.attach_or_detach,true|string',
        ];
    }

Behaviors

Actual behavior

The test succeeds.

Expected behavior

The test fails. Indeed, the array job is provided but no keys id or attach_or_detach or (eventually) message are provided, whereas the validation rules do specify: required_array_keys:id,attach_or_detach.

Also, if no job array is specified at all, then the validator must not reject the request because this array is not provided, nor its keys: it's perfectly normal since the array must be optional (it is nullable to provide this feature).

Question

Why doesn't Laravel make my test fail since my nullable (= optional) array is provided, and that its keys are required?

CodePudding user response:

You didn't put the correct input. you should put the post body to put() method instead of route() method

change this:

    $response = $this->put(route('users.update', ['user' => $this->applier['id']], [
        'job' => [
        ]
    ]));

to:

    $response = $this->put(route('users.update', ['user' => $this->applier['id']]),
        [
            'job' => []
        ]);
  • Related