123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455 |
- <?php
- /**
- * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- namespace OCA\Provisioning_API\Tests\Controller;
- use OC\AppConfig;
- use OCA\Provisioning_API\Controller\AppConfigController;
- use OCP\AppFramework\Http;
- use OCP\AppFramework\Http\DataResponse;
- use OCP\Exceptions\AppConfigUnknownKeyException;
- use OCP\IAppConfig;
- use OCP\IGroupManager;
- use OCP\IL10N;
- use OCP\IRequest;
- use OCP\IUser;
- use OCP\IUserSession;
- use OCP\Settings\IManager;
- use Test\TestCase;
- use function json_decode;
- use function json_encode;
- /**
- * Class AppConfigControllerTest
- *
- * @package OCA\Provisioning_API\Tests
- */
- class AppConfigControllerTest extends TestCase {
- /** @var IAppConfig|\PHPUnit\Framework\MockObject\MockObject */
- private $appConfig;
- /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */
- private $userSession;
- /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */
- private $l10n;
- /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */
- private $settingManager;
- /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */
- private $groupManager;
- protected function setUp(): void {
- parent::setUp();
- $this->appConfig = $this->createMock(AppConfig::class);
- $this->userSession = $this->createMock(IUserSession::class);
- $this->l10n = $this->createMock(IL10N::class);
- $this->groupManager = $this->createMock(IGroupManager::class);
- $this->settingManager = $this->createMock(IManager::class);
- }
- /**
- * @param string[] $methods
- * @return AppConfigController|\PHPUnit\Framework\MockObject\MockObject
- */
- protected function getInstance(array $methods = []) {
- $request = $this->createMock(IRequest::class);
- if (empty($methods)) {
- return new AppConfigController(
- 'provisioning_api',
- $request,
- $this->appConfig,
- $this->userSession,
- $this->l10n,
- $this->groupManager,
- $this->settingManager
- );
- } else {
- return $this->getMockBuilder(AppConfigController::class)
- ->setConstructorArgs([
- 'provisioning_api',
- $request,
- $this->appConfig,
- $this->userSession,
- $this->l10n,
- $this->groupManager,
- $this->settingManager
- ])
- ->setMethods($methods)
- ->getMock();
- }
- }
- public function testGetApps() {
- $this->appConfig->expects($this->once())
- ->method('getApps')
- ->willReturn(['apps']);
- $result = $this->getInstance()->getApps();
- $this->assertInstanceOf(DataResponse::class, $result);
- $this->assertSame(Http::STATUS_OK, $result->getStatus());
- $this->assertEquals(['data' => ['apps']], $result->getData());
- }
- public function dataGetKeys() {
- return [
- ['app1 ', null, new \InvalidArgumentException('error'), Http::STATUS_FORBIDDEN],
- ['app2', ['keys'], null, Http::STATUS_OK],
- ];
- }
- /**
- * @dataProvider dataGetKeys
- * @param string $app
- * @param array|null $keys
- * @param \Exception|null $throws
- * @param int $status
- */
- public function testGetKeys($app, $keys, $throws, $status) {
- $api = $this->getInstance(['verifyAppId']);
- if ($throws instanceof \Exception) {
- $api->expects($this->once())
- ->method('verifyAppId')
- ->with($app)
- ->willThrowException($throws);
- $this->appConfig->expects($this->never())
- ->method('getKeys');
- } else {
- $api->expects($this->once())
- ->method('verifyAppId')
- ->with($app);
- $this->appConfig->expects($this->once())
- ->method('getKeys')
- ->with($app)
- ->willReturn($keys);
- }
- $result = $api->getKeys($app);
- $this->assertInstanceOf(DataResponse::class, $result);
- $this->assertSame($status, $result->getStatus());
- if ($throws instanceof \Exception) {
- $this->assertEquals(['data' => ['message' => $throws->getMessage()]], $result->getData());
- } else {
- $this->assertEquals(['data' => $keys], $result->getData());
- }
- }
- public function dataGetValue() {
- return [
- ['app1', 'key', 'default', null, new \InvalidArgumentException('error'), Http::STATUS_FORBIDDEN],
- ['app2', 'key', 'default', 'return', null, Http::STATUS_OK],
- ];
- }
- /**
- * @dataProvider dataGetValue
- * @param string $app
- * @param string|null $key
- * @param string|null $default
- * @param string|null $return
- * @param \Exception|null $throws
- * @param int $status
- */
- public function testGetValue($app, $key, $default, $return, $throws, $status) {
- $api = $this->getInstance(['verifyAppId']);
- if ($throws instanceof \Exception) {
- $api->expects($this->once())
- ->method('verifyAppId')
- ->with($app)
- ->willThrowException($throws);
- } else {
- $api->expects($this->once())
- ->method('verifyAppId')
- ->with($app);
- $this->appConfig->expects($this->once())
- ->method('getValueMixed')
- ->with($app, $key, $default)
- ->willReturn($return);
- }
- $result = $api->getValue($app, $key, $default);
- $this->assertInstanceOf(DataResponse::class, $result);
- $this->assertSame($status, $result->getStatus());
- if ($throws instanceof \Exception) {
- $this->assertEquals(['data' => ['message' => $throws->getMessage()]], $result->getData());
- } else {
- $this->assertEquals(['data' => $return], $result->getData());
- }
- }
- public function dataSetValue() {
- return [
- ['app1', 'key', 'default', new \InvalidArgumentException('error1'), null, Http::STATUS_FORBIDDEN],
- ['app2', 'key', 'default', null, new \InvalidArgumentException('error2'), Http::STATUS_FORBIDDEN],
- ['app2', 'key', 'default', null, null, Http::STATUS_OK],
- ['app2', 'key', '1', null, null, Http::STATUS_OK, IAppConfig::VALUE_BOOL],
- ['app2', 'key', '42', null, null, Http::STATUS_OK, IAppConfig::VALUE_INT],
- ['app2', 'key', '4.2', null, null, Http::STATUS_OK, IAppConfig::VALUE_FLOAT],
- ['app2', 'key', '42', null, null, Http::STATUS_OK, IAppConfig::VALUE_STRING],
- ['app2', 'key', 'secret', null, null, Http::STATUS_OK, IAppConfig::VALUE_STRING | IAppConfig::VALUE_SENSITIVE],
- ['app2', 'key', json_encode([4, 2]), null, null, Http::STATUS_OK, IAppConfig::VALUE_ARRAY],
- ['app2', 'key', json_encode([4, 2]), null, null, Http::STATUS_OK, new AppConfigUnknownKeyException()],
- ];
- }
- /**
- * @dataProvider dataSetValue
- * @param string $app
- * @param string|null $key
- * @param string|null $value
- * @param \Exception|null $appThrows
- * @param \Exception|null $keyThrows
- * @param int|\Throwable $status
- */
- public function testSetValue($app, $key, $value, $appThrows, $keyThrows, $status, int|\Throwable $type = IAppConfig::VALUE_MIXED) {
- $adminUser = $this->createMock(IUser::class);
- $adminUser->expects($this->once())
- ->method('getUid')
- ->willReturn('admin');
- $this->userSession->expects($this->once())
- ->method('getUser')
- ->willReturn($adminUser);
- $this->groupManager->expects($this->once())
- ->method('isAdmin')
- ->with('admin')
- ->willReturn(true);
- $api = $this->getInstance(['verifyAppId', 'verifyConfigKey']);
- if ($appThrows instanceof \Exception) {
- $api->expects($this->once())
- ->method('verifyAppId')
- ->with($app)
- ->willThrowException($appThrows);
- $api->expects($this->never())
- ->method('verifyConfigKey');
- $this->appConfig->expects($this->never())
- ->method('setValueMixed');
- } elseif ($keyThrows instanceof \Exception) {
- $api->expects($this->once())
- ->method('verifyAppId')
- ->with($app);
- $api->expects($this->once())
- ->method('verifyConfigKey')
- ->with($app, $key)
- ->willThrowException($keyThrows);
- $this->appConfig->expects($this->never())
- ->method('setValueMixed');
- } else {
- $api->expects($this->once())
- ->method('verifyAppId')
- ->with($app);
- $api->expects($this->once())
- ->method('verifyConfigKey')
- ->with($app, $key);
- if ($type instanceof \Throwable) {
- $this->appConfig->expects($this->once())
- ->method('getDetails')
- ->with($app, $key)
- ->willThrowException($type);
- } else {
- $this->appConfig->expects($this->once())
- ->method('getDetails')
- ->with($app, $key)
- ->willReturn([
- 'app' => $app,
- 'key' => $key,
- 'value' => '', // 🤷
- 'type' => $type,
- 'lazy' => false,
- 'typeString' => (string)$type, // this is not accurate, but acceptable
- 'sensitive' => ($type & IAppConfig::VALUE_SENSITIVE) !== 0,
- ]);
- }
- $configValueSetter = match ($type) {
- IAppConfig::VALUE_BOOL => 'setValueBool',
- IAppConfig::VALUE_FLOAT => 'setValueFloat',
- IAppConfig::VALUE_INT => 'setValueInt',
- IAppConfig::VALUE_STRING => 'setValueString',
- IAppConfig::VALUE_ARRAY => 'setValueArray',
- default => 'setValueMixed',
- };
- $this->appConfig->expects($this->once())
- ->method($configValueSetter)
- ->with($app, $key, $configValueSetter === 'setValueArray' ? json_decode($value, true) : $value);
- }
- $result = $api->setValue($app, $key, $value);
- $this->assertInstanceOf(DataResponse::class, $result);
- $this->assertSame($status, $result->getStatus());
- if ($appThrows instanceof \Exception) {
- $this->assertEquals(['data' => ['message' => $appThrows->getMessage()]], $result->getData());
- } elseif ($keyThrows instanceof \Exception) {
- $this->assertEquals(['data' => ['message' => $keyThrows->getMessage()]], $result->getData());
- } else {
- $this->assertEquals([], $result->getData());
- }
- }
- public function dataDeleteValue() {
- return [
- ['app1', 'key', new \InvalidArgumentException('error1'), null, Http::STATUS_FORBIDDEN],
- ['app2', 'key', null, new \InvalidArgumentException('error2'), Http::STATUS_FORBIDDEN],
- ['app2', 'key', null, null, Http::STATUS_OK],
- ];
- }
- /**
- * @dataProvider dataDeleteValue
- * @param string $app
- * @param string|null $key
- * @param \Exception|null $appThrows
- * @param \Exception|null $keyThrows
- * @param int $status
- */
- public function testDeleteValue($app, $key, $appThrows, $keyThrows, $status) {
- $api = $this->getInstance(['verifyAppId', 'verifyConfigKey']);
- if ($appThrows instanceof \Exception) {
- $api->expects($this->once())
- ->method('verifyAppId')
- ->with($app)
- ->willThrowException($appThrows);
- $api->expects($this->never())
- ->method('verifyConfigKey');
- $this->appConfig->expects($this->never())
- ->method('deleteKey');
- } elseif ($keyThrows instanceof \Exception) {
- $api->expects($this->once())
- ->method('verifyAppId')
- ->with($app);
- $api->expects($this->once())
- ->method('verifyConfigKey')
- ->with($app, $key)
- ->willThrowException($keyThrows);
- $this->appConfig->expects($this->never())
- ->method('deleteKey');
- } else {
- $api->expects($this->once())
- ->method('verifyAppId')
- ->with($app);
- $api->expects($this->once())
- ->method('verifyConfigKey')
- ->with($app, $key);
- $this->appConfig->expects($this->once())
- ->method('deleteKey')
- ->with($app, $key);
- }
- $result = $api->deleteKey($app, $key);
- $this->assertInstanceOf(DataResponse::class, $result);
- $this->assertSame($status, $result->getStatus());
- if ($appThrows instanceof \Exception) {
- $this->assertEquals(['data' => ['message' => $appThrows->getMessage()]], $result->getData());
- } elseif ($keyThrows instanceof \Exception) {
- $this->assertEquals(['data' => ['message' => $keyThrows->getMessage()]], $result->getData());
- } else {
- $this->assertEquals([], $result->getData());
- }
- }
- public function testVerifyAppId() {
- $api = $this->getInstance();
- $this->invokePrivate($api, 'verifyAppId', ['activity']);
- $this->addToAssertionCount(1);
- }
- public function dataVerifyAppIdThrows() {
- return [
- ['activity..'],
- ['activity/'],
- ['activity\\'],
- ['activity\0'],
- ];
- }
- /**
- * @dataProvider dataVerifyAppIdThrows
- * @param string $app
- */
- public function testVerifyAppIdThrows($app) {
- $this->expectException(\InvalidArgumentException::class);
- $api = $this->getInstance();
- $this->invokePrivate($api, 'verifyAppId', [$app]);
- }
- public function dataVerifyConfigKey() {
- return [
- ['activity', 'abc', ''],
- ['dav', 'public_route', ''],
- ['files', 'remote_route', ''],
- ['core', 'encryption_enabled', 'yes'],
- ];
- }
- /**
- * @dataProvider dataVerifyConfigKey
- * @param string $app
- * @param string $key
- * @param string $value
- */
- public function testVerifyConfigKey($app, $key, $value) {
- $api = $this->getInstance();
- $this->invokePrivate($api, 'verifyConfigKey', [$app, $key, $value]);
- $this->addToAssertionCount(1);
- }
- public function dataVerifyConfigKeyThrows() {
- return [
- ['activity', 'installed_version', ''],
- ['calendar', 'enabled', ''],
- ['contacts', 'types', ''],
- ['core', 'encryption_enabled', 'no'],
- ['core', 'encryption_enabled', ''],
- ['core', 'public_files', ''],
- ['core', 'public_dav', ''],
- ['core', 'remote_files', ''],
- ['core', 'remote_dav', ''],
- ];
- }
- /**
- * @dataProvider dataVerifyConfigKeyThrows
- * @param string $app
- * @param string $key
- * @param string $value
- */
- public function testVerifyConfigKeyThrows($app, $key, $value) {
- $this->expectException(\InvalidArgumentException::class);
- $api = $this->getInstance();
- $this->invokePrivate($api, 'verifyConfigKey', [$app, $key, $value]);
- }
- }
|