Skip to content

Commit

Permalink
Add unit test and adjust code
Browse files Browse the repository at this point in the history
  • Loading branch information
jvillafanez committed Jun 21, 2023
1 parent fcbcd46 commit 1683039
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 16 deletions.
31 changes: 15 additions & 16 deletions lib/Command/FillSecondary.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\QuestionHelper;

/**
* Class Rebuild
Expand Down Expand Up @@ -108,7 +110,7 @@ protected function configure() {
'force',
'f',
InputOption::VALUE_NONE,
'Use this option to rebuild the search index without further questions.'
'Use this option to fill the secondary index without further questions.'
)
->addOption(
'startOver',
Expand All @@ -123,6 +125,8 @@ protected function configure() {
'The savepoint will be updated after processing this number of files.',
'100'
);

$this->setHelperSet(new HelperSet(['question' => new QuestionHelper()])); // it seems needed for unit tests
}

/**
Expand All @@ -148,17 +152,23 @@ public function execute(InputInterface $input, OutputInterface $output) {
'chunkSize' => $chunkSize,
];

$shouldAbort = true;
$this->searchElasticService->partialSetup();
foreach ($users as $user) {
$userObject = $this->userManager->get($user);
if ($userObject !== null) {
if ($this->shouldAbort($input, $output)) {
if ($shouldAbort && ($shouldAbort = $this->shouldAbort($input, $output))) {
// the $this->shouldAbort method should be executed only once.
// If it returns true, the command is aborted (returning -1).
// If it returns false, the $shouldAbort var will be false, so the
// next condition won't be evaluated the next time.
$output->writeln('Aborting.');
return -1;
}
$this->fillSecondary($connectorName, $userObject, $quiet, $output, $params);
} else {
$output->writeln("<error>Unknown user $user</error>");
return -1;
}
}
return 0;
Expand All @@ -172,22 +182,10 @@ public function execute(InputInterface $input, OutputInterface $output) {
* @return bool, returns true when the command has to be aborted, else false
*/
private function shouldAbort(InputInterface $input, OutputInterface $output) {
/**
* We are using static variable here because this method is private and
* the question should be asked once for the user, instead of asking for
* each user. So at any point we need to maintain a state to know if the
* question was asked or not.
*/
static $result = null;

if (isset($result)) {
return $result;
}

if (!$input->getOption('force')) {
$helper = $this->getHelper('question');
$question = new ChoiceQuestion(
"This will delete all search index data for selected users! Do you want to proceed?",
"This will re-index data for selected users based on already-indexed data! Do you want to proceed?",
['no', 'yes'],
'no'
);
Expand All @@ -213,7 +211,7 @@ private function shouldAbort(InputInterface $input, OutputInterface $output) {
protected function fillSecondary($connectorName, $user, $quiet, $output, $params) {
$uid = $user->getUID();
if (!$quiet) {
$output->writeln("Rebuilding Search Index for <info>$uid</info>");
$output->writeln("Filling secondary index for <info>$uid</info>");
}
$home = $this->rootFolder->getUserFolder($uid);

Expand All @@ -231,5 +229,6 @@ protected function fillSecondary($connectorName, $user, $quiet, $output, $params
};
$this->searchElasticService->fillSecondaryIndex($uid, $home, $connectorName, $fillParams);
$progressBar->finish();
$output->writeln('');
}
}
166 changes: 166 additions & 0 deletions tests/unit/Command/FillSecondaryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<?php
/**
* @copyright Copyright (c) 2023, ownCloud GmbH
* @license GPL-2.0
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/

namespace OCA\Search_Elastic\Tests\Unit\Command;

use OC\Files\Node\Folder;
use OCA\Search_Elastic\SearchElasticService;
use OCP\Files\IRootFolder;
use OCP\IUser;
use OCP\IUserManager;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Tester\CommandTester;
use OCA\Search_Elastic\Command\FillSecondary;
use Test\TestCase;

/**
* Class UpdateTest
*
* @package OCA\Search_Elastic\Tests\Unit\Command
*/
class FillSecondaryTest extends TestCase {
/** @var CommandTester */
private $commandTester;
/** @var SearchElasticService */
private $searchElasticService;
/** @var IUserManager */
private $userManager;
/** @var IRootFolder */
private $rootFolder;

protected function setUp(): void {
parent::setUp();

$this->searchElasticService = $this->createMock(SearchElasticService::class);
$this->userManager = $this->createMock(IUserManager::class);
$this->rootFolder = $this->createMock(IRootFolder::class);

$command = new FillSecondary($this->searchElasticService, $this->userManager, $this->rootFolder);
$this->commandTester = new CommandTester($command);
}

public function testNoUserId() {
$this->expectException(\RuntimeException::class);

$this->commandTester->execute([]);
}

public function testConnectorNoUser() {
$this->expectException(\RuntimeException::class);

$this->commandTester->execute(['connector_name' => 'con001']);
}

public function testMissingUser() {
$this->userManager->method('get')->willReturn(null);

$this->searchElasticService->expects($this->once())
->method('partialSetup');

$this->commandTester->execute([
'connector_name' => 'con001',
'user_id' => ['user001'],
]);
$this->assertSame(-1, $this->commandTester->getStatusCode());
}

public function testShouldAbort() {
$user = $this->createMock(IUser::class);
$user->method('getUID')->willReturn('user001');

$this->userManager->expects($this->once())
->method('get')
->with('user001')
->willReturn($user);

$this->searchElasticService->expects($this->once())
->method('partialSetup');

$this->commandTester->setInputs(['no']);
$this->commandTester->execute([
'connector_name' => 'con001',
'user_id' => ['user001'],
]);
$this->assertSame(-1, $this->commandTester->getStatusCode());
}

public function testShouldAbortMultipleUsers() {
$user1 = $this->createMock(IUser::class);
$user1->method('getUID')->willReturn('user001');
$user2 = $this->createMock(IUser::class);
$user2->method('getUID')->willReturn('user002');
$user3 = $this->createMock(IUser::class);
$user3->method('getUID')->willReturn('user003');

$this->userManager->expects($this->once())
->method('get')
->willReturnMap([
['user001', false, $user1],
['user002', false, $user2],
['user003', false, $user3],
]);

$this->searchElasticService->expects($this->once())
->method('partialSetup');

$this->commandTester->setInputs(['no']);
$this->commandTester->execute([
'connector_name' => 'con001',
'user_id' => ['user001'],
]);
$this->assertSame(-1, $this->commandTester->getStatusCode());
}

public function testExecute() {
$user = $this->createMock(IUser::class);
$user->method('getUID')->willReturn('user001');

$this->userManager->expects($this->once())
->method('get')
->with('user001')
->willReturn($user);

$this->searchElasticService->expects($this->once())
->method('partialSetup');

$folder = $this->createMock(Folder::class);
$this->rootFolder->expects($this->once())
->method('getUserFolder')
->with('user001')
->willReturn($folder);

$this->searchElasticService->expects($this->once())
->method('getCountFillSecondaryIndex')
->with('user001', $folder, 'con001', ['startOver' => false])
->willReturn(987);
$this->searchElasticService->expects($this->once())
->method('fillSecondaryIndex')
->with('user001', $folder, 'con001', $this->anything());

//$this->commandTester->setInputs(['yes']);
$this->commandTester->execute([
'connector_name' => 'con001',
'user_id' => ['user001'],
'--force' => true,
]);
$this->assertSame(0, $this->commandTester->getStatusCode());
}
}

0 comments on commit 1683039

Please sign in to comment.