4

I am testing an API endpoint returned Laravel resource with pagination

 public function test_showing_all_plans(): void
 {
    $plans = Plan::where('is_active', true)
        ->paginate(10);

    $resource = PlansResource::collection($plans);

    $this->withHeaders([
        'Accept' => 'application/json',
        'Content-Type' => 'application/json',
        'AppKey' => 5,
    ])
        ->json('GET', '/api/customer/plans')
        ->assertStatus(200)
        ->assertExactJson([
            $resource->response()->getData(true),
        ]);
}

so my problem is the returned result is not the same because of the path of the endpoint is not equal to the returned of the resource.

This is the result returned from the endpoint:

"links": {
        "first": "http://www.site.local/api/customer/plans?page=1",
        "last": "http://www.site.local/api/customer/plans?page=3",
        "next": "http://www.site.local/api/customer/plans?page=2",
        "prev": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 3,
        "path": "http://www.site.local/api/customer/plans",
        "per_page": 10,
        "to": 10,
        "total": 24
    }

This is the code returned from the resource ' $resource->response()->getData(true) '

 "links": {
            "first": "http://www.site.local?page=1",
            "last": "http://www.site.local?page=3",
            "next": "http://www.site.local?page=2",
            "prev": null
        },
        "meta": {
            "current_page": 1,
            "from": 1,
            "last_page": 3,
            "path": "http://www.site.local",
            "per_page": 10,
            "to": 10,
          }

so how can I pass the endpoint to my code or how can I make them equal, and is there is a proper way to test Laravel resource?

2 Answers 2

13

The answer lies in the JsonResource::response() method — this method accepts an optional Illuminate\Http\Request $request parameter, which will give context as to where you're trying to use the resource.

Calling $this->json('GET', '/api/customer/plans') will produce a Request object that looks something like this (heavily truncated for brevity):

Illuminate\Http\Request {
  pathInfo: "/api/customer/plans"
  requestUri: "/api/customer/plans"
  method: "GET"
}

Meanwhile, if no Request object is provided when resolving API resources, Laravel will create a new one using defaults, which will look more like this:

Illuminate\Http\Request {
  pathInfo: "/"
  requestUri: "/"
  method: "GET"
}

To make sure these match, you'll want to create a new Request object in your test case that looks something like what you're requesting, then pass it to the $resource->response() call:

use Illuminate\Http\Request;

public function test_showing_all_plans(): void
 {
    $plans    = Plan::where('is_active', true)->paginate(10);
    $resource = PlansResource::collection($plans);
    $request  = Request::create('/api/customer/plans', 'GET');

    $this->getJson('/api/customer/plans', [
         'AppKey' => 5,
       ])
        ->assertStatus(200)
        ->assertExactJson([
            $resource->response($request)->getData(true),
        ]);
}
Sign up to request clarification or add additional context in comments.

Comments

0

In my case (Laravel 8.x), I was forced to use Paginator::currentPathResolver to achieve success:

use Illuminate\Http\Request;

public function test_showing_all_plans(): void
 {
    $request  = Request::create('/api/customer/plans', 'GET');
    Paginator::currentPathResolver(fn () => $request->url());
    $plans    = Plan::where('is_active', true)->paginate(10);
    $resource = PlansResource::collection($plans);

    $this->getJson('/api/customer/plans', [
         'AppKey' => 5,
       ])
        ->assertStatus(200)
        ->assertExactJson([
            $resource->response($request)->getData(true),
        ]);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.