Returning api resources fails to perform toArray on related models when testing.
Or because we cant provide the current request in testing this is causing issues.
Honestly i dont know whats causing it, but i do know the test result shows the roles property is returning a resource collection instance of the roles, not the array produced from that collection.
The returned response from a login call
protected function authenticated(Request $request, $user)
{
return new \App\Http\Resources\User($user->loadMissing(['roles.permissions']));
}
/**
* Ensure correct logins return user resource
*
* @return void
*/
public function testCorrectLoginReturnsUserResourceTest()
{
$user = factory(User::class)->create([
'app_id' => 1,
'password' => 'mysecretpass'
]);
$user->roles()->save(Role::first());
$resource = (new \App\Http\Resources\User($user->loadMissing(['roles.permissions'])))->resolve();
$response = $this->json('POST', 'login', [
'email' => $user->email,
'password' => 'mysecretpass'
])
->assertStatus(200)
->assertJsonStructure([
'data' => [
'id', 'title', 'first_name', 'last_name', 'full_name', 'email', 'reference', 'created_at', 'updated_at'
],
'links' => [
'self'
]
]);
$this->assertSame($response->json(), $resource);
}
class User extends Resource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request
* @return array
*/
public function toArray($request)
{
return [
'data' => [
'id' => $this->uuid,
'title' => $this->title,
'first_name' => $this->first_name,
'last_name' => $this->last_name,
'full_name' => $this->full_name,
'reference' => $this->reference,
'api_token' => $this->when($request->route() && $request->route()->getName() === 'api.v1.0.0.users.store' || ($request->user() && $request->user()->id === $this->id), $this->api_token),
'email' => $this->email,
'addresses' => Address::collection($this->whenLoaded('addresses')),
'roles' => Role::collection($this->whenLoaded('roles')),
'created_at' => (string) $this->created_at,
'updated_at' => (string) $this->updated_at,
],
'links' => [
'self' => route('api.v1.0.0.users.show', ['user' => $this->uuid]),
],
];
}
}
Failed asserting that Array &0 (
'data' => Array &1 (
'id' => '9fc1e7fc-3bbf-4c69-85d1-0dadc5f1674d'
'title' => 'Mr'
'first_name' => 'Brandi'
'last_name' => 'Feeney'
'full_name' => 'Brandi Feeney'
'reference' => '5a71e65051cfd'
'email' => '[email protected]'
'roles' => Illuminate\Http\Resources\Json\AnonymousResourceCollection Object &000000004c01bdd1000000001d6d5ff2 (
'collects' => 'App\Http\Resources\Role'
'collection' => Illuminate\Support\Collection Object &000000004c01bc29000000001d6d5ff2 (
'items' => Array &2 (
0 => App\Http\Resources\Role Object &000000004c01bc4f000000001d6d5ff2 (
'resource' => App\Models\Role Object &000000004c01bd86000000001d6d5ff2 (
'fillable' => Array &3 (
0 => 'name'
1 => 'label'
)
'hidden' => Array &4 (
0 => 'id'
1 => 'pivot'
2 => 'app_id'
)
'appends' => Array &5 (
0 => 'core'
)
'connection' => 'test'
'table' => null
'primaryKey' => 'id'
'keyType' => 'int'
'incrementing' => true
'with' => Array &6 ()
'withCount' => Array &7 ()
'perPage' => 15
'exists' => true
'wasRecentlyCreated' => false
'attributes' => Array &8 (
'id' => '1'
'uuid' => '21eb3313-79ca-420b-b112-8a024cb80d23'
'name' => 'administrator'
'label' => 'Administrator'
'created_at' => '2018-01-31 15:52:42'
'updated_at' => '2018-01-31 15:52:42'
'app_id' => null
)
'original' => Array &9 (
'id' => '1'
'uuid' => '21eb3313-79ca-420b-b112-8a024cb80d23'
'name' => 'administrator'
'label' => 'Administrator'
'created_at' => '2018-01-31 15:52:42'
'updated_at' => '2018-01-31 15:52:42'
'app_id' => null
'pivot_user_id' => '1'
'pivot_role_id' => '1'
)
'changes' => Array &10 ()
'casts' => Array &11 ()
'dates' => Array &12 ()
'dateFormat' => null
'dispatchesEvents' => Array &13 ()
'observables' => Array &14 ()
'relations' => Array &15 (
'pivot' => Illuminate\Database\Eloquent\Relations\Pivot Object &000000004c01bd87000000001d6d5ff2 (
'pivotParent' => App\Models\User Object &000000004c01a0d4000000001d6d5ff2 (
'dates' => Array &16 (
0 => 'created_at'
1 => 'updated_at'
2 => 'deleted_at'
)
'fillable' => Array &17 (
0 => 'title'
1 => 'first_name'
2 => 'last_name'
3 => 'email'
4 => 'password'
5 => 'api_token'
)
'hidden' => Array &18 (
0 => 'id'
1 => 'password'
2 => 'remember_token'
3 => 'pivot'
4 => 'app_id'
)
'appends' => Array &19 (
0 => 'full_name'
)
'connection' => 'test'
'table' => null
'primaryKey' => 'id'
'keyType' => 'int'
'incrementing' => true
'with' => Array &20 ()
'withCount' => Array &21 ()
'perPage' => 15
'exists' => true
'wasRecentlyCreated' => true
'attributes' => Array &22 (
'uuid' => '9fc1e7fc-3bbf-4c69-85d1-0dadc5f1674d'
'title' => 'Mr'
'first_name' => 'Brandi'
'last_name' => 'Feeney'
'email' => '[email protected]'
'password' => '$2y$04$t7XZe3OP6g79ROayPcS9suesPHuKJJoFJ3bF3nb9wqvkKjRyaAzlu'
'remember_token' => '5ES7sWYPdz'
'api_token' => 'lE0FiO751DpgdkjY3fbPnUnvUKrHGYoF'
'app_id' => 1
'reference' => '5a71e65051cfd'
'updated_at' => '2018-01-31 15:52:48'
'created_at' => '2018-01-31 15:52:48'
'id' => 1
)
'original' => Array &23 (
'uuid' => '9fc1e7fc-3bbf-4c69-85d1-0dadc5f1674d'
'title' => 'Mr'
'first_name' => 'Brandi'
'last_name' => 'Feeney'
'email' => '[email protected]'
'password' => '$2y$04$t7XZe3OP6g79ROayPcS9suesPHuKJJoFJ3bF3nb9wqvkKjRyaAzlu'
'remember_token' => '5ES7sWYPdz'
'api_token' => 'lE0FiO751DpgdkjY3fbPnUnvUKrHGYoF'
'app_id' => 1
'reference' => '5a71e65051cfd'
'updated_at' => '2018-01-31 15:52:48'
'created_at' => '2018-01-31 15:52:48'
'id' => 1
)
'changes' => Array &24 ()
'casts' => Array &25 ()
'dateFormat' => null
'dispatchesEvents' => Array &26 ()
'observables' => Array &27 ()
'relations' => Array &28 (
'roles' => Illuminate\Database\Eloquent\Collection Object &000000004c01bc62000000001d6d5ff2 (
'items' => Array &29 (
0 => App\Models\Role Object &000000004c01bd86000000001d6d5ff2
)
)
)
'touches' => Array &30 ()
'timestamps' => true
'visible' => Array &31 ()
'guarded' => Array &32 (
0 => '*'
)
'rememberTokenName' => 'remember_token'
'forceDeleting' => false
)
'foreignKey' => 'user_id'
'relatedKey' => 'role_id'
'guarded' => Array &33 ()
'connection' => 'test'
'table' => 'role_user'
'primaryKey' => 'id'
'keyType' => 'int'
'incrementing' => true
'with' => Array &34 ()
'withCount' => Array &35 ()
'perPage' => 15
'exists' => true
'wasRecentlyCreated' => false
'attributes' => Array &36 (
'user_id' => '1'
'role_id' => '1'
)
'original' => Array &37 (
'user_id' => '1'
'role_id' => '1'
)
'changes' => Array &38 ()
'casts' => Array &39 ()
'dates' => Array &40 ()
'dateFormat' => null
'appends' => Array &41 ()
'dispatchesEvents' => Array &42 ()
'observables' => Array &43 ()
'relations' => Array &44 ()
'touches' => Array &45 ()
'timestamps' => false
'hidden' => Array &46 ()
'visible' => Array &47 ()
'fillable' => Array &48 ()
)
'permissions' => Illuminate\Database\Eloquent\Collection Object &000000004c01bd85000000001d6d5ff2 (
'items' => Array &49 ()
)
)
'touches' => Array &50 ()
'timestamps' => true
'visible' => Array &51 ()
'guarded' => Array &52 (
0 => '*'
)
)
'with' => Array &53 ()
'additional' => Array &54 ()
)
)
)
'resource' => Illuminate\Support\Collection Object &000000004c01bc29000000001d6d5ff2
'with' => Array &55 ()
'additional' => Array &56 ()
)
'created_at' => '2018-01-31 15:52:48'
'updated_at' => '2018-01-31 15:52:48'
)
'links' => Array &57 (
'self' => 'http://localhost/api/v1.0.0/users/9fc1e7fc-3bbf-4c69-85d1-0dadc5f1674d'
)
) is identical to Array &0 (
'data' => Array &1 (
'id' => '9fc1e7fc-3bbf-4c69-85d1-0dadc5f1674d'
'title' => 'Mr'
'first_name' => 'Brandi'
'last_name' => 'Feeney'
'full_name' => 'Brandi Feeney'
'reference' => '5a71e65051cfd'
'api_token' => 'lE0FiO751DpgdkjY3fbPnUnvUKrHGYoF'
'email' => '[email protected]'
'roles' => Array &2 (
0 => Array &3 (
'data' => Array &4 (
'id' => '21eb3313-79ca-420b-b112-8a024cb80d23'
'name' => 'administrator'
'label' => 'Administrator'
'core' => true
'permissions' => Array &5 ()
'created_at' => '2018-01-31 15:52:42'
'updated_at' => '2018-01-31 15:52:42'
)
'links' => Array &6 (
'self' => ''
)
)
)
'created_at' => '2018-01-31 15:52:48'
'updated_at' => '2018-01-31 15:52:48'
)
'links' => Array &7 (
'self' => 'http://localhost/api/v1.0.0/users/9fc1e7fc-3bbf-4c69-85d1-0dadc5f1674d'
)
).
I can't replicate this, seems to be working fine for me, please test in a fresh laravel app using simple two nested resources, if issue can be replicated on a fresh sample app please share the repo URL so we can clone that project and run the tests.
@leemason - its because the resource is not a json representation when comparing. Try the below, I used something like this and it works perfectly.
$resource = (new \App\Http\Resources\User($user->loadMissing(['roles.permissions'])));
and
$this->assertSame(json_decode($resource->response()->getContent(), true), $response->json());
Most helpful comment
@leemason - its because the resource is not a json representation when comparing. Try the below, I used something like this and it works perfectly.
$resource = (new \App\Http\Resources\User($user->loadMissing(['roles.permissions'])));and
$this->assertSame(json_decode($resource->response()->getContent(), true), $response->json());