aboutsummaryrefslogtreecommitdiffstats
path: root/tests/lib/Command
diff options
context:
space:
mode:
Diffstat (limited to 'tests/lib/Command')
-rw-r--r--tests/lib/Command/AsyncBusTestCase.php179
-rw-r--r--tests/lib/Command/BackgroundModeTest.php60
-rw-r--r--tests/lib/Command/CronBusTest.php40
-rw-r--r--tests/lib/Command/Integrity/SignAppTest.php272
-rw-r--r--tests/lib/Command/Integrity/SignCoreTest.php212
5 files changed, 763 insertions, 0 deletions
diff --git a/tests/lib/Command/AsyncBusTestCase.php b/tests/lib/Command/AsyncBusTestCase.php
new file mode 100644
index 00000000000..bb47de30b11
--- /dev/null
+++ b/tests/lib/Command/AsyncBusTestCase.php
@@ -0,0 +1,179 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace Test\Command;
+
+use OC\Command\FileAccess;
+use OCP\Command\IBus;
+use OCP\Command\ICommand;
+use Test\TestCase;
+
+class SimpleCommand implements ICommand {
+ public function handle() {
+ AsyncBusTestCase::$lastCommand = 'SimpleCommand';
+ }
+}
+
+class StateFullCommand implements ICommand {
+ public function __construct(
+ private $state,
+ ) {
+ }
+
+ public function handle() {
+ AsyncBusTestCase::$lastCommand = $this->state;
+ }
+}
+
+class FilesystemCommand implements ICommand {
+ use FileAccess;
+
+ public function handle() {
+ AsyncBusTestCase::$lastCommand = 'FileAccess';
+ }
+}
+
+function basicFunction() {
+ AsyncBusTestCase::$lastCommand = 'function';
+}
+
+// clean class to prevent phpunit putting closure in $this
+class ThisClosureTest {
+ private function privateMethod() {
+ AsyncBusTestCase::$lastCommand = 'closure-this';
+ }
+
+ public function test(IBus $bus) {
+ $bus->push(function (): void {
+ $this->privateMethod();
+ });
+ }
+}
+
+abstract class AsyncBusTestCase extends TestCase {
+ /**
+ * Basic way to check output from a command
+ *
+ * @var string
+ */
+ public static $lastCommand;
+
+ /**
+ * @var IBus
+ */
+ private $bus;
+
+ public static function DummyCommand() {
+ self::$lastCommand = 'static';
+ }
+
+ /**
+ * @return IBus
+ */
+ protected function getBus() {
+ if (!$this->bus instanceof IBus) {
+ $this->bus = $this->createBus();
+ }
+ return $this->bus;
+ }
+
+ /**
+ * @return IBus
+ */
+ abstract protected function createBus();
+
+ protected function setUp(): void {
+ self::$lastCommand = '';
+ }
+
+ public function testSimpleCommand(): void {
+ $command = new SimpleCommand();
+ $this->getBus()->push($command);
+ $this->runJobs();
+ $this->assertEquals('SimpleCommand', self::$lastCommand);
+ }
+
+ public function testStateFullCommand(): void {
+ $command = new StateFullCommand('foo');
+ $this->getBus()->push($command);
+ $this->runJobs();
+ $this->assertEquals('foo', self::$lastCommand);
+ }
+
+ public function testStaticCallable(): void {
+ $this->getBus()->push(['\Test\Command\AsyncBusTestCase', 'DummyCommand']);
+ $this->runJobs();
+ $this->assertEquals('static', self::$lastCommand);
+ }
+
+ public function testMemberCallable(): void {
+ $command = new StateFullCommand('bar');
+ $this->getBus()->push([$command, 'handle']);
+ $this->runJobs();
+ $this->assertEquals('bar', self::$lastCommand);
+ }
+
+ public function testFunctionCallable(): void {
+ $this->getBus()->push('\Test\Command\BasicFunction');
+ $this->runJobs();
+ $this->assertEquals('function', self::$lastCommand);
+ }
+
+ public function testClosure(): void {
+ $this->getBus()->push(function (): void {
+ AsyncBusTestCase::$lastCommand = 'closure';
+ });
+ $this->runJobs();
+ $this->assertEquals('closure', self::$lastCommand);
+ }
+
+ public function testClosureSelf(): void {
+ $this->getBus()->push(function (): void {
+ AsyncBusTestCase::$lastCommand = 'closure-self';
+ });
+ $this->runJobs();
+ $this->assertEquals('closure-self', self::$lastCommand);
+ }
+
+
+ public function testClosureThis(): void {
+ // clean class to prevent phpunit putting closure in $this
+ $test = new ThisClosureTest();
+ $test->test($this->getBus());
+ $this->runJobs();
+ $this->assertEquals('closure-this', self::$lastCommand);
+ }
+
+ public function testClosureBind(): void {
+ $state = 'bar';
+ $this->getBus()->push(function () use ($state): void {
+ AsyncBusTestCase::$lastCommand = 'closure-' . $state;
+ });
+ $this->runJobs();
+ $this->assertEquals('closure-bar', self::$lastCommand);
+ }
+
+ public function testFileFileAccessCommand(): void {
+ $this->getBus()->push(new FilesystemCommand());
+ $this->assertEquals('', self::$lastCommand);
+ $this->runJobs();
+ $this->assertEquals('FileAccess', self::$lastCommand);
+ }
+
+ public function testFileFileAccessCommandSync(): void {
+ $this->getBus()->requireSync('\OC\Command\FileAccess');
+ $this->getBus()->push(new FilesystemCommand());
+ $this->assertEquals('FileAccess', self::$lastCommand);
+ self::$lastCommand = '';
+ $this->runJobs();
+ $this->assertEquals('', self::$lastCommand);
+ }
+
+
+ abstract protected function runJobs();
+}
diff --git a/tests/lib/Command/BackgroundModeTest.php b/tests/lib/Command/BackgroundModeTest.php
new file mode 100644
index 00000000000..ab036ef87ee
--- /dev/null
+++ b/tests/lib/Command/BackgroundModeTest.php
@@ -0,0 +1,60 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016-2023 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2015 Christian Kampka <christian@kampka.net>
+ * SPDX-License-Identifier: MIT
+ */
+namespace Test\Command;
+
+use OC\Core\Command\Background\Mode;
+use OCP\IAppConfig;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Tester\CommandTester;
+use Test\TestCase;
+
+/**
+ * @group DB
+ */
+class BackgroundModeTest extends TestCase {
+ private IAppConfig $appConfig;
+
+ private Mode $command;
+
+ public function setUp(): void {
+ $this->appConfig = $this->createMock(IAppConfig::class);
+
+ $inputDefinition = new InputDefinition([
+ new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'),
+ ]);
+
+ $this->command = new Mode($this->appConfig);
+ $this->command->setDefinition($inputDefinition);
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataModeCommand')]
+ public function testModeCommand(string $mode): void {
+ $this->appConfig->expects($this->once())
+ ->method('setValueString')
+ ->with('core', 'backgroundjobs_mode', $mode);
+
+ $commandTester = new CommandTester($this->command);
+ $commandTester->execute(['command' => 'background:' . $mode]);
+
+ $commandTester->assertCommandIsSuccessful();
+
+ $output = $commandTester->getDisplay();
+ $this->assertStringContainsString($mode, $output);
+ }
+
+ public static function dataModeCommand(): array {
+ return [
+ 'ajax' => ['ajax'],
+ 'cron' => ['cron'],
+ 'webcron' => ['webcron'],
+ ];
+ }
+}
diff --git a/tests/lib/Command/CronBusTest.php b/tests/lib/Command/CronBusTest.php
new file mode 100644
index 00000000000..c86cdcb1da0
--- /dev/null
+++ b/tests/lib/Command/CronBusTest.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace Test\Command;
+
+use OC\Command\CronBus;
+use OCP\BackgroundJob\IJobList;
+use Test\BackgroundJob\DummyJobList;
+
+/**
+ * @group DB
+ */
+class CronBusTest extends AsyncBusTestCase {
+ /**
+ * @var IJobList
+ */
+ private $jobList;
+
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->jobList = new DummyJobList();
+ }
+
+ protected function createBus() {
+ return new CronBus($this->jobList);
+ }
+
+ protected function runJobs() {
+ $jobs = $this->jobList->getAll();
+ foreach ($jobs as $job) {
+ $job->start($this->jobList);
+ }
+ }
+}
diff --git a/tests/lib/Command/Integrity/SignAppTest.php b/tests/lib/Command/Integrity/SignAppTest.php
new file mode 100644
index 00000000000..237afe3a5b5
--- /dev/null
+++ b/tests/lib/Command/Integrity/SignAppTest.php
@@ -0,0 +1,272 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+namespace Test\Command\Integrity;
+
+use OC\Core\Command\Integrity\SignApp;
+use OC\IntegrityCheck\Checker;
+use OC\IntegrityCheck\Helpers\FileAccessHelper;
+use OCP\IURLGenerator;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Test\TestCase;
+
+class SignAppTest extends TestCase {
+ /** @var Checker|\PHPUnit\Framework\MockObject\MockObject */
+ private $checker;
+ /** @var SignApp */
+ private $signApp;
+ /** @var FileAccessHelper|\PHPUnit\Framework\MockObject\MockObject */
+ private $fileAccessHelper;
+ /** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */
+ private $urlGenerator;
+
+ protected function setUp(): void {
+ parent::setUp();
+ $this->checker = $this->createMock(Checker::class);
+ $this->fileAccessHelper = $this->createMock(FileAccessHelper::class);
+ $this->urlGenerator = $this->createMock(IURLGenerator::class);
+ $this->signApp = new SignApp(
+ $this->checker,
+ $this->fileAccessHelper,
+ $this->urlGenerator
+ );
+ }
+
+ public function testExecuteWithMissingPath(): void {
+ $inputInterface = $this->createMock(InputInterface::class);
+ $outputInterface = $this->createMock(OutputInterface::class);
+
+ $inputInterface
+ ->expects($this->exactly(3))
+ ->method('getOption')
+ ->willReturnMap([
+ ['path', null],
+ ['privateKey', 'PrivateKey'],
+ ['certificate', 'Certificate'],
+ ]);
+
+ $calls = [
+ 'This command requires the --path, --privateKey and --certificate.',
+ '*',
+ '*',
+ ];
+ $outputInterface
+ ->expects($this->any())
+ ->method('writeln')
+ ->willReturnCallback(function (string $message) use (&$calls): void {
+ $expected = array_shift($calls);
+ if ($expected === '*') {
+ $this->assertNotEmpty($message);
+ } else {
+ $this->assertEquals($expected, $message);
+ }
+ });
+
+ $this->assertSame(1, self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]));
+ }
+
+ public function testExecuteWithMissingPrivateKey(): void {
+ $inputInterface = $this->createMock(InputInterface::class);
+ $outputInterface = $this->createMock(OutputInterface::class);
+
+ $inputInterface
+ ->expects($this->exactly(3))
+ ->method('getOption')
+ ->willReturnMap([
+ ['path', 'AppId'],
+ ['privateKey', null],
+ ['certificate', 'Certificate'],
+ ]);
+
+ $calls = [
+ 'This command requires the --path, --privateKey and --certificate.',
+ '*',
+ '*',
+ ];
+ $outputInterface
+ ->expects($this->any())
+ ->method('writeln')
+ ->willReturnCallback(function (string $message) use (&$calls): void {
+ $expected = array_shift($calls);
+ if ($expected === '*') {
+ $this->assertNotEmpty($message);
+ } else {
+ $this->assertEquals($expected, $message);
+ }
+ });
+
+ $this->assertSame(1, self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]));
+ }
+
+ public function testExecuteWithMissingCertificate(): void {
+ $inputInterface = $this->createMock(InputInterface::class);
+ $outputInterface = $this->createMock(OutputInterface::class);
+
+ $inputInterface
+ ->expects($this->exactly(3))
+ ->method('getOption')
+ ->willReturnMap([
+ ['path', 'AppId'],
+ ['privateKey', 'PrivateKey'],
+ ['certificate', null],
+ ]);
+
+ $calls = [
+ 'This command requires the --path, --privateKey and --certificate.',
+ '*',
+ '*',
+ ];
+ $outputInterface
+ ->expects($this->any())
+ ->method('writeln')
+ ->willReturnCallback(function (string $message) use (&$calls): void {
+ $expected = array_shift($calls);
+ if ($expected === '*') {
+ $this->assertNotEmpty($message);
+ } else {
+ $this->assertEquals($expected, $message);
+ }
+ });
+
+ $this->assertSame(1, self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]));
+ }
+
+ public function testExecuteWithNotExistingPrivateKey(): void {
+ $inputInterface = $this->createMock(InputInterface::class);
+ $outputInterface = $this->createMock(OutputInterface::class);
+
+ $inputInterface
+ ->expects($this->exactly(3))
+ ->method('getOption')
+ ->willReturnMap([
+ ['path', 'AppId'],
+ ['privateKey', 'privateKey'],
+ ['certificate', 'certificate'],
+ ]);
+
+ $this->fileAccessHelper
+ ->expects($this->any())
+ ->method('file_get_contents')
+ ->willReturnMap([
+ ['privateKey', false],
+ ]);
+
+
+ $outputInterface
+ ->expects($this->any())
+ ->method('writeln')
+ ->willReturnCallback(function (string $message): void {
+ $this->assertEquals('Private key "privateKey" does not exists.', $message);
+ });
+
+ $this->assertSame(1, self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]));
+ }
+
+ public function testExecuteWithNotExistingCertificate(): void {
+ $inputInterface = $this->createMock(InputInterface::class);
+ $outputInterface = $this->createMock(OutputInterface::class);
+
+ $inputInterface
+ ->expects($this->exactly(3))
+ ->method('getOption')
+ ->willReturnMap([
+ ['path', 'AppId'],
+ ['privateKey', 'privateKey'],
+ ['certificate', 'certificate'],
+ ]);
+
+ $this->fileAccessHelper
+ ->expects($this->any())
+ ->method('file_get_contents')
+ ->willReturnMap([
+ ['privateKey', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')],
+ ['certificate', false],
+ ]);
+
+ $outputInterface
+ ->expects($this->any())
+ ->method('writeln')
+ ->willReturnCallback(function (string $message): void {
+ $this->assertEquals('Certificate "certificate" does not exists.', $message);
+ });
+
+ $this->assertSame(1, self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]));
+ }
+
+ public function testExecuteWithException(): void {
+ $inputInterface = $this->createMock(InputInterface::class);
+ $outputInterface = $this->createMock(OutputInterface::class);
+
+ $inputInterface
+ ->expects($this->exactly(3))
+ ->method('getOption')
+ ->willReturnMap([
+ ['path', 'AppId'],
+ ['privateKey', 'privateKey'],
+ ['certificate', 'certificate'],
+ ]);
+
+ $this->fileAccessHelper
+ ->expects($this->any())
+ ->method('file_get_contents')
+ ->willReturnMap([
+ ['privateKey', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')],
+ ['certificate', \OC::$SERVERROOT . '/tests/data/integritycheck/core.crt'],
+ ]);
+
+ $this->checker
+ ->expects($this->once())
+ ->method('writeAppSignature')
+ ->willThrowException(new \Exception('My error message'));
+
+ $outputInterface
+ ->expects($this->any())
+ ->method('writeln')
+ ->willReturnCallback(function (string $message): void {
+ $this->assertEquals('Error: My error message', $message);
+ });
+
+ $this->assertSame(1, self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]));
+ }
+
+ public function testExecute(): void {
+ $inputInterface = $this->createMock(InputInterface::class);
+ $outputInterface = $this->createMock(OutputInterface::class);
+
+ $inputInterface
+ ->expects($this->exactly(3))
+ ->method('getOption')
+ ->willReturnMap([
+ ['path', 'AppId'],
+ ['privateKey', 'privateKey'],
+ ['certificate', 'certificate'],
+ ]);
+
+ $this->fileAccessHelper
+ ->expects($this->any())
+ ->method('file_get_contents')
+ ->willReturnMap([
+ ['privateKey', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')],
+ ['certificate', \OC::$SERVERROOT . '/tests/data/integritycheck/core.crt'],
+ ]);
+
+ $this->checker
+ ->expects($this->once())
+ ->method('writeAppSignature');
+
+ $outputInterface
+ ->expects($this->any())
+ ->method('writeln')
+ ->willReturnCallback(function (string $message): void {
+ $this->assertEquals('Successfully signed "AppId"', $message);
+ });
+
+ $this->assertSame(0, self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface]));
+ }
+}
diff --git a/tests/lib/Command/Integrity/SignCoreTest.php b/tests/lib/Command/Integrity/SignCoreTest.php
new file mode 100644
index 00000000000..843084eebd9
--- /dev/null
+++ b/tests/lib/Command/Integrity/SignCoreTest.php
@@ -0,0 +1,212 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+namespace Test\Command\Integrity;
+
+use OC\Core\Command\Integrity\SignCore;
+use OC\IntegrityCheck\Checker;
+use OC\IntegrityCheck\Helpers\FileAccessHelper;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Test\TestCase;
+
+class SignCoreTest extends TestCase {
+ /** @var Checker|\PHPUnit\Framework\MockObject\MockObject */
+ private $checker;
+ /** @var FileAccessHelper|\PHPUnit\Framework\MockObject\MockObject */
+ private $fileAccessHelper;
+ /** @var SignCore */
+ private $signCore;
+
+ protected function setUp(): void {
+ parent::setUp();
+ $this->checker = $this->createMock(Checker::class);
+ $this->fileAccessHelper = $this->createMock(FileAccessHelper::class);
+ $this->signCore = new SignCore(
+ $this->checker,
+ $this->fileAccessHelper
+ );
+ }
+
+ public function testExecuteWithMissingPrivateKey(): void {
+ $inputInterface = $this->createMock(InputInterface::class);
+ $outputInterface = $this->createMock(OutputInterface::class);
+
+ $inputInterface
+ ->expects($this->exactly(3))
+ ->method('getOption')
+ ->willReturnMap([
+ ['privateKey', null],
+ ['certificate', 'certificate'],
+ ['path', 'certificate'],
+ ]);
+
+ $outputInterface
+ ->expects($this->any())
+ ->method('writeln')
+ ->willReturnCallback(function (string $message): void {
+ $this->assertEquals('--privateKey, --certificate and --path are required.', $message);
+ });
+
+ $this->assertSame(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
+ }
+
+ public function testExecuteWithMissingCertificate(): void {
+ $inputInterface = $this->createMock(InputInterface::class);
+ $outputInterface = $this->createMock(OutputInterface::class);
+
+ $inputInterface
+ ->expects($this->exactly(3))
+ ->method('getOption')
+ ->willReturnMap([
+ ['privateKey', 'privateKey'],
+ ['certificate', null],
+ ['path', 'certificate'],
+ ]);
+
+ $outputInterface
+ ->expects($this->any())
+ ->method('writeln')
+ ->willReturnCallback(function (string $message): void {
+ $this->assertEquals('--privateKey, --certificate and --path are required.', $message);
+ });
+
+ $this->assertSame(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
+ }
+
+ public function testExecuteWithNotExistingPrivateKey(): void {
+ $inputInterface = $this->createMock(InputInterface::class);
+ $outputInterface = $this->createMock(OutputInterface::class);
+
+ $inputInterface
+ ->expects($this->exactly(3))
+ ->method('getOption')
+ ->willReturnMap([
+ ['privateKey', 'privateKey'],
+ ['certificate', 'certificate'],
+ ['path', 'certificate'],
+ ]);
+
+ $this->fileAccessHelper
+ ->method('file_get_contents')
+ ->willReturnMap([
+ ['privateKey', false],
+ ]);
+
+ $outputInterface
+ ->expects($this->any())
+ ->method('writeln')
+ ->willReturnCallback(function (string $message): void {
+ $this->assertEquals('Private key "privateKey" does not exists.', $message);
+ });
+
+ $this->assertSame(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
+ }
+
+ public function testExecuteWithNotExistingCertificate(): void {
+ $inputInterface = $this->createMock(InputInterface::class);
+ $outputInterface = $this->createMock(OutputInterface::class);
+
+ $inputInterface
+ ->expects($this->exactly(3))
+ ->method('getOption')
+ ->willReturnMap([
+ ['privateKey', 'privateKey'],
+ ['certificate', 'certificate'],
+ ['path', 'certificate'],
+ ]);
+
+ $this->fileAccessHelper
+ ->expects($this->any())
+ ->method('file_get_contents')
+ ->willReturnMap([
+ ['privateKey', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')],
+ ['certificate', false],
+ ]);
+
+ $outputInterface
+ ->expects($this->any())
+ ->method('writeln')
+ ->willReturnCallback(function (string $message): void {
+ $this->assertEquals('Certificate "certificate" does not exists.', $message);
+ });
+
+ $this->assertSame(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
+ }
+
+ public function testExecuteWithException(): void {
+ $inputInterface = $this->createMock(InputInterface::class);
+ $outputInterface = $this->createMock(OutputInterface::class);
+
+ $inputInterface
+ ->expects($this->exactly(3))
+ ->method('getOption')
+ ->willReturnMap([
+ ['privateKey', 'privateKey'],
+ ['certificate', 'certificate'],
+ ['path', 'certificate'],
+ ]);
+
+ $this->fileAccessHelper
+ ->expects($this->any())
+ ->method('file_get_contents')
+ ->willReturnMap([
+ ['privateKey', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')],
+ ['certificate', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt')],
+ ]);
+
+ $this->checker
+ ->expects($this->once())
+ ->method('writeCoreSignature')
+ ->willThrowException(new \Exception('My exception message'));
+
+ $outputInterface
+ ->expects($this->any())
+ ->method('writeln')
+ ->willReturnCallback(function (string $message): void {
+ $this->assertEquals('Error: My exception message', $message);
+ });
+
+ $this->assertEquals(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
+ }
+
+ public function testExecute(): void {
+ $inputInterface = $this->createMock(InputInterface::class);
+ $outputInterface = $this->createMock(OutputInterface::class);
+
+ $inputInterface
+ ->expects($this->exactly(3))
+ ->method('getOption')
+ ->willReturnMap([
+ ['privateKey', 'privateKey'],
+ ['certificate', 'certificate'],
+ ['path', 'certificate'],
+ ]);
+
+ $this->fileAccessHelper
+ ->expects($this->any())
+ ->method('file_get_contents')
+ ->willReturnMap([
+ ['privateKey', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')],
+ ['certificate', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt')],
+ ]);
+
+ $this->checker
+ ->expects($this->once())
+ ->method('writeCoreSignature');
+
+ $outputInterface
+ ->expects($this->any())
+ ->method('writeln')
+ ->willReturnCallback(function (string $message): void {
+ $this->assertEquals('Successfully signed "core"', $message);
+ });
+
+ $this->assertEquals(0, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
+ }
+}