Test Setup Failed
Push — master ( 698635...8c1479 )
by Jeremy
05:28 queued 12s
created

NPlusOneQueriesTest::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
dl 0
loc 9
rs 10
c 1
b 0
f 0
cc 1
nc 1
nop 0
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
The trait jeremykenedy\LaravelRoles\Test\RefreshDatabase requires some properties which are not provided by jeremykenedy\LaravelRole...ure\NPlusOneQueriesTest: $connectionsToTransact, $dropTypes, $dropViews
Loading history...
14
15
    protected $seed = true;
16
17
    protected $usersCount = 10;
18
    protected $rolesCount = 3;
19
    protected $permissionsCount = 4;
20
21
    protected $queries = 0;
22
23
    protected function setUp(): void
24
    {
25
        parent::setUp();
26
27
        $this->assertEquals($this->rolesCount, config('roles.models.role')::count());
28
        $this->assertEquals($this->permissionsCount, config('roles.models.permission')::count());
29
30
        DB::listen(function (QueryExecuted $query) {
0 ignored issues
show
Unused Code introduced by
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 ignore-unused  annotation

30
        DB::listen(function (/** @scrutinizer ignore-unused */ QueryExecuted $query) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
31
            $this->queries++;
32
        });
33
    }
34
35
    /** @test */
36
    public function canPreloadRolesOnCollection(): void
37
    {
38
        $roleIds = config('roles.models.role')::pluck('id');
39
40
        User::factory($this->usersCount)->create()
41
            ->each(function (User $user) use ($roleIds) {
42
                $user->roles()->attach($roleIds);
43
            });
44
        $this->assertEquals($this->usersCount, User::count());
45
46
        $this->queries = 0;
47
48
        // without eager load
49
        $users = User::get();
50
        $this->assertQueries(1);
51
52
        $users->each(function (User $user) {
53
            $user->getRoles();
54
        });
55
        $this->assertQueries($this->usersCount);
56
57
        // with eager load
58
        $users = User::with('roles')->get();
59
        $this->assertQueries(2);
60
61
        $users->each(function (User $user) {
62
            $user->getRoles();
63
        });
64
        $this->assertQueries(0);
65
    }
66
67
    /** @test */
68
    public function canAttachRoles()
69
    {
70
        /** @var User $user */
71
        $user = User::factory()->create();
72
        $roleId = config('roles.models.role')::value('id');
73
74
        $this->queries = 0;
75
        $user->attachRole($roleId);
76
        // getRoles + attach
77
        $this->assertQueries(2);
78
79
        $this->queries = 0;
80
        $user->detachAllRoles();
81
        $user->attachRole($roleId);
82
        // detach + getRoles + attach
83
        $this->assertQueries(3);
84
    }
85
86
    /** @test */
87
    public function itCachesRoles()
88
    {
89
        /** @var User $user */
90
        $user = User::factory()->create();
91
92
        $this->queries = 0;
93
        $user->getRoles();
94
        $this->assertQueries(1);
95
96
        $user->getRoles();
97
        $this->assertQueries(0);
98
99
        $user->roles;
0 ignored issues
show
Bug Best Practice introduced by
The property $roles is declared protected in jeremykenedy\LaravelRoles\Test\User. Since you implement __get, consider adding a @property or @property-read.
Loading history...
100
        $this->assertQueries(0);
101
    }
102
103
    /** @test */
104
    public function itCachesPermissions()
105
    {
106
        /** @var User $user */
107
        $user = User::factory()->create();
108
        $roleIds = config('roles.models.role')::pluck('id');
109
        $user->roles()->attach($roleIds);
110
111
        $this->queries = 0;
112
        $user->getPermissions();
113
        // rolePermissions(+getRoles) + userPermissions
114
        $this->assertQueries(3);
115
116
        $user->getPermissions();
117
        $this->assertQueries(0);
118
119
        $user->permissions;
0 ignored issues
show
Bug Best Practice introduced by
The property $permissions is declared protected in jeremykenedy\LaravelRoles\Test\User. Since you implement __get, consider adding a @property or @property-read.
Loading history...
120
        $this->assertQueries(0);
121
122
        /** @var User $user */
123
        $user = User::find($user->id);
124
125
        $this->queries = 0;
126
        $user->getRoles();
127
        $this->assertQueries(1);
128
        $user->getPermissions();
129
        // rolePermissions + userPermissions
130
        $this->assertQueries(2);
131
    }
132
133
    /** @test */
134
    public function canPreloadPermissionsOnCollection(): void
135
    {
136
        $roleIds = config('roles.models.role')::pluck('id');
137
138
        User::factory($this->usersCount)->create()
139
            ->each(function (User $user) use ($roleIds) {
140
                $user->roles()->attach($roleIds);
141
            });
142
        $this->assertEquals($this->usersCount, User::count());
143
144
        $this->queries = 0;
145
146
        // without eager load
147
        $users = User::get();
148
        $this->assertQueries(1);
149
150
        $users->each(function (User $user) {
151
            $user->getPermissions();
152
        });
153
        // rolePermissions(+getRoles) + userPermissions
154
        $this->assertQueries($this->usersCount * 3);
155
156
        // with eager load
157
        // TODO: 'rolePermissions' relation
158
        $users = User::with('roles', 'userPermissions')->get();
159
        $this->assertQueries(3);
160
161
        $users->each(function (User $user) {
162
            $user->getPermissions();
163
        });
164
        // TODO: optimize via relations: userPermissions and rolePermissions
165
        $this->assertQueries(20);
166
        // $this->assertQueries(0);
167
    }
168
169
    protected function assertQueries(int $count): void
170
    {
171
        $this->assertEquals($count, $this->queries);
172
        $this->queries = 0;
173
    }
174
}
175