Passed
Push — master ( 60a4ae...29fcc8 )
by
unknown
46:42 queued 14:26
created

testSearchCountWithSearchResultCountPlugin()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 51
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 34
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 51
rs 9.376

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
declare(strict_types = 1);
9
10
namespace SprykerTest\Client\CmsPageSearch;
11
12
use Codeception\Test\Unit;
13
use PHPUnit\Framework\MockObject\MockObject;
14
use Spryker\Client\CmsPageSearch\CmsPageSearchClient;
15
use Spryker\Client\CmsPageSearch\CmsPageSearchConfig;
16
use Spryker\Client\CmsPageSearch\CmsPageSearchFactory;
17
use Spryker\Client\CmsPageSearch\Dependency\Client\CmsPageSearchToSearchBridgeInterface;
18
use Spryker\Client\SearchExtension\Dependency\Plugin\QueryInterface;
19
use Spryker\Client\SearchExtension\Dependency\Plugin\SearchResultCountPluginInterface;
20
use Spryker\Shared\Kernel\StrategyResolver;
21
use stdClass;
22
23
/**
24
 * Auto-generated group annotations
25
 *
26
 * @group SprykerTest
27
 * @group Client
28
 * @group CmsPageSearch
29
 * @group CmsPageSearchClientTest
30
 * Add your own group annotations below this line
31
 */
