1 | <?php |
||||
2 | |||||
3 | namespace jeremykenedy\LaravelRoles\Test\Feature; |
||||
4 | |||||
5 | use Illuminate\Database\Events\QueryExecuted; |
||||
6 | use Illuminate\Support\Facades\DB; |
||||
7 | use jeremykenedy\LaravelRoles\Test\RefreshDatabase; |
||||
8 | use jeremykenedy\LaravelRoles\Test\TestCase; |
||||
9 | use jeremykenedy\LaravelRoles\Test\User; |
||||
10 | |||||
11 | class NPlusOneQueriesTest extends TestCase |
||||
12 | { |
||||
13 | use RefreshDatabase; |
||||
0 ignored issues
–
show
introduced
by
![]() |
|||||
14 | |||||
15 | protected $seed = true; |
||||
16 | |||||
17 | protected $usersCount = 10; |
||||
18 | /** |
||||
19 | * @var int in case UsersTableSeeder seeds your users, |
||||
20 | * please indicate their number here |
||||
21 | */ |
||||
22 | protected $usersCountCorrection = 0; |
||||
23 | protected $rolesCount = 3; //correct according to your data |
||||
24 | protected $permissionsCount = 4; //correct according to your data |
||||
25 | |||||
26 | protected $queries = 0; |
||||
27 | |||||
28 | protected function setUp(): void |
||||
29 | { |
||||
30 | parent::setUp(); |
||||
31 | |||||
32 | $this->assertEquals($this->rolesCount, config('roles.models.role')::count()); |
||||
33 | $this->assertEquals($this->permissionsCount, config('roles.models.permission')::count()); |
||||
34 | |||||
35 | DB::listen(function (QueryExecuted $query) { |
||||
0 ignored issues
–
show
The parameter
$query is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
36 | $this->queries++; |
||||
37 | }); |
||||
38 | } |
||||
39 | |||||
40 | /** @test */ |
||||
41 | public function canPreloadRolesOnCollection(): void |
||||
42 | { |
||||
43 | $roleIds = config('roles.models.role')::pluck('id'); |
||||
44 | |||||
45 | User::factory($this->usersCount)->create() |
||||
46 | ->each(function (User $user) use ($roleIds) { |
||||
47 | $user->roles()->attach($roleIds); |
||||
48 | }); |
||||
49 | $this->assertEquals($this->usersCount, User::count() - $this->usersCountCorrection); |
||||
50 | |||||
51 | $this->queries = 0; |
||||
52 | |||||
53 | // without eager load |
||||
54 | $users = User::get(); |
||||
55 | $this->assertQueries(1); |
||||
56 | |||||
57 | $users->each(function (User $user) { |
||||
58 | $user->getRoles(); |
||||
59 | }); |
||||
60 | $this->queries = $this->queries - $this->usersCountCorrection; |
||||
61 | $this->assertQueries($this->usersCount); |
||||
62 | |||||
63 | // with eager load |
||||
64 | $users = User::with('roles')->get(); |
||||
65 | $this->assertQueries(2); |
||||
66 | |||||
67 | $users->each(function (User $user) { |
||||
68 | $user->getRoles(); |
||||
69 | }); |
||||
70 | $this->assertQueries(0); |
||||
71 | } |
||||
72 | |||||
73 | /** @test */ |
||||
74 | public function canAttachRoles() |
||||
75 | { |
||||
76 | /** @var User $user */ |
||||
77 | $user = User::factory()->create(); |
||||
78 | $roleId = config('roles.models.role')::value('id'); |
||||
79 | |||||
80 | $this->queries = 0; |
||||
81 | $user->attachRole($roleId); |
||||
82 | // getRoles + attach |
||||
83 | $this->assertQueries(2); |
||||
84 | |||||
85 | $this->queries = 0; |
||||
86 | $user->detachAllRoles(); |
||||
87 | $user->attachRole($roleId); |
||||
88 | // detach + getRoles + attach |
||||
89 | $this->assertQueries(3); |
||||
90 | } |
||||
91 | |||||
92 | /** @test */ |
||||
93 | public function itCachesRoles() |
||||
94 | { |
||||
95 | /** @var User $user */ |
||||
96 | $user = User::factory()->create(); |
||||
97 | |||||
98 | $this->queries = 0; |
||||
99 | $user->getRoles(); |
||||
100 | $this->assertQueries(1); |
||||
101 | |||||
102 | $user->getRoles(); |
||||
103 | $this->assertQueries(0); |
||||
104 | |||||
105 | $user->roles; |
||||
0 ignored issues
–
show
The property
$roles is declared protected in jeremykenedy\LaravelRoles\Test\User . Since you implement __get , consider adding a @property or @property-read.
![]() |
|||||
106 | $this->assertQueries(0); |
||||
107 | } |
||||
108 | |||||
109 | /** @test */ |
||||
110 | public function itCachesPermissions() |
||||
111 | { |
||||
112 | /** @var User $user */ |
||||
113 | $user = User::factory()->create(); |
||||
114 | $roleIds = config('roles.models.role')::pluck('id'); |
||||
115 | $user->roles()->attach($roleIds); |
||||
116 | |||||
117 | $this->queries = 0; |
||||
118 | $user->getPermissions(); |
||||
119 | // rolePermissions(+getRoles) + userPermissions |
||||
120 | $this->assertQueries(3); |
||||
121 | |||||
122 | $user->getPermissions(); |
||||
123 | $this->assertQueries(0); |
||||
124 | |||||
125 | $user->permissions; |
||||
0 ignored issues
–
show
The property
$permissions is declared protected in jeremykenedy\LaravelRoles\Test\User . Since you implement __get , consider adding a @property or @property-read.
![]() |
|||||
126 | $this->assertQueries(0); |
||||
127 | |||||
128 | /** @var User $user */ |
||||
129 | $user = User::find($user->id); |
||||
130 | |||||
131 | $this->queries = 0; |
||||
132 | $user->getRoles(); |
||||
133 | $this->assertQueries(1); |
||||
134 | $user->getPermissions(); |
||||
135 | // rolePermissions + userPermissions |
||||
136 | $this->assertQueries(2); |
||||
137 | } |
||||
138 | |||||
139 | /** @test */ |
||||
140 | public function canPreloadPermissionsOnCollection(): void |
||||
141 | { |
||||
142 | $roleIds = config('roles.models.role')::pluck('id'); |
||||
143 | |||||
144 | User::factory($this->usersCount)->create() |
||||
145 | ->each(function (User $user) use ($roleIds) { |
||||
146 | $user->roles()->attach($roleIds); |
||||
147 | }); |
||||
148 | $this->assertEquals($this->usersCount, User::count() - $this->usersCountCorrection); |
||||
149 | |||||
150 | $this->queries = 0; |
||||
151 | |||||
152 | // without eager load |
||||
153 | $users = User::get(); |
||||
154 | $this->assertQueries(1); |
||||
155 | |||||
156 | $users->each(function (User $user) { |
||||
157 | $user->getPermissions(); |
||||
158 | }); |
||||
159 | // rolePermissions(+getRoles) + userPermissions |
||||
160 | $this->assertQueries(($this->usersCount + $this->usersCountCorrection) * 3); |
||||
161 | |||||
162 | // with eager load |
||||
163 | // TODO: 'rolePermissions' relation |
||||
164 | $users = User::with('roles', 'userPermissions')->get(); |
||||
165 | $this->assertQueries(3); |
||||
166 | |||||
167 | $users->each(function (User $user) { |
||||
168 | $user->getPermissions(); |
||||
169 | }); |
||||
170 | // TODO: optimize via relations: userPermissions and rolePermissions |
||||
171 | $this->assertQueries(20 + $this->usersCountCorrection * 2); |
||||
172 | // $this->assertQueries(0); |
||||
173 | } |
||||
174 | |||||
175 | protected function assertQueries(int $count): void |
||||
176 | { |
||||
177 | $this->assertEquals($count, $this->queries); |
||||
178 | $this->queries = 0; |
||||
179 | } |
||||
180 | } |
||||
181 |