Passed
Pull Request — master (#5)
by Alex
03:18
created

QueryBuilderTest::testGetQuery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 17
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 29
rs 9.7
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ArpTest\DoctrineQueryFilter;
6
7
use Arp\DoctrineQueryFilter\QueryBuilder;
8
use Arp\DoctrineQueryFilter\QueryBuilderInterface;
9
use Doctrine\Common\Collections\ArrayCollection;
10
use Doctrine\DBAL\Types\Types;
11
use Doctrine\ORM\Configuration;
12
use Doctrine\ORM\EntityManager;
13
use Doctrine\ORM\EntityManagerInterface;
14
use Doctrine\ORM\Query;
15
use Doctrine\ORM\Query\Expr;
16
use Doctrine\ORM\Query\Parameter;
17
use Doctrine\ORM\QueryBuilder as DoctrineQueryBuilder;
18
use PHPUnit\Framework\MockObject\MockObject;
19
use PHPUnit\Framework\TestCase;
20
21
/**
22
 * @author  Alex Patterson <[email protected]>
23
 * @package ArpTest\DoctrineQueryFilter
24
 */
25
final class QueryBuilderTest extends TestCase
26
{
27
    /**
28
     * @var DoctrineQueryBuilder&MockObject
29
     */
30
    private DoctrineQueryBuilder $doctrineQueryBuilder;
31
32
    /**
33
     * Prepare the test case dependencies
34
     */
35
    public function setUp(): void
36
    {
37
        $this->doctrineQueryBuilder = $this->createMock(DoctrineQueryBuilder::class);
38
    }
39
40
    /**
41
     * Assert the class implement QueryBuilderInterface
42
     */
43
    public function testInstanceOfQueryBuilderInterface(): void
44
    {
45
        $queryBuilder = new QueryBuilder($this->doctrineQueryBuilder);
46
47
        $this->assertInstanceOf(QueryBuilderInterface::class, $queryBuilder);
48
    }
49
50
    /**
51
     * Assert calls to createQueryBuilder will return a new instance of itself
52
     */
53
    public function testCreateQueryBuilderWillReturnAnewInstanceOfItself(): void
54
    {
55
        $queryBuilder = new QueryBuilder($this->doctrineQueryBuilder);
56
57
        /** @var EntityManager&MockObject $entityManager */
58
        $entityManager = $this->createMock(EntityManager::class);
59
60
        /** @var DoctrineQueryBuilder&MockObject $newDoctrineQueryBuilder */
61
        $newDoctrineQueryBuilder = $this->createMock(DoctrineQueryBuilder::class);
62
63
        $this->doctrineQueryBuilder->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Doctrine\ORM\QueryBuilder. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

63
        $this->doctrineQueryBuilder->/** @scrutinizer ignore-call */ 
64
                                     expects($this->once())

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
64
            ->method('getEntityManager')
65
            ->willReturn($entityManager);
66
67
        $entityManager->expects($this->once())
68
            ->method('createQueryBuilder')
69
            ->willReturn($newDoctrineQueryBuilder);
70
71
        $this->assertInstanceOf(QueryBuilder::class, $queryBuilder->createQueryBuilder());
72
    }
73
74
    /**
75
     * Assert that calls to getEntityManager will return the internal query builder's entity manager instance
76
     */
77
    public function testGetEntityManagerWillReturnTheConfiguredEntityManagerInstance(): void
78
    {
79
        $queryBuilder = new QueryBuilder($this->doctrineQueryBuilder);
80
81
        /** @var EntityManager&MockObject $entityManager */
82
        $entityManager = $this->createMock(EntityManager::class);
83
84
        $this->doctrineQueryBuilder->expects($this->once())
85
            ->method('getEntityManager')
86
            ->willReturn($entityManager);
87
88
        $queryBuilder->getEntityManager();
89
    }
90
91
    /**
92
     * Assert that calls to getQuery() will proxy and return the wrapped query builders query instance
93
     */
94
    public function testGetWrappedQueryBuilderWillReturnTheDoctrineQueryBuilder(): void
95
    {
96
        $queryBuilder = new QueryBuilder($this->doctrineQueryBuilder);
97
98
        $this->assertSame($this->doctrineQueryBuilder, $queryBuilder->getWrappedQueryBuilder());
99
    }
100
101
    /**
102
     * Assert that calls to expr() will return the internal query builder's Expr instance
103
     */
104
    public function testGetQueryBuilderWillReturnTheConfiguredExprInstance(): void
105
    {
106
        $queryBuilder = new QueryBuilder($this->doctrineQueryBuilder);
107
108
        /** @var Expr&MockObject $expr */
109
        $expr = $this->createMock(Expr::class);
110
111
        $this->doctrineQueryBuilder->expects($this->once())
112
            ->method('expr')
113
            ->willReturn($expr);
114
115
        $queryBuilder->expr();
116
    }
117
118
    /**
119
     * Assert that calls to expr() will return the internal query builder's DQL parts
120
     */
121
    public function testGetEntityManagerWillReturnTheConfiguredExprInstance(): void
122
    {
123
        $queryBuilder = new QueryBuilder($this->doctrineQueryBuilder);
124
125
        $parts = [
126
            'foo' => 'bar',
127
        ];
128
129
        $this->doctrineQueryBuilder->expects($this->once())
130
            ->method('getDQLParts')
131
            ->willReturn($parts);
132
133
        $this->assertSame($parts, $queryBuilder->getQueryParts());
134
    }
135
136
    /**
137
     * Assert the Query instance is returned from getQuery()
138
     */
139
    public function testGetQuery(): void
140
    {
141
        $queryBuilder = new QueryBuilder($this->doctrineQueryBuilder);
142
143
        /** @var EntityManagerInterface&MockObject $entityManager */
144
        $entityManager = $this->createMock(EntityManagerInterface::class);
145
146
        /** @var Configuration&MockObject $configuration */
147
        $configuration = $this->createMock(Configuration::class);
148
149
        $entityManager->expects($this->exactly(2))
150
            ->method('getConfiguration')
151
            ->willReturn($configuration);
152
153
        $configuration->expects($this->once())
154
            ->method('getDefaultQueryHints')
155
            ->willReturn([]);
156
157
        $configuration->expects($this->once())
158
            ->method('isSecondLevelCacheEnabled')
159
            ->willReturn(false);
160
161
        $query = new Query($entityManager);
162
163
        $this->doctrineQueryBuilder->expects($this->once())
164
            ->method('getQuery')
165
            ->willReturn($query);
166
167
        $this->assertSame($query, $queryBuilder->getQuery());
168
    }
169
170
    /**
171
     * Assert that calls to innerJoin() will proxy to the internal query builder
172
     */
173
    public function testInnerJoinWillProxyToInternalQueryBuilder(): void
174
    {
175
        $queryBuilder = new QueryBuilder($this->doctrineQueryBuilder);
176
177
        $name = 'foo';
178
        $alias = 'a';
179
        $type = Expr\Join::ON;
180
        $condition = '1 = 1';
181
        $indexBy = null;
182
183
        $this->doctrineQueryBuilder->expects($this->once())
184
            ->method('innerJoin')
185
            ->with($name, $alias, $type, $condition, $indexBy);
186
187
        $this->assertSame($queryBuilder, $queryBuilder->innerJoin($name, $alias, $type, $condition, $indexBy));
188
    }
189
190
    /**
191
     * Assert that calls to leftJoin() will proxy to the internal query builder
192
     */
193
    public function testLeftJoinWillProxyToInternalQueryBuilder(): void
194
    {
195
        $queryBuilder = new QueryBuilder($this->doctrineQueryBuilder);
196
197
        $name = 'bar';
198
        $alias = 'b';
199
        $type = Expr\Join::ON;
200
        $condition = 'a.test = b.hello';
201
        $indexBy = 'a.name';
202
203
        $this->doctrineQueryBuilder->expects($this->once())
204
            ->method('leftJoin')
205
            ->with($name, $alias, $type, $condition, $indexBy);
206
207
        $this->assertSame($queryBuilder, $queryBuilder->leftJoin($name, $alias, $type, $condition, $indexBy));
208
    }
209
210
    /**
211
     * Assert that calls to getParameters() will proxy to the internal query builder
212
     */
213
    public function testGetParametersWillProxyToInternalQueryBuilder(): void
214
    {
215
        $queryBuilder = new QueryBuilder($this->doctrineQueryBuilder);
216
217
        /** @var ArrayCollection<int, Parameter>&MockObject $parameters */
218
        $parameters = $this->createMock(ArrayCollection::class);
219
220
        $this->doctrineQueryBuilder->expects($this->once())
221
            ->method('getParameters')
222
            ->willReturn($parameters);
223
224
        $this->assertSame($parameters, $queryBuilder->getParameters());
225
    }
226
227
    /**
228
     * Assert that calls to setParameters() will proxy to the internal query builder
229
     */
230
    public function testSetParametersWillProxyToInternalQueryBuilder(): void
231
    {
232
        $queryBuilder = new QueryBuilder($this->doctrineQueryBuilder);
233
234
        /** @var ArrayCollection<int, Parameter>&MockObject $parameters */
235
        $parameters = $this->createMock(ArrayCollection::class);
236
237
        $this->doctrineQueryBuilder->expects($this->once())
238
            ->method('setParameters')
239
            ->with($parameters);
240
241
        $this->assertSame($queryBuilder, $queryBuilder->setParameters($parameters));
242
    }
243
244
    /**
245
     * Assert that calls to setParameter() will proxy to the internal query builder
246
     */
247
    public function testSetParameterWillProxyToInternalQueryBuilder(): void
248
    {
249
        $queryBuilder = new QueryBuilder($this->doctrineQueryBuilder);
250
251
        $name = 'Foo';
252
        $value = 'This is a test value';
253
        $type = Types::STRING;
254
255
        $this->doctrineQueryBuilder->expects($this->once())
256
            ->method('setParameter')
257
            ->with($name, $value, $type);
258
259
        $this->assertSame($queryBuilder, $queryBuilder->setParameter($name, $value, $type));
260
    }
261
262
    /**
263
     * Assert that calls to mergeParameters() will proxy to the internal query builder
264
     */
265
    public function testMergeParametersWillProxyToInternalQueryBuilder(): void
266
    {
267
        $queryBuilder = new QueryBuilder($this->doctrineQueryBuilder);
268
269
        $bParams = $addArgs = [];
270
        $b = [
271
            'bar'  => 456,
272
            'test' => 'This is value from B',
273
        ];
274
        $count = count($b);
275
        for ($x = 1; $x < $count; $x++) {
276
            /** @var Parameter&MockObject $parameter */
277
            $parameter = $this->createMock(Parameter::class);
278
            $bParams[] = $parameter;
279
            $addArgs[] = [$parameter];
280
        }
281
282
        /** @var ArrayCollection<int, Parameter>&MockObject $params */
283
        $params = $this->createMock(ArrayCollection::class);
284
        $this->doctrineQueryBuilder->expects($this->once())
285
            ->method('getParameters')
286
            ->willReturn($params);
287
288
        /** @var QueryBuilderInterface&MockObject $newQueryBuilder */
289
        $newQueryBuilder = $this->createMock(QueryBuilderInterface::class);
290
291
        /** @var ArrayCollection<int, Parameter>&MockObject $newParams */
292
        $newParams = $this->createMock(ArrayCollection::class);
293
294
        $newQueryBuilder->expects($this->once())
295
            ->method('getParameters')
296
            ->willReturn($newParams);
297
298
        $newParams->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Doctrine\Common\Collections\ArrayCollection. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

298
        $newParams->/** @scrutinizer ignore-call */ 
299
                    expects($this->once())

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
299
            ->method('getIterator')
300
            ->willReturn(new \ArrayIterator($bParams));
301
302
        $params->expects($this->exactly(count($bParams)))
303
            ->method('add')
304
            ->withConsecutive(...$addArgs);
305
306
        $this->assertSame($queryBuilder, $queryBuilder->mergeParameters($newQueryBuilder));
307
    }
308
}
309