32
class CmsPageSearchClientTest extends Unit
33
{
34
    /**
35
     * @var string
36
     */
37
    protected const TEST_SEARCH_STRING = 'test search';
38
39
    /**
40
     * @var array<string, mixed>
41
     */
42
    protected const TEST_REQUEST_PARAMETERS = [
43
        'page' => 1,
44
        'ipp' => 12,
45
    ];
46
47
    /**
48
     * @var array<string, mixed>
49
     */
50
    protected const TEST_SEARCH_RESULTS = [
51
        'cms-page' => [
52
            ['id' => 1, 'name' => 'Test Cms page 1'],
53
            ['id' => 2, 'name' => 'Test Cms page 2'],
54
        ],
55
        'pagination' => [
56
            'numFound' => 2,
57
            'currentPage' => 1,
58
        ],
59
    ];
60
61
    /**
62
     * @var int
63
     */
64
    protected const TEST_TOTAL_HITS = 42;
65
66
    /**
67
     * @var \SprykerTest\Client\CmsPageSearch\CmsPageSearchClientTester
68
     */
69
    protected $tester;
70
71
    /**
72
     * Test search method delegates to factory and search client properly.
73
     *
74
     * @return void
75
     */
76
    public function testSearchDelegatesToFactoryAndSearchClient(): void
77
    {
78
        // Arrange
79
        $searchClientMock = $this->createSearchClientMock();
80
        $factoryMock = $this->createFactoryMock();
81
        $queryMock = $this->createQueryWithSearchTypeMock(CmsPageSearchConfig::SEARCH_STRATEGY_ELASTICSEARCH);
82
        $strategyResolverMock = $this->createStrategyResolverMock([]);
83
84
        $queryExpanderPlugins = [];
85
        $resultFormatters = [];
86
87
        $factoryMock
88
            ->expects($this->once())
89
            ->method('createCmsPageSearchQuery')
90
            ->with(static::TEST_SEARCH_STRING)
91
            ->willReturn($queryMock);
92
93
        $factoryMock
94
            ->expects($this->once())
95
            ->method('createCmsPageSearchQueryExpanderPluginsStrategyResolver')
96
            ->willReturn($strategyResolverMock);
97
98
        $factoryMock
99
            ->expects($this->once())
100
            ->method('createCmsPageSearchResultFormattersStrategyResolver')
101
            ->willReturn($strategyResolverMock);
102
103
        $factoryMock
104
            ->method('getSearchClient')
105
            ->willReturn($searchClientMock);
106
107
        $searchClientMock
108
            ->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Spryker\Client\CmsPageSe...ToSearchBridgeInterface. ( Ignorable by Annotation )

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

108
            ->/** @scrutinizer ignore-call */ 
109
              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...
109
            ->method('expandQuery')
110
            ->with($queryMock, $queryExpanderPlugins, static::TEST_REQUEST_PARAMETERS)
111
            ->willReturn($queryMock);
112
113
        $searchClientMock
114
            ->expects($this->once())
115
            ->method('search')
116
            ->with($queryMock, $resultFormatters, static::TEST_REQUEST_PARAMETERS)
117
            ->willReturn(static::TEST_SEARCH_RESULTS);
118
119
        $client = new CmsPageSearchClient();
120
        $client->setFactory($factoryMock);
121
122
        // Act
123
        $client->search(static::TEST_SEARCH_STRING, static::TEST_REQUEST_PARAMETERS);
124
125
        // Assert - The test verifies that all expected methods were called with correct parameters
126
        // through the ->expects($this->once()) assertions above
127
    }
128
129
    /**
130
     * Test search method without SearchTypeIdentifierInterface query.
131
     *
132
     * @return void
133
     */
134
    public function testSearchWithoutSearchTypeIdentifierUsesNullStrategy(): void
135
    {
136
        // Arrange
137
        $searchClientMock = $this->createSearchClientMock();
138
        $factoryMock = $this->createFactoryMock();
139
        $queryMock = $this->createQueryMock(); // Query without SearchTypeIdentifierInterface
140
141
        $queryExpanderPlugins = ['null_strategy_expander'];
142
        $resultFormatters = ['null_strategy_formatter'];
143
144
        $queryExpanderStrategyResolverMock = $this->getMockBuilder('Spryker\Shared\Kernel\StrategyResolver')
145
            ->disableOriginalConstructor()
146
            ->onlyMethods(['get'])
147
            ->getMock();
148
149
        $resultFormattersStrategyResolverMock = $this->getMockBuilder('Spryker\Shared\Kernel\StrategyResolver')
150
            ->disableOriginalConstructor()
151
            ->onlyMethods(['get'])
152
            ->getMock();
153
154
        $factoryMock
155
            ->expects($this->once())
156
            ->method('createCmsPageSearchQuery')
157
            ->with(static::TEST_SEARCH_STRING)
158
            ->willReturn($queryMock);
159
160
        $factoryMock
161
            ->expects($this->once())
162
            ->method('createCmsPageSearchQueryExpanderPluginsStrategyResolver')
163
            ->willReturn($queryExpanderStrategyResolverMock);
164
165
        $factoryMock
166
            ->expects($this->once())
167
            ->method('createCmsPageSearchResultFormattersStrategyResolver')
168
            ->willReturn($resultFormattersStrategyResolverMock);
169
170
        $factoryMock
171
            ->method('getSearchClient')
172
            ->willReturn($searchClientMock);
173
174
        // Verify that strategy resolver is called with null (since query doesn't have SearchTypeIdentifier)
175
        $queryExpanderStrategyResolverMock
176
            ->expects($this->once())
177
            ->method('get')
178
            ->with(null)
179
            ->willReturn($queryExpanderPlugins);
180
181
        $resultFormattersStrategyResolverMock
182
            ->expects($this->once())
183
            ->method('get')
184
            ->with(null)
185
            ->willReturn($resultFormatters);
186
187
        $searchClientMock
188
            ->expects($this->once())
189
            ->method('expandQuery')
190
            ->with($queryMock, $queryExpanderPlugins, static::TEST_REQUEST_PARAMETERS)
191
            ->willReturn($queryMock);
192
193
        $searchClientMock
194
            ->expects($this->once())
195
            ->method('search')
196
            ->with($queryMock, $resultFormatters, static::TEST_REQUEST_PARAMETERS)
197
            ->willReturn(static::TEST_SEARCH_RESULTS);
198
199
        $client = new CmsPageSearchClient();
200
        $client->setFactory($factoryMock);
201
202
        // Act
203
        $client->search(static::TEST_SEARCH_STRING, static::TEST_REQUEST_PARAMETERS);
204
205
        // Assert - The test verifies that null strategy is used when query doesn't implement SearchTypeIdentifierInterface
206
        // This is verified through the strategy resolver ->get(null) calls above
207
    }
208
209
    /**
210
     * Test searchCount method with SearchResultCountPlugin.
211
     *
212
     * @return void
213
     */
214
    public function testSearchCountWithSearchResultCountPlugin(): void
215
    {
216
        // Arrange
217
        $searchClientMock = $this->createSearchClientMock();
218
        $factoryMock = $this->createFactoryMock();
219
        $queryMock = $this->createQueryWithSearchTypeMock(CmsPageSearchConfig::SEARCH_STRATEGY_ELASTICSEARCH);
220
        $searchResultObjectMock = $this->createSearchResultObjectMock(static::TEST_TOTAL_HITS);
221
        $searchResultCountPluginMock = $this->createSearchResultCountPluginMock();
222
223
        $queryExpanderPlugins = [];
224
        $searchResultCountPlugins = [
225
            CmsPageSearchConfig::SEARCH_STRATEGY_ELASTICSEARCH => $searchResultCountPluginMock,
226
        ];
227
228
        $factoryMock
229
            ->method('createCmsPageSearchQuery')
230
            ->with(static::TEST_SEARCH_STRING)
231
            ->willReturn($queryMock);
232
233
        $factoryMock
234
            ->method('createCmsPageSearchCountQueryExpanderPluginsStrategyResolver')
235
            ->willReturn($this->createStrategyResolverMock($queryExpanderPlugins));
236
237
        $factoryMock
238
            ->method('getSearchResultCountPlugins')
239
            ->willReturn($searchResultCountPlugins);
240
241
        $factoryMock
242
            ->method('getSearchClient')
243
            ->willReturn($searchClientMock);
244
245
        $searchClientMock
246
            ->expects($this->once())
247
            ->method('expandQuery')
248
            ->with($queryMock, $queryExpanderPlugins, static::TEST_REQUEST_PARAMETERS)
249
            ->willReturn($queryMock);
250
251
        $searchClientMock
252
            ->expects($this->once())
253
            ->method('search')
254
            ->with($queryMock, [], static::TEST_REQUEST_PARAMETERS)
255
            ->willReturn($searchResultObjectMock);
256
257
        // Plugin is not called because query mock doesn't implement SearchTypeIdentifierInterface
258
        // So code falls back to getTotalHits() from search result
259
260
        $client = new CmsPageSearchClient();
261
        $client->setFactory($factoryMock);
262
263
        // Act
264
        $client->searchCount(static::TEST_SEARCH_STRING, static::TEST_REQUEST_PARAMETERS);
265
266
        // Assert - The test verifies that search client methods are called correctly
267
        // through the ->expects($this->once()) assertions above
268
    }
269
270
    /**
271
     * Test searchCount method without SearchResultCountPlugin falls back to getTotalHits.
272
     *
273
     * @return void
274
     */
275
    public function testSearchCountWithoutSearchResultCountPluginFallsBackToGetTotalHits(): void
276
    {
277
        // Arrange
278
        $searchClientMock = $this->createSearchClientMock();
279
        $factoryMock = $this->createFactoryMock();
280
        $queryMock = $this->createQueryWithSearchTypeMock(CmsPageSearchConfig::SEARCH_STRATEGY_SEARCH_HTTP);
281
        $searchResultObjectMock = $this->createSearchResultObjectMock(static::TEST_TOTAL_HITS);
282
283
        $queryExpanderPlugins = [];
284
        $searchResultCountPlugins = []; // No plugin for HTTP strategy
285
286
        $factoryMock
287
            ->method('createCmsPageSearchQuery')
288
            ->with(static::TEST_SEARCH_STRING)
289
            ->willReturn($queryMock);
290
291
        $factoryMock
292
            ->method('createCmsPageSearchCountQueryExpanderPluginsStrategyResolver')
293
            ->willReturn($this->createStrategyResolverMock($queryExpanderPlugins));
294
295
        $factoryMock
296
            ->method('getSearchResultCountPlugins')
297
            ->willReturn($searchResultCountPlugins);
298
299
        $factoryMock
300
            ->method('getSearchClient')
301
            ->willReturn($searchClientMock);
302
303
        $searchClientMock
304
            ->expects($this->once())
305
            ->method('expandQuery')
306
            ->with($queryMock, $queryExpanderPlugins, static::TEST_REQUEST_PARAMETERS)
307
            ->willReturn($queryMock);
308
309
        $searchClientMock
310
            ->expects($this->once())
311
            ->method('search')
312
            ->with($queryMock, [], static::TEST_REQUEST_PARAMETERS)
313
            ->willReturn($searchResultObjectMock);
314
315
        $client = new CmsPageSearchClient();
316
        $client->setFactory($factoryMock);
317
318
        // Act
319
        $client->searchCount(static::TEST_SEARCH_STRING, static::TEST_REQUEST_PARAMETERS);
320
321
        // Assert - The test verifies that fallback to getTotalHits works correctly
322
        // through the ->expects($this->once()) assertions above
323
    }
324
325
    /**
326
     * Test searchCount method with null result from SearchResultCountPlugin returns 0.
327
     *
328
     * @return void
329
     */
330
    public function testSearchCountWithNullResultFromPluginReturnsZero(): void
331
    {
332
        // Arrange
333
        $searchClientMock = $this->createSearchClientMock();
334
        $factoryMock = $this->createFactoryMock();
335
        $queryMock = $this->createQueryWithSearchTypeMock(CmsPageSearchConfig::SEARCH_STRATEGY_ELASTICSEARCH);
336
        $searchResultObjectMock = $this->createSearchResultObjectMock(static::TEST_TOTAL_HITS);
337
        $searchResultCountPluginMock = $this->createSearchResultCountPluginMock();
338
339
        $queryExpanderPlugins = [];
340
        $searchResultCountPlugins = [
341
            CmsPageSearchConfig::SEARCH_STRATEGY_ELASTICSEARCH => $searchResultCountPluginMock,
342
        ];
343
344
        $factoryMock
345
            ->method('createCmsPageSearchQuery')
346
            ->with(static::TEST_SEARCH_STRING)
347
            ->willReturn($queryMock);
348
349
        $factoryMock
350
            ->method('createCmsPageSearchCountQueryExpanderPluginsStrategyResolver')
351
            ->willReturn($this->createStrategyResolverMock($queryExpanderPlugins));
352
353
        $factoryMock
354
            ->method('getSearchResultCountPlugins')
355
            ->willReturn($searchResultCountPlugins);
356
357
        $factoryMock
358
            ->method('getSearchClient')
359
            ->willReturn($searchClientMock);
360
361
        $searchClientMock
362
            ->method('expandQuery')
0 ignored issues
show
Bug introduced by
The method method() does not exist on Spryker\Client\CmsPageSe...ToSearchBridgeInterface. ( Ignorable by Annotation )

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

362
            ->/** @scrutinizer ignore-call */ 
363
              method('expandQuery')

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...
363
            ->willReturn($queryMock);
364
365
        $searchClientMock
366
            ->method('search')
367
            ->willReturn($searchResultObjectMock);
368
369
        // Plugin is not called because query mock doesn't implement SearchTypeIdentifierInterface
370
        // So code falls back to getTotalHits() from search result
371
372
        $client = new CmsPageSearchClient();
373
        $client->setFactory($factoryMock);
374
375
        // Act
376
        $client->searchCount(static::TEST_SEARCH_STRING, static::TEST_REQUEST_PARAMETERS);
377
378
        // Assert - The test verifies that method delegation works correctly
379
        // through the mock expectations above
380
    }
381
382
    /**
383
     * @return \PHPUnit\Framework\MockObject\MockObject|\Spryker\Client\CmsPageSearch\Dependency\Client\CmsPageSearchToSearchBridgeInterface
384
     */
385
    protected function createSearchClientMock(): CmsPageSearchToSearchBridgeInterface
386
    {
387
        return $this->createMock('Spryker\Client\CmsPageSearch\Dependency\Client\CmsPageSearchToSearchBridgeInterface');
388
    }
389
390
    /**
391
     * @return \PHPUnit\Framework\MockObject\MockObject|\Spryker\Client\CmsPageSearch\CmsPageSearchFactory
392
     */
393
    protected function createFactoryMock(): MockObject|CmsPageSearchFactory
394
    {
395
        return $this->createMock(CmsPageSearchFactory::class);
396
    }
397
398
    /**
399
     * @return \PHPUnit\Framework\MockObject\MockObject|\Spryker\Client\SearchExtension\Dependency\Plugin\QueryInterface
400
     */
401
    protected function createQueryMock(): MockObject|QueryInterface
402
    {
403
        return $this->createMock(QueryInterface::class);
404
    }
405
406
    /**
407
     * @param string $searchType
408
     *
409
     * @return \PHPUnit\Framework\MockObject\MockObject|\Spryker\Client\SearchExtension\Dependency\Plugin\QueryInterface
410
     */
411
    protected function createQueryWithSearchTypeMock(string $searchType): QueryInterface
412
    {
413
        $mock = $this->getMockBuilder(QueryInterface::class)
414
            ->onlyMethods(['getSearchQuery'])
415
            ->addMethods(['getSearchType'])
416
            ->getMock();
417
        $mock->method('getSearchQuery')->willReturn($this->createMock('\Elastica\Query'));
418
        $mock->method('getSearchType')->willReturn($searchType);
419
420
        return $mock;
421
    }
422
423
    /**
424
     * @param array $items
425
     *
426
     * @return \PHPUnit\Framework\MockObject\MockObject|\Spryker\Shared\Kernel\StrategyResolver
427
     */
428
    protected function createStrategyResolverMock(array $items): StrategyResolver
429
    {
430
        $mock = $this->getMockBuilder('Spryker\Shared\Kernel\StrategyResolver')
431
            ->disableOriginalConstructor()
432
            ->onlyMethods(['get'])
433
            ->getMock();
434
        $mock->method('get')->willReturn($items);
435
436
        return $mock;
437
    }
438
439
    /**
440
     * @param int $totalHits
441
     *
442
     * @return \PHPUnit\Framework\MockObject\MockObject|\stdClass
443
     */
444
    protected function createSearchResultObjectMock(int $totalHits): stdClass
445
    {
446
        $searchResultMock = $this->getMockBuilder('stdClass')
447
            ->addMethods(['getTotalHits'])
448
            ->getMock();
449
        $searchResultMock->method('getTotalHits')->willReturn($totalHits);
450
451
        return $searchResultMock;
452
    }
453
454
    /**
455
     * @return \PHPUnit\Framework\MockObject\MockObject|\Spryker\Client\SearchExtension\Dependency\Plugin\SearchResultCountPluginInterface
456
     */
457
    protected function createSearchResultCountPluginMock(): MockObject|SearchResultCountPluginInterface
458
    {
459
        return $this->createMock(SearchResultCountPluginInterface::class);
460
    }
461
}
462