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