ssquare's avatar

Help Needed to write test case for laravel index method

My cod for laravel index is :

public function index(Request $request)
{
    $this->authorize('view', User::class);
    if ($request->ajax()) {
        $columns = array(
            0 => 'first_name',
            1 => 'last_name',
            2 => 'email',
            3 => 'role',
            4 => 'created_at',
            5 => 'action',
        );

        $limit  = $request->input('length');
        $start  = $request->input('start');
        $order  = $columns[$request->input('order.0.column')];
        $dir    = $request->input('order.0.dir');
        $search = $request->input('search.value');

        $query = \DB::table('users as u')
            ->join('roles as r', 'r.id', 'u.role_id')
            ->select(
                'u.id',
                'u.first_name',
                'u.last_name',
                'u.email',
                'u.created_at',
                'r.label as role'
            );
        $query->where('u.first_name', 'like', $search . '%')
            ->orWhere('u.last_name', 'like', $search . '%')
            ->orWhere('u.email', 'like', $search . '%')
            ->orWhere('r.label', 'like', $search . '%')
            ->orWhere('u.created_at', 'like', $search . '%');
        $totalData = $query->count();
        $query->orderBy($order, $dir);
        if ($limit != '-1') {
            $query->offset($start)->limit($limit);
        }
        $records = $query->get();
        $totalFiltered = $totalData;
        $data = array();
        if (isset($records)) {
            foreach ($records as $k => $v) {
                $nestedData['id'] = $v->id;
                $nestedData['first_name'] = $v->first_name;
                $nestedData['last_name'] = $v->last_name;
                $nestedData['email'] = $v->email;
                $nestedData['role'] = $v->role;
                $nestedData['created_at'] = \Carbon\Carbon::parse($v->created_at)->format('Y-m-d');
                $nestedData['action'] = \View::make('dashboard.users._action')->with('r',$v)->render();
                $data[] = $nestedData;
            }
        }
        return response()->json([
            "draw" => intval($request->input('draw')),
            "recordsTotal" => intval($totalData),
            "recordsFiltered" => intval($totalFiltered),
            "data" => $data
        ], 200);
    }
    return view('dashboard.users.index');
}

Here, as you can see on the initial page load, it just returns the view dashboard.users.index now from the front end, an ajax request will be sent to this same route. And, on ajax request, it fetch data and sent it. How could a test for this?

I tried to start with the following code but had no success:

    public function test_users_list_is_showing_correctly()
    {
        $this->signIn();
        $this->get($this->endPoint, [], array('HTTP_X-Requested-With' => 'XMLHttpRequest'))
            ->assertStatus(Response::HTTP_OK)
            ->assertJson([
                'data' => [
                    '*' => [
                        'id',
                        'first_name',
                        'last_name',
                        'email',
                        'role',
                        'created_at'
                    ]
                ],
            ]);
    }

Could anyone, please suggest how could I write a good test for this index method, I am too new to this testing so, I am just starting to learn for CRUD Test

0 likes
6 replies
Sinnbeck's avatar

What doesnt work? It just returns the view or?

ssquare's avatar

Here is the error:

Invalid JSON was returned from the route.

On basic request (no ajax):

it simply returns a view.

But, on ajax request it returns something like this:

data: [{id: 189, first_name: "Abby", last_name: "Leannon", email: "[email protected]",…},…]
draw: 1
recordsFiltered: 203
recordsTotal: 203
Sinnbeck's avatar

You can try the build in json() method perhaps

$this->json('POST', $this->endPoint)
            ->assertStatus(Response::HTTP_OK)
            ->assertJson([
                'data' => [
                    '*' => [
                        'id',
                        'first_name',
                        'last_name',
                        'email',
                        'role',
                        'created_at'
                    ]
                ],
            ]);
automica's avatar

If you are writing a CRUD test may I ask why you are POSTing to an index?

Index should be being accessed via a GET.

It that’s an error and you are actually trying to get the data for the index as json, and it’s an API, I would create a separate endpoint for it, add to your api routes. If there’s shared functionality between your api and standard web routes then extract that to a shared class and use in both places. This will give you two simpler methods and will be much easier to to maintain and test.

ssquare's avatar

My bad I have updated my question, yeah you are right it's a "GET" request, and I have used $request->ajax() to return data for the jquery data table request.

automica's avatar

in which case, do as @sinnbeck suggested but with:

$this->json('GET', route('NAME OF ROUTE'))
            ->assertStatus(Response::HTTP_OK)
            ->assertJson([
                'data' => [
                    '*' => [
                        'id',
                        'first_name',
                        'last_name',
                        'email',
                        'role',
                        'created_at'
                    ]
                ],
            ]);

changing route('NAME OF ROUTE') to whatever your route is.

1 like

Please or to participate in this conversation.