1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* FullTextSearch - Full text search framework for Nextcloud |
4
|
|
|
* |
5
|
|
|
* This file is licensed under the Affero General Public License version 3 or |
6
|
|
|
* later. See the COPYING file. |
7
|
|
|
* |
8
|
|
|
* @author Maxence Lange <[email protected]> |
9
|
|
|
* @copyright 2018 |
10
|
|
|
* @license GNU AGPL version 3 or any later version |
11
|
|
|
* |
12
|
|
|
* This program is free software: you can redistribute it and/or modify |
13
|
|
|
* it under the terms of the GNU Affero General Public License as |
14
|
|
|
* published by the Free Software Foundation, either version 3 of the |
15
|
|
|
* License, or (at your option) any later version. |
16
|
|
|
* |
17
|
|
|
* This program is distributed in the hope that it will be useful, |
18
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
19
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20
|
|
|
* GNU Affero General Public License for more details. |
21
|
|
|
* |
22
|
|
|
* You should have received a copy of the GNU Affero General Public License |
23
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
24
|
|
|
* |
25
|
|
|
*/ |
26
|
|
|
|
27
|
|
|
namespace OCA\FullTextSearch\Command; |
28
|
|
|
|
29
|
|
|
use Exception; |
30
|
|
|
use OCA\FullTextSearch\Exceptions\InterruptException; |
31
|
|
|
use OCA\FullTextSearch\Exceptions\ProviderDoesNotExistException; |
32
|
|
|
use OCA\FullTextSearch\Exceptions\ProviderIsNotCompatibleException; |
33
|
|
|
use OCA\FullTextSearch\Exceptions\ProviderIsNotUniqueException; |
34
|
|
|
use OCA\FullTextSearch\Exceptions\RunnerAlreadyUpException; |
35
|
|
|
use OCA\FullTextSearch\Exceptions\TickDoesNotExistException; |
36
|
|
|
use OCA\FullTextSearch\IFullTextSearchPlatform; |
37
|
|
|
use OCA\FullTextSearch\IFullTextSearchProvider; |
38
|
|
|
use OCA\FullTextSearch\Model\DocumentAccess; |
39
|
|
|
use OCA\FullTextSearch\Model\ExtendedBase; |
40
|
|
|
use OCA\FullTextSearch\Model\IndexOptions; |
41
|
|
|
use OCA\FullTextSearch\Model\Runner; |
42
|
|
|
use OCA\FullTextSearch\Model\SearchRequest; |
43
|
|
|
use OCA\FullTextSearch\Model\SearchResult; |
44
|
|
|
use OCA\FullTextSearch\Provider\TestProvider; |
45
|
|
|
use OCA\FullTextSearch\Service\IndexService; |
46
|
|
|
use OCA\FullTextSearch\Service\MiscService; |
47
|
|
|
use OCA\FullTextSearch\Service\PlatformService; |
48
|
|
|
use OCA\FullTextSearch\Service\ProviderService; |
49
|
|
|
use OCA\FullTextSearch\Service\RunningService; |
50
|
|
|
use OCA\FullTextSearch\Service\TestService; |
51
|
|
|
use OCP\AppFramework\QueryException; |
52
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
53
|
|
|
use Symfony\Component\Console\Input\InputOption; |
54
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
55
|
|
|
|
56
|
|
|
|
57
|
|
|
class Test extends ExtendedBase { |
58
|
|
|
|
59
|
|
|
const DELAY_STABILIZE_PLATFORM = 3; |
60
|
|
|
|
61
|
|
|
/** @var RunningService */ |
62
|
|
|
private $runningService; |
63
|
|
|
|
64
|
|
|
/** @var PlatformService */ |
65
|
|
|
private $platformService; |
66
|
|
|
|
67
|
|
|
/** @var ProviderService */ |
68
|
|
|
private $providerService; |
69
|
|
|
|
70
|
|
|
/** @var IndexService */ |
71
|
|
|
private $indexService; |
72
|
|
|
|
73
|
|
|
/** @var TestService */ |
74
|
|
|
private $testService; |
75
|
|
|
|
76
|
|
|
/** @var MiscService */ |
77
|
|
|
private $miscService; |
78
|
|
|
|
79
|
|
|
|
80
|
|
|
/** @var Runner */ |
81
|
|
|
private $runner; |
82
|
|
|
|
83
|
|
|
|
84
|
|
|
/** @var boolean */ |
85
|
|
|
private $isJson = false; |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* Index constructor. |
89
|
|
|
* |
90
|
|
|
* @param RunningService $runningService |
91
|
|
|
* @param ProviderService $providerService |
92
|
|
|
* @param IndexService $indexService |
93
|
|
|
* @param PlatformService $platformService |
94
|
|
|
* @param TestService $testService |
95
|
|
|
* @param MiscService $miscService |
96
|
|
|
*/ |
97
|
|
View Code Duplication |
public function __construct( |
|
|
|
|
98
|
|
|
RunningService $runningService, PlatformService $platformService, |
99
|
|
|
ProviderService $providerService, IndexService $indexService, TestService $testService, |
100
|
|
|
MiscService $miscService |
101
|
|
|
) { |
102
|
|
|
parent::__construct(); |
103
|
|
|
|
104
|
|
|
$this->runningService = $runningService; |
105
|
|
|
$this->platformService = $platformService; |
106
|
|
|
$this->providerService = $providerService; |
107
|
|
|
$this->indexService = $indexService; |
108
|
|
|
$this->testService = $testService; |
109
|
|
|
$this->miscService = $miscService; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* |
115
|
|
|
*/ |
116
|
|
|
protected function configure() { |
117
|
|
|
parent::configure(); |
118
|
|
|
$this->setName('fulltextsearch:test') |
119
|
|
|
->setDescription('Testing the platform setup') |
120
|
|
|
->addOption('json', 'j', InputOption::VALUE_NONE, 'return result as JSON') |
121
|
|
|
->addOption( |
122
|
|
|
'platform_delay', 'd', InputOption::VALUE_REQUIRED, |
123
|
|
|
'change DELAY_STABILIZE_PLATFORM' |
124
|
|
|
); |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* @param InputInterface $input |
130
|
|
|
* @param OutputInterface $output |
131
|
|
|
* |
132
|
|
|
* @return int|null|void |
133
|
|
|
* @throws Exception |
134
|
|
|
*/ |
135
|
|
|
protected function execute(InputInterface $input, OutputInterface $output) { |
136
|
|
|
$this->isJson = ($input->getOption('json') === true); |
137
|
|
|
$platformDelay = ($input->getOption('platform_delay') > 0) ? $input->getOption( |
138
|
|
|
'platform_delay' |
139
|
|
|
) : self::DELAY_STABILIZE_PLATFORM; |
140
|
|
|
|
141
|
|
|
$this->output($output, '.Testing your current setup:'); |
142
|
|
|
|
143
|
|
|
try { |
144
|
|
|
$testProvider = $this->testCreatingProvider($output); |
145
|
|
|
$this->testMockedProvider($output, $testProvider); |
146
|
|
|
$testPlatform = $this->testLoadingPlatform($output); |
147
|
|
|
$this->testLockingProcess($output, $testPlatform, $testProvider); |
148
|
|
|
} catch (Exception $e) { |
149
|
|
|
$this->output($output, false); |
150
|
|
|
throw $e; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
try { |
154
|
|
|
$this->testResetTest($output, $testProvider); |
155
|
|
|
$this->pause($output, $platformDelay); |
156
|
|
|
$this->testInitIndexing($output, $testPlatform); |
157
|
|
|
$this->testIndexingDocuments($output, $testPlatform, $testProvider); |
158
|
|
|
$this->pause($output, $platformDelay); |
159
|
|
|
$this->testContentLicense($output, $testPlatform); |
160
|
|
|
$this->testSearchSimple($output, $testPlatform, $testProvider); |
161
|
|
|
|
162
|
|
|
$this->testUpdatingDocumentsAccess($output, $testPlatform, $testProvider); |
163
|
|
|
$this->pause($output, $platformDelay); |
164
|
|
|
$this->testSearchAccess($output, $testPlatform, $testProvider); |
165
|
|
|
$this->testSearchShare($output, $testPlatform, $testProvider); |
166
|
|
|
|
167
|
|
|
$this->testResetTest($output, $testProvider); |
168
|
|
|
$this->testUnlockingProcess($output); |
169
|
|
|
} catch (Exception $e) { |
170
|
|
|
$this->output($output, false); |
171
|
|
|
$this->output($output, 'Error detected, unlocking process'); |
172
|
|
|
$this->runner->stop(); |
173
|
|
|
$this->output($output, true); |
174
|
|
|
|
175
|
|
|
throw $e; |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
$this->output($output, '', true); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
|
182
|
|
|
/** |
183
|
|
|
* @return IFullTextSearchProvider |
184
|
|
|
* @throws ProviderIsNotCompatibleException |
185
|
|
|
* @throws QueryException |
186
|
|
|
* @throws ProviderDoesNotExistException |
187
|
|
|
* @throws ProviderIsNotUniqueException |
188
|
|
|
*/ |
189
|
|
|
private function generateMockProvider() { |
190
|
|
|
$this->providerService->loadProvider('OCA\FullTextSearch\Provider\TestProvider'); |
191
|
|
|
|
192
|
|
|
return $this->providerService->getProvider(TestProvider::TEST_PROVIDER_ID); |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* @param OutputInterface $output |
198
|
|
|
* @param string|bool $line |
199
|
|
|
* @param bool $isNewLine |
200
|
|
|
*/ |
201
|
|
|
private function output(OutputInterface $output, $line, $isNewLine = true) { |
202
|
|
|
$line = $this->convertBoolToLine($line, $isNewLine); |
203
|
|
|
if ($isNewLine) { |
204
|
|
|
$output->write(' ', true); |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
$output->write($line . ' ', false); |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
|
211
|
|
|
/** |
212
|
|
|
* @param string|bool $line |
213
|
|
|
* @param $isNewLine |
214
|
|
|
* |
215
|
|
|
* @return string |
216
|
|
|
*/ |
217
|
|
|
private function convertBoolToLine($line, &$isNewLine) { |
218
|
|
|
if (!is_bool($line)) { |
219
|
|
|
return $line; |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
$isNewLine = false; |
223
|
|
|
if ($line === false) { |
224
|
|
|
return '<error>fail</error>'; |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
return '<info>ok</info>'; |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
|
231
|
|
|
/** |
232
|
|
|
* @param $output |
233
|
|
|
* |
234
|
|
|
* @return IFullTextSearchProvider |
235
|
|
|
* @throws ProviderDoesNotExistException |
236
|
|
|
* @throws ProviderIsNotCompatibleException |
237
|
|
|
* @throws ProviderIsNotUniqueException |
238
|
|
|
* @throws QueryException |
239
|
|
|
*/ |
240
|
|
|
private function testCreatingProvider($output) { |
241
|
|
|
$this->output($output, 'Creating mocked content provider.'); |
242
|
|
|
$testProvider = $this->generateMockProvider(); |
243
|
|
|
$this->output($output, true); |
244
|
|
|
|
245
|
|
|
return $testProvider; |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
|
249
|
|
|
/** |
250
|
|
|
* @param $output |
251
|
|
|
* @param IFullTextSearchProvider $testProvider |
252
|
|
|
*/ |
253
|
|
|
private function testMockedProvider($output, IFullTextSearchProvider $testProvider) { |
254
|
|
|
$this->output($output, 'Testing mocked provider: get indexable documents.'); |
255
|
|
|
$indexableDocuments = |
256
|
|
|
$testProvider->generateIndexableDocuments(TestService::DOCUMENT_USER1); |
257
|
|
|
$this->output($output, '(' . sizeof($indexableDocuments) . ' items)', false); |
258
|
|
|
$this->output($output, true); |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
|
262
|
|
|
/** |
263
|
|
|
* @param $output |
264
|
|
|
* |
265
|
|
|
* @return IFullTextSearchPlatform |
266
|
|
|
* @throws Exception |
267
|
|
|
*/ |
268
|
|
|
private function testLoadingPlatform($output) { |
269
|
|
|
$this->output($output, 'Loading search platform.'); |
270
|
|
|
$testPlatform = $this->platformService->getPlatform(); |
271
|
|
|
$this->output($output, '(' . $testPlatform->getName() . ')', false); |
272
|
|
|
$this->output($output, true); |
273
|
|
|
|
274
|
|
|
$this->output($output, 'Testing search platform.'); |
275
|
|
|
if (!$testPlatform->testPlatform()) { |
276
|
|
|
throw new Exception ('Search platform (' . $testPlatform->getName() . ') down ?'); |
277
|
|
|
} |
278
|
|
|
$this->output($output, true); |
279
|
|
|
|
280
|
|
|
return $testPlatform; |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
/** |
284
|
|
|
* @param OutputInterface $output |
285
|
|
|
* @param IFullTextSearchPlatform $testPlatform |
286
|
|
|
* @param IFullTextSearchProvider $testProvider |
287
|
|
|
* |
288
|
|
|
* @throws RunnerAlreadyUpException |
289
|
|
|
*/ |
290
|
|
|
private function testLockingProcess( |
291
|
|
|
OutputInterface $output, IFullTextSearchPlatform $testPlatform, |
292
|
|
|
IFullTextSearchProvider $testProvider |
293
|
|
|
) { |
294
|
|
|
$this->output($output, 'Locking process'); |
295
|
|
|
$this->runner = new Runner($this->runningService, 'test'); |
296
|
|
|
$this->runner->start(true); |
297
|
|
|
$this->indexService->setRunner($this->runner); |
298
|
|
|
$testPlatform->setRunner($this->runner); |
299
|
|
|
$testProvider->setRunner($this->runner); |
300
|
|
|
$this->output($output, true); |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
|
304
|
|
|
/** |
305
|
|
|
* @param OutputInterface $output |
306
|
|
|
* @param IFullTextSearchProvider $testProvider |
307
|
|
|
* |
308
|
|
|
* @throws Exception |
309
|
|
|
*/ |
310
|
|
|
private function testResetTest(OutputInterface $output, IFullTextSearchProvider $testProvider |
311
|
|
|
) { |
312
|
|
|
$this->output($output, 'Removing test.'); |
313
|
|
|
$this->indexService->resetIndex($testProvider->getId()); |
314
|
|
|
$this->output($output, true); |
315
|
|
|
} |
316
|
|
|
|
317
|
|
|
|
318
|
|
|
/** |
319
|
|
|
* @param OutputInterface $output |
320
|
|
|
* @param IFullTextSearchPlatform $testPlatform |
321
|
|
|
*/ |
322
|
|
|
private function testInitIndexing(OutputInterface $output, IFullTextSearchPlatform $testPlatform |
323
|
|
|
) { |
324
|
|
|
$this->output($output, 'Initializing index mapping.'); |
325
|
|
|
$testPlatform->initializeIndex(); |
326
|
|
|
$this->output($output, true); |
327
|
|
|
} |
328
|
|
|
|
329
|
|
|
|
330
|
|
|
/** |
331
|
|
|
* @param OutputInterface $output |
332
|
|
|
* @param IFullTextSearchPlatform $testPlatform |
333
|
|
|
* @param IFullTextSearchProvider $testProvider |
334
|
|
|
* |
335
|
|
|
* @throws InterruptException |
336
|
|
|
* @throws TickDoesNotExistException |
337
|
|
|
*/ |
338
|
|
|
private function testIndexingDocuments( |
339
|
|
|
OutputInterface $output, IFullTextSearchPlatform $testPlatform, |
340
|
|
|
IFullTextSearchProvider $testProvider |
341
|
|
|
) { |
342
|
|
|
$this->output($output, 'Indexing generated documents.'); |
343
|
|
|
$options = new IndexOptions( |
344
|
|
|
[ |
345
|
|
|
'provider' => TestProvider::TEST_PROVIDER_ID |
346
|
|
|
] |
347
|
|
|
); |
348
|
|
|
$this->indexService->indexProviderContentFromUser( |
349
|
|
|
$testPlatform, $testProvider, TestService::DOCUMENT_USER1, $options |
350
|
|
|
); |
351
|
|
|
$this->output($output, true); |
352
|
|
|
} |
353
|
|
|
|
354
|
|
|
|
355
|
|
|
/** |
356
|
|
|
* @param OutputInterface $output |
357
|
|
|
* @param IFullTextSearchPlatform $testPlatform |
358
|
|
|
* |
359
|
|
|
* @throws Exception |
360
|
|
|
*/ |
361
|
|
|
private function testContentLicense( |
362
|
|
|
OutputInterface $output, IFullTextSearchPlatform $testPlatform |
363
|
|
|
) { |
364
|
|
|
|
365
|
|
|
try { |
366
|
|
|
$this->output($output, 'Retreiving content from a big index (license).'); |
367
|
|
|
$indexDocument = $testPlatform->getDocument( |
|
|
|
|
368
|
|
|
TestProvider::TEST_PROVIDER_ID, TestService::DOCUMENT_TYPE_LICENSE |
369
|
|
|
); |
370
|
|
|
|
371
|
|
|
$this->output( |
372
|
|
|
$output, '(size: ' . $indexDocument->getContentSize() . ')', false |
373
|
|
|
); |
374
|
|
|
$this->output($output, true); |
375
|
|
|
} catch (Exception $e) { |
376
|
|
|
throw new Exception( |
377
|
|
|
"Issue while getting test document '" . TestService::DOCUMENT_TYPE_LICENSE |
378
|
|
|
. "' from search platform: " . $e->getMessage() |
379
|
|
|
); |
380
|
|
|
} |
381
|
|
|
|
382
|
|
|
$this->output($output, 'Comparing document with source.'); |
383
|
|
|
$this->testService->compareIndexDocument( |
384
|
|
|
$this->testService->generateIndexDocumentContentLicense(), $indexDocument |
385
|
|
|
); |
386
|
|
|
$this->output($output, true); |
387
|
|
|
} |
388
|
|
|
|
389
|
|
|
|
390
|
|
|
/** |
391
|
|
|
* @param OutputInterface $output |
392
|
|
|
* @param IFullTextSearchPlatform $testPlatform |
393
|
|
|
* |
394
|
|
|
* @param IFullTextSearchProvider $testProvider |
395
|
|
|
* |
396
|
|
|
* @throws Exception |
397
|
|
|
*/ |
398
|
|
|
private function testSearchSimple( |
399
|
|
|
OutputInterface $output, IFullTextSearchPlatform $testPlatform, |
400
|
|
|
IFullTextSearchProvider $testProvider |
401
|
|
|
) { |
402
|
|
|
|
403
|
|
|
$this->output($output, 'Searching basic keywords:'); |
404
|
|
|
|
405
|
|
|
$access = new DocumentAccess(); |
406
|
|
|
$access->setViewerId(TestService::DOCUMENT_USER1); |
407
|
|
|
|
408
|
|
|
$this->search( |
409
|
|
|
$output, $testPlatform, $testProvider, $access, 'test', |
410
|
|
|
[TestService::DOCUMENT_TYPE_SIMPLE] |
411
|
|
|
); |
412
|
|
|
$this->search( |
413
|
|
|
$output, $testPlatform, $testProvider, $access, 'document is a simple test', |
414
|
|
|
// [TestService::DOCUMENT_TYPE_SIMPLE] |
|
|
|
|
415
|
|
|
[TestService::DOCUMENT_TYPE_SIMPLE, TestService::DOCUMENT_TYPE_LICENSE] |
416
|
|
|
); |
417
|
|
|
$this->search( |
418
|
|
|
$output, $testPlatform, $testProvider, $access, '"document is a test"', |
419
|
|
|
[] |
420
|
|
|
); |
421
|
|
|
$this->search( |
422
|
|
|
$output, $testPlatform, $testProvider, $access, '"document is a simple test"', |
423
|
|
|
[TestService::DOCUMENT_TYPE_SIMPLE] |
424
|
|
|
); |
425
|
|
|
$this->search( |
426
|
|
|
$output, $testPlatform, $testProvider, $access, 'document is a simple -test', |
427
|
|
|
[TestService::DOCUMENT_TYPE_LICENSE] |
428
|
|
|
); |
429
|
|
|
$this->search( |
430
|
|
|
$output, $testPlatform, $testProvider, $access, 'document is a simple +test', |
431
|
|
|
[TestService::DOCUMENT_TYPE_SIMPLE] |
432
|
|
|
); |
433
|
|
|
$this->search( |
434
|
|
|
$output, $testPlatform, $testProvider, $access, '-document is a simple test', |
435
|
|
|
[] |
436
|
|
|
); |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
|
440
|
|
|
/** |
441
|
|
|
* @param OutputInterface $output |
442
|
|
|
* @param IFullTextSearchPlatform $testPlatform |
443
|
|
|
* @param IFullTextSearchProvider $testProvider |
444
|
|
|
* |
445
|
|
|
* @throws InterruptException |
446
|
|
|
* @throws TickDoesNotExistException |
447
|
|
|
*/ |
448
|
|
|
private function testUpdatingDocumentsAccess( |
449
|
|
|
OutputInterface $output, IFullTextSearchPlatform $testPlatform, |
450
|
|
|
IFullTextSearchProvider $testProvider |
451
|
|
|
) { |
452
|
|
|
$this->output($output, 'Updating documents access.'); |
453
|
|
|
$options = new IndexOptions( |
454
|
|
|
[ |
455
|
|
|
'provider' => TestProvider::TEST_PROVIDER_ID, |
456
|
|
|
TestService::DOCUMENT_INDEXING_OPTION => TestService::DOCUMENT_INDEXING_ACCESS |
457
|
|
|
] |
458
|
|
|
); |
459
|
|
|
$testProvider->setIndexOptions($options); |
460
|
|
|
$this->indexService->indexProviderContentFromUser( |
461
|
|
|
$testPlatform, $testProvider, TestService::DOCUMENT_USER1, $options |
462
|
|
|
); |
463
|
|
|
$this->output($output, true); |
464
|
|
|
} |
465
|
|
|
|
466
|
|
|
|
467
|
|
|
/** |
468
|
|
|
* @param OutputInterface $output |
469
|
|
|
* @param IFullTextSearchPlatform $platform |
470
|
|
|
* |
471
|
|
|
* @param IFullTextSearchProvider $provider |
472
|
|
|
* |
473
|
|
|
* @throws Exception |
474
|
|
|
*/ |
475
|
|
|
private function testSearchAccess( |
476
|
|
|
OutputInterface $output, IFullTextSearchPlatform $platform, |
477
|
|
|
IFullTextSearchProvider $provider |
478
|
|
|
) { |
479
|
|
|
|
480
|
|
|
$this->output($output, 'Searching with group access rights:'); |
481
|
|
|
|
482
|
|
|
$this->searchGroups($output, $platform, $provider, [], []); |
483
|
|
|
$this->searchGroups( |
484
|
|
|
$output, $platform, $provider, [TestService::DOCUMENT_GROUP1], |
485
|
|
|
[TestService::DOCUMENT_TYPE_LICENSE] |
486
|
|
|
); |
487
|
|
|
$this->searchGroups( |
488
|
|
|
$output, $platform, $provider, |
489
|
|
|
[TestService::DOCUMENT_GROUP1, TestService::DOCUMENT_GROUP2], |
490
|
|
|
[TestService::DOCUMENT_TYPE_LICENSE] |
491
|
|
|
); |
492
|
|
|
$this->searchGroups( |
493
|
|
|
$output, $platform, $provider, |
494
|
|
|
[TestService::DOCUMENT_NOTGROUP, TestService::DOCUMENT_GROUP2], |
495
|
|
|
[TestService::DOCUMENT_TYPE_LICENSE] |
496
|
|
|
); |
497
|
|
|
$this->searchGroups($output, $platform, $provider, [TestService::DOCUMENT_NOTGROUP], []); |
498
|
|
|
} |
499
|
|
|
|
500
|
|
|
|
501
|
|
|
/** |
502
|
|
|
* @param OutputInterface $output |
503
|
|
|
* @param IFullTextSearchPlatform $platform |
504
|
|
|
* |
505
|
|
|
* @param IFullTextSearchProvider $provider |
506
|
|
|
* |
507
|
|
|
* @throws Exception |
508
|
|
|
*/ |
509
|
|
|
private function testSearchShare( |
510
|
|
|
OutputInterface $output, IFullTextSearchPlatform $platform, |
511
|
|
|
IFullTextSearchProvider $provider |
512
|
|
|
) { |
513
|
|
|
|
514
|
|
|
$this->output($output, 'Searching with share rights:'); |
515
|
|
|
|
516
|
|
|
$this->searchUsers($output, $platform, $provider, TestService::DOCUMENT_NOTUSER, []); |
517
|
|
|
$this->searchUsers($output, $platform, $provider, TestService::DOCUMENT_USER2, ['license']); |
518
|
|
|
$this->searchUsers($output, $platform, $provider, TestService::DOCUMENT_USER3, ['license']); |
519
|
|
|
} |
520
|
|
|
|
521
|
|
|
|
522
|
|
|
/** |
523
|
|
|
* @param OutputInterface $output |
524
|
|
|
* |
525
|
|
|
* @throws TickDoesNotExistException |
526
|
|
|
*/ |
527
|
|
|
private function testUnlockingProcess(OutputInterface $output) { |
528
|
|
|
$this->output($output, 'Unlocking process'); |
529
|
|
|
$this->runner->stop(); |
530
|
|
|
$this->output($output, true); |
531
|
|
|
} |
532
|
|
|
|
533
|
|
|
|
534
|
|
|
/** |
535
|
|
|
* @param OutputInterface $output |
536
|
|
|
* @param IFullTextSearchPlatform $testPlatform |
537
|
|
|
* @param IFullTextSearchProvider $testProvider |
538
|
|
|
* @param DocumentAccess $access |
539
|
|
|
* @param string $search |
540
|
|
|
* @param array $expected |
541
|
|
|
* @param string $moreOutput |
542
|
|
|
* |
543
|
|
|
* @throws Exception |
544
|
|
|
*/ |
545
|
|
|
private function search( |
546
|
|
|
OutputInterface $output, IFullTextSearchPlatform $testPlatform, |
547
|
|
|
IFullTextSearchProvider $testProvider, |
548
|
|
|
DocumentAccess $access, $search, $expected, $moreOutput = '' |
549
|
|
|
) { |
550
|
|
|
$this->output( |
551
|
|
|
$output, |
552
|
|
|
" - '" . $search . "'" . (($moreOutput === '') ? '' : ' - ' . $moreOutput . ' - ') |
553
|
|
|
); |
554
|
|
|
$request = new SearchRequest(); |
555
|
|
|
|
556
|
|
|
$request->setSearch($search); |
557
|
|
|
$searchResult = $testPlatform->searchDocuments($testProvider, $access, $request); |
558
|
|
|
$this->output( |
559
|
|
|
$output, |
560
|
|
|
'(result: ' . $searchResult->getCount() . ', expected: ' . json_encode($expected) . ')', |
561
|
|
|
false |
562
|
|
|
); |
563
|
|
|
$this->compareSearchResult($searchResult, $expected); |
564
|
|
|
$this->output($output, true); |
565
|
|
|
} |
566
|
|
|
|
567
|
|
|
|
568
|
|
|
/** |
569
|
|
|
* @param OutputInterface $output |
570
|
|
|
* @param IFullTextSearchPlatform $testPlatform |
571
|
|
|
* @param IFullTextSearchProvider $testProvider |
572
|
|
|
* @param array $groups |
573
|
|
|
* @param array $expected |
574
|
|
|
* |
575
|
|
|
* @throws Exception |
576
|
|
|
*/ |
577
|
|
View Code Duplication |
private function searchGroups( |
|
|
|
|
578
|
|
|
OutputInterface $output, IFullTextSearchPlatform $testPlatform, |
579
|
|
|
IFullTextSearchProvider $testProvider, $groups, $expected |
580
|
|
|
) { |
581
|
|
|
|
582
|
|
|
$access = new DocumentAccess(); |
583
|
|
|
$access->setViewerId(TestService::DOCUMENT_NOTUSER); |
584
|
|
|
$access->setGroups($groups); |
585
|
|
|
|
586
|
|
|
$this->search( |
587
|
|
|
$output, $testPlatform, $testProvider, $access, 'license', |
588
|
|
|
$expected, json_encode($groups) |
589
|
|
|
); |
590
|
|
|
} |
591
|
|
|
|
592
|
|
|
|
593
|
|
|
/** |
594
|
|
|
* @param OutputInterface $output |
595
|
|
|
* @param IFullTextSearchPlatform $testPlatform |
596
|
|
|
* @param IFullTextSearchProvider $testProvider |
597
|
|
|
* @param string $user |
598
|
|
|
* @param array $expected |
599
|
|
|
* |
600
|
|
|
* @throws Exception |
601
|
|
|
*/ |
602
|
|
View Code Duplication |
private function searchUsers( |
|
|
|
|
603
|
|
|
OutputInterface $output, IFullTextSearchPlatform $testPlatform, |
604
|
|
|
IFullTextSearchProvider $testProvider, $user, $expected |
605
|
|
|
) { |
606
|
|
|
$access = new DocumentAccess(); |
607
|
|
|
$access->setViewerId($user); |
608
|
|
|
$this->search( |
609
|
|
|
$output, $testPlatform, $testProvider, $access, 'license', |
610
|
|
|
$expected, $user |
611
|
|
|
); |
612
|
|
|
} |
613
|
|
|
|
614
|
|
|
|
615
|
|
|
/** |
616
|
|
|
* @param SearchResult $searchResult |
617
|
|
|
* @param $entries |
618
|
|
|
* |
619
|
|
|
* @throws Exception |
620
|
|
|
*/ |
621
|
|
|
private function compareSearchResult(SearchResult $searchResult, $entries) { |
622
|
|
|
$documents = $searchResult->getDocuments(); |
623
|
|
|
if (sizeof($documents) !== sizeof($entries)) { |
624
|
|
|
throw new \Exception('Unexpected SearchResult: ' . json_encode($searchResult)); |
625
|
|
|
} |
626
|
|
|
|
627
|
|
|
foreach ($documents as $document) { |
628
|
|
|
if (!in_array($document->getId(), $entries)) { |
629
|
|
|
throw new \Exception('Unexpected Document: ' . json_encode($document)); |
630
|
|
|
} |
631
|
|
|
} |
632
|
|
|
} |
633
|
|
|
|
634
|
|
|
|
635
|
|
|
/** |
636
|
|
|
* @param OutputInterface $output |
637
|
|
|
* @param int $s |
638
|
|
|
* |
639
|
|
|
* @throws InterruptException |
640
|
|
|
*/ |
641
|
|
|
private function pause(OutputInterface $output, $s) { |
642
|
|
|
$this->output($output, 'Pausing ' . $s . ' seconds'); |
643
|
|
|
|
644
|
|
|
for ($i = 1; $i <= $s; $i++) { |
645
|
|
|
if (time_nanosleep(1, 0) !== true) { |
646
|
|
|
throw new InterruptException('Interrupted by user'); |
647
|
|
|
} |
648
|
|
|
|
649
|
|
|
$this->output($output, $i, false); |
650
|
|
|
} |
651
|
|
|
|
652
|
|
|
$this->output($output, true); |
653
|
|
|
} |
654
|
|
|
|
655
|
|
|
} |
656
|
|
|
|
657
|
|
|
|
658
|
|
|
|
659
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.