2020-04-09 05:50:14 -04:00
< ? php
declare ( strict_types = 1 );
2014-11-07 08:26:12 -05:00
/**
2024-05-10 09:09:14 -04:00
* SPDX - FileCopyrightText : 2016 - 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX - FileCopyrightText : 2016 ownCloud , Inc .
* SPDX - License - Identifier : AGPL - 3.0 - or - later
2014-11-07 08:26:12 -05:00
*/
namespace Test\App ;
2017-03-20 05:21:08 -04:00
use OC\App\AppManager ;
2018-01-17 15:10:40 -05:00
use OC\AppConfig ;
2016-11-17 06:30:52 -05:00
use OCP\App\AppPathNotFoundException ;
2022-12-08 04:55:19 -05:00
use OCP\App\Events\AppDisableEvent ;
use OCP\App\Events\AppEnableEvent ;
2017-03-20 05:21:08 -04:00
use OCP\App\IAppManager ;
2022-12-08 04:55:19 -05:00
use OCP\EventDispatcher\IEventDispatcher ;
2017-03-20 05:21:08 -04:00
use OCP\ICache ;
use OCP\ICacheFactory ;
2019-11-22 14:52:10 -05:00
use OCP\IConfig ;
2019-02-22 07:07:26 -05:00
use OCP\IGroup ;
2017-03-20 05:21:08 -04:00
use OCP\IGroupManager ;
2024-03-06 05:13:29 -05:00
use OCP\IURLGenerator ;
2019-02-22 07:07:26 -05:00
use OCP\IUser ;
2017-03-20 05:21:08 -04:00
use OCP\IUserSession ;
2019-09-05 06:55:24 -04:00
use PHPUnit\Framework\MockObject\MockObject ;
2021-04-19 08:06:34 -04:00
use Psr\Log\LoggerInterface ;
2015-12-17 11:29:17 -05:00
use Test\TestCase ;
2014-11-07 08:26:12 -05:00
2016-01-14 09:23:07 -05:00
/**
2017-03-20 05:21:08 -04:00
* Class AppManagerTest
2016-01-14 09:23:07 -05:00
*
* @ package Test\App
*/
2017-03-20 05:21:08 -04:00
class AppManagerTest extends TestCase {
2014-11-07 08:26:12 -05:00
/**
2019-09-05 06:55:24 -04:00
* @ return AppConfig | MockObject
2014-11-07 08:26:12 -05:00
*/
protected function getAppConfig () {
2020-03-26 04:30:18 -04:00
$appConfig = [];
2018-01-17 15:10:40 -05:00
$config = $this -> createMock ( AppConfig :: class );
2014-11-07 08:26:12 -05:00
$config -> expects ( $this -> any ())
-> method ( 'getValue' )
2020-03-25 17:21:27 -04:00
-> willReturnCallback ( function ( $app , $key , $default ) use ( & $appConfig ) {
2014-11-07 08:26:12 -05:00
return ( isset ( $appConfig [ $app ]) and isset ( $appConfig [ $app ][ $key ])) ? $appConfig [ $app ][ $key ] : $default ;
2020-03-25 17:21:27 -04:00
});
2014-11-07 08:26:12 -05:00
$config -> expects ( $this -> any ())
-> method ( 'setValue' )
2020-03-25 17:21:27 -04:00
-> willReturnCallback ( function ( $app , $key , $value ) use ( & $appConfig ) {
2014-11-07 08:26:12 -05:00
if ( ! isset ( $appConfig [ $app ])) {
2020-03-26 04:30:18 -04:00
$appConfig [ $app ] = [];
2014-11-07 08:26:12 -05:00
}
$appConfig [ $app ][ $key ] = $value ;
2020-03-25 17:21:27 -04:00
});
2014-11-07 08:26:12 -05:00
$config -> expects ( $this -> any ())
-> method ( 'getValues' )
2020-03-25 17:21:27 -04:00
-> willReturnCallback ( function ( $app , $key ) use ( & $appConfig ) {
2014-11-07 08:26:12 -05:00
if ( $app ) {
return $appConfig [ $app ];
} else {
2020-03-26 04:30:18 -04:00
$values = [];
2017-03-20 05:21:08 -04:00
foreach ( $appConfig as $appid => $appData ) {
2014-11-07 08:26:12 -05:00
if ( isset ( $appData [ $key ])) {
2017-03-20 05:21:08 -04:00
$values [ $appid ] = $appData [ $key ];
2014-11-07 08:26:12 -05:00
}
}
return $values ;
}
2020-03-25 17:21:27 -04:00
});
2014-11-07 08:26:12 -05:00
return $config ;
}
2019-09-05 06:55:24 -04:00
/** @var IUserSession|MockObject */
2015-04-01 11:19:44 -04:00
protected $userSession ;
2019-09-05 06:55:24 -04:00
/** @var IConfig|MockObject */
private $config ;
/** @var IGroupManager|MockObject */
2015-04-01 11:19:44 -04:00
protected $groupManager ;
2019-09-05 06:55:24 -04:00
/** @var AppConfig|MockObject */
2015-04-01 11:19:44 -04:00
protected $appConfig ;
2019-09-05 06:55:24 -04:00
/** @var ICache|MockObject */
2015-04-01 11:19:44 -04:00
protected $cache ;
2019-09-05 06:55:24 -04:00
/** @var ICacheFactory|MockObject */
2015-04-01 11:19:44 -04:00
protected $cacheFactory ;
2022-12-08 04:55:19 -05:00
/** @var IEventDispatcher|MockObject */
2016-02-08 20:51:12 -05:00
protected $eventDispatcher ;
2021-04-19 08:06:34 -04:00
/** @var LoggerInterface|MockObject */
2019-07-15 16:19:11 -04:00
protected $logger ;
2024-04-22 09:50:06 -04:00
protected IURLGenerator & MockObject $urlGenerator ;
2024-03-06 05:13:29 -05:00
2017-03-20 05:21:08 -04:00
/** @var IAppManager */
protected $manager ;
2019-11-21 10:40:38 -05:00
protected function setUp () : void {
2015-04-01 11:19:44 -04:00
parent :: setUp ();
2017-03-20 06:14:14 -04:00
$this -> userSession = $this -> createMock ( IUserSession :: class );
$this -> groupManager = $this -> createMock ( IGroupManager :: class );
2019-09-05 06:55:24 -04:00
$this -> config = $this -> createMock ( IConfig :: class );
2015-04-01 11:19:44 -04:00
$this -> appConfig = $this -> getAppConfig ();
2017-03-20 06:14:14 -04:00
$this -> cacheFactory = $this -> createMock ( ICacheFactory :: class );
$this -> cache = $this -> createMock ( ICache :: class );
2022-12-08 04:55:19 -05:00
$this -> eventDispatcher = $this -> createMock ( IEventDispatcher :: class );
2021-04-19 08:06:34 -04:00
$this -> logger = $this -> createMock ( LoggerInterface :: class );
2024-03-06 05:13:29 -05:00
$this -> urlGenerator = $this -> createMock ( IURLGenerator :: class );
2024-03-06 12:19:24 -05:00
$this -> overwriteService ( AppConfig :: class , $this -> appConfig );
2024-04-22 09:50:06 -04:00
$this -> overwriteService ( IURLGenerator :: class , $this -> urlGenerator );
2024-03-06 12:19:24 -05:00
2015-04-01 11:19:44 -04:00
$this -> cacheFactory -> expects ( $this -> any ())
2017-12-18 15:06:52 -05:00
-> method ( 'createDistributed' )
2015-04-01 11:19:44 -04:00
-> with ( 'settings' )
-> willReturn ( $this -> cache );
2024-03-06 12:19:24 -05:00
$this -> config
-> method ( 'getSystemValueBool' )
-> with ( 'installed' , false )
-> willReturn ( true );
2019-09-05 06:55:24 -04:00
$this -> manager = new AppManager (
$this -> userSession ,
$this -> config ,
$this -> groupManager ,
$this -> cacheFactory ,
$this -> eventDispatcher ,
2024-03-06 05:13:29 -05:00
$this -> logger ,
2019-09-05 06:55:24 -04:00
);
2015-04-01 11:19:44 -04:00
}
2024-03-06 05:13:29 -05:00
/**
* @ dataProvider dataGetAppIcon
*/
2024-03-07 19:05:24 -05:00
public function testGetAppIcon ( $callback , ? bool $dark , string | null $expected ) {
2024-03-06 05:13:29 -05:00
$this -> urlGenerator -> expects ( $this -> atLeastOnce ())
-> method ( 'imagePath' )
-> willReturnCallback ( $callback );
2024-03-07 19:05:24 -05:00
if ( $dark !== null ) {
$this -> assertEquals ( $expected , $this -> manager -> getAppIcon ( 'test' , $dark ));
} else {
$this -> assertEquals ( $expected , $this -> manager -> getAppIcon ( 'test' ));
}
2024-03-06 05:13:29 -05:00
}
public function dataGetAppIcon () : array {
$nothing = function ( $appId ) {
$this -> assertEquals ( 'test' , $appId );
throw new \RuntimeException ();
};
$createCallback = function ( $workingIcons ) {
return function ( $appId , $icon ) use ( $workingIcons ) {
$this -> assertEquals ( 'test' , $appId );
if ( in_array ( $icon , $workingIcons )) {
return '/path/' . $icon ;
}
throw new \RuntimeException ();
};
};
return [
'does not find anything' => [
$nothing ,
2024-03-07 19:05:24 -05:00
false ,
null ,
],
'nothing if request dark but only bright available' => [
$createCallback ([ 'app.svg' ]),
true ,
null ,
],
'nothing if request bright but only dark available' => [
$createCallback ([ 'app-dark.svg' ]),
false ,
2024-03-06 05:13:29 -05:00
null ,
],
2024-03-07 19:05:24 -05:00
'bright and only app.svg' => [
2024-03-06 05:13:29 -05:00
$createCallback ([ 'app.svg' ]),
2024-03-07 19:05:24 -05:00
false ,
2024-03-06 05:13:29 -05:00
'/path/app.svg' ,
],
2024-03-07 19:05:24 -05:00
'dark and only app-dark.svg' => [
2024-03-06 05:13:29 -05:00
$createCallback ([ 'app-dark.svg' ]),
2024-03-07 19:05:24 -05:00
true ,
2024-03-06 05:13:29 -05:00
'/path/app-dark.svg' ,
],
2024-03-07 19:05:24 -05:00
'dark only appname -dark.svg' => [
2024-03-06 05:13:29 -05:00
$createCallback ([ 'test-dark.svg' ]),
2024-03-07 19:05:24 -05:00
true ,
2024-03-06 05:13:29 -05:00
'/path/test-dark.svg' ,
],
2024-03-07 19:05:24 -05:00
'bright and only appname.svg' => [
2024-03-06 05:13:29 -05:00
$createCallback ([ 'test.svg' ]),
2024-03-07 19:05:24 -05:00
false ,
2024-03-06 05:13:29 -05:00
'/path/test.svg' ,
],
'priotize custom over default' => [
$createCallback ([ 'app.svg' , 'test.svg' ]),
2024-03-07 19:05:24 -05:00
false ,
2024-03-06 05:13:29 -05:00
'/path/test.svg' ,
],
2024-03-07 19:05:24 -05:00
'defaults to bright' => [
$createCallback ([ 'test-dark.svg' , 'test.svg' ]),
null ,
'/path/test.svg' ,
2024-03-06 05:13:29 -05:00
],
2024-03-07 19:05:24 -05:00
'no dark icon on default' => [
$createCallback ([ 'test-dark.svg' , 'test.svg' , 'app-dark.svg' , 'app.svg' ]),
false ,
2024-03-06 05:13:29 -05:00
'/path/test.svg' ,
],
2024-03-07 19:05:24 -05:00
'no bright icon on dark' => [
$createCallback ([ 'test-dark.svg' , 'test.svg' , 'app-dark.svg' , 'app.svg' ]),
true ,
'/path/test-dark.svg' ,
],
2024-03-06 05:13:29 -05:00
];
}
2014-11-07 08:26:12 -05:00
public function testEnableApp () {
2017-03-08 05:13:47 -05:00
// making sure "files_trashbin" is disabled
if ( $this -> manager -> isEnabledForUser ( 'files_trashbin' )) {
$this -> manager -> disableApp ( 'files_trashbin' );
}
2022-12-08 04:55:19 -05:00
$this -> eventDispatcher -> expects ( $this -> once ()) -> method ( 'dispatchTyped' ) -> with ( new AppEnableEvent ( 'files_trashbin' ));
2017-03-08 05:13:47 -05:00
$this -> manager -> enableApp ( 'files_trashbin' );
$this -> assertEquals ( 'yes' , $this -> appConfig -> getValue ( 'files_trashbin' , 'enabled' , 'no' ));
2014-11-07 08:26:12 -05:00
}
public function testDisableApp () {
2022-12-08 04:55:19 -05:00
$this -> eventDispatcher -> expects ( $this -> once ()) -> method ( 'dispatchTyped' ) -> with ( new AppDisableEvent ( 'files_trashbin' ));
2017-03-08 05:13:47 -05:00
$this -> manager -> disableApp ( 'files_trashbin' );
$this -> assertEquals ( 'no' , $this -> appConfig -> getValue ( 'files_trashbin' , 'enabled' , 'no' ));
2014-11-07 08:26:12 -05:00
}
2017-03-08 05:13:47 -05:00
public function testNotEnableIfNotInstalled () {
2017-03-20 04:47:32 -04:00
try {
$this -> manager -> enableApp ( 'some_random_name_which_i_hope_is_not_an_app' );
$this -> assertFalse ( true , 'If this line is reached the expected exception is not thrown.' );
2017-03-20 05:02:05 -04:00
} catch ( AppPathNotFoundException $e ) {
// Exception is expected
$this -> assertEquals ( 'Could not find path for some_random_name_which_i_hope_is_not_an_app' , $e -> getMessage ());
2017-03-20 04:47:32 -04:00
}
2017-03-20 05:02:05 -04:00
2017-03-08 05:13:47 -05:00
$this -> assertEquals ( 'no' , $this -> appConfig -> getValue (
'some_random_name_which_i_hope_is_not_an_app' , 'enabled' , 'no'
));
2017-05-20 14:58:36 -04:00
}
2017-03-08 05:13:47 -05:00
2014-11-07 08:26:12 -05:00
public function testEnableAppForGroups () {
2019-02-22 07:07:26 -05:00
$group1 = $this -> createMock ( IGroup :: class );
$group1 -> method ( 'getGID' )
-> willReturn ( 'group1' );
$group2 = $this -> createMock ( IGroup :: class );
$group2 -> method ( 'getGID' )
-> willReturn ( 'group2' );
$groups = [ $group1 , $group2 ];
2019-01-26 16:31:45 -05:00
2019-09-05 06:55:24 -04:00
/** @var AppManager|MockObject $manager */
2019-01-26 16:31:45 -05:00
$manager = $this -> getMockBuilder ( AppManager :: class )
-> setConstructorArgs ([
2024-03-06 05:13:29 -05:00
$this -> userSession ,
$this -> config ,
$this -> groupManager ,
$this -> cacheFactory ,
$this -> eventDispatcher ,
$this -> logger ,
2019-01-26 16:31:45 -05:00
])
2024-03-06 05:13:29 -05:00
-> onlyMethods ([
2019-01-26 16:31:45 -05:00
'getAppPath' ,
])
-> getMock ();
$manager -> expects ( $this -> exactly ( 2 ))
-> method ( 'getAppPath' )
-> with ( 'test' )
-> willReturn ( 'apps/test' );
2022-12-08 04:55:19 -05:00
$this -> eventDispatcher -> expects ( $this -> once ()) -> method ( 'dispatchTyped' ) -> with ( new AppEnableEvent ( 'test' , [ 'group1' , 'group2' ]));
2019-01-26 16:31:45 -05:00
$manager -> enableAppForGroups ( 'test' , $groups );
2015-04-01 11:19:44 -04:00
$this -> assertEquals ( '["group1","group2"]' , $this -> appConfig -> getValue ( 'test' , 'enabled' , 'no' ));
2014-11-07 08:26:12 -05:00
}
2016-01-14 09:23:07 -05:00
public function dataEnableAppForGroupsAllowedTypes () {
return [
[[]],
[[
'types' => [],
]],
[[
'types' => [ 'nickvergessen' ],
]],
];
}
/**
* @ dataProvider dataEnableAppForGroupsAllowedTypes
*
* @ param array $appInfo
*/
public function testEnableAppForGroupsAllowedTypes ( array $appInfo ) {
2019-02-22 07:07:26 -05:00
$group1 = $this -> createMock ( IGroup :: class );
$group1 -> method ( 'getGID' )
-> willReturn ( 'group1' );
$group2 = $this -> createMock ( IGroup :: class );
$group2 -> method ( 'getGID' )
-> willReturn ( 'group2' );
$groups = [ $group1 , $group2 ];
2016-01-14 09:23:07 -05:00
2019-09-05 06:55:24 -04:00
/** @var AppManager|MockObject $manager */
2017-03-20 05:21:08 -04:00
$manager = $this -> getMockBuilder ( AppManager :: class )
2016-01-14 09:23:07 -05:00
-> setConstructorArgs ([
2024-03-06 05:13:29 -05:00
$this -> userSession ,
$this -> config ,
$this -> groupManager ,
$this -> cacheFactory ,
$this -> eventDispatcher ,
$this -> logger ,
2016-01-14 09:23:07 -05:00
])
2024-03-06 05:13:29 -05:00
-> onlyMethods ([
2019-01-26 16:31:45 -05:00
'getAppPath' ,
'getAppInfo' ,
2016-01-14 09:23:07 -05:00
])
-> getMock ();
2019-01-26 16:31:45 -05:00
$manager -> expects ( $this -> once ())
-> method ( 'getAppPath' )
-> with ( 'test' )
-> willReturn ( null );
2016-01-14 09:23:07 -05:00
$manager -> expects ( $this -> once ())
-> method ( 'getAppInfo' )
-> with ( 'test' )
-> willReturn ( $appInfo );
2022-12-08 04:55:19 -05:00
$this -> eventDispatcher -> expects ( $this -> once ()) -> method ( 'dispatchTyped' ) -> with ( new AppEnableEvent ( 'test' , [ 'group1' , 'group2' ]));
2016-01-14 09:23:07 -05:00
$manager -> enableAppForGroups ( 'test' , $groups );
$this -> assertEquals ( '["group1","group2"]' , $this -> appConfig -> getValue ( 'test' , 'enabled' , 'no' ));
}
public function dataEnableAppForGroupsForbiddenTypes () {
return [
[ 'filesystem' ],
[ 'prelogin' ],
[ 'authentication' ],
[ 'logging' ],
[ 'prevent_group_restriction' ],
];
}
/**
* @ dataProvider dataEnableAppForGroupsForbiddenTypes
*
* @ param string $type
*
*/
public function testEnableAppForGroupsForbiddenTypes ( $type ) {
2019-11-27 09:27:18 -05:00
$this -> expectException ( \Exception :: class );
$this -> expectExceptionMessage ( 'test can\'t be enabled for groups.' );
2019-02-22 07:07:26 -05:00
$group1 = $this -> createMock ( IGroup :: class );
$group1 -> method ( 'getGID' )
-> willReturn ( 'group1' );
$group2 = $this -> createMock ( IGroup :: class );
$group2 -> method ( 'getGID' )
-> willReturn ( 'group2' );
$groups = [ $group1 , $group2 ];
2016-01-14 09:23:07 -05:00
2019-09-05 06:55:24 -04:00
/** @var AppManager|MockObject $manager */
2017-03-20 05:21:08 -04:00
$manager = $this -> getMockBuilder ( AppManager :: class )
2016-01-14 09:23:07 -05:00
-> setConstructorArgs ([
2024-03-06 05:13:29 -05:00
$this -> userSession ,
$this -> config ,
$this -> groupManager ,
$this -> cacheFactory ,
$this -> eventDispatcher ,
$this -> logger ,
2016-01-14 09:23:07 -05:00
])
2024-03-06 05:13:29 -05:00
-> onlyMethods ([
2019-01-26 16:31:45 -05:00
'getAppPath' ,
'getAppInfo' ,
2016-01-14 09:23:07 -05:00
])
-> getMock ();
2019-01-26 16:31:45 -05:00
$manager -> expects ( $this -> once ())
-> method ( 'getAppPath' )
-> with ( 'test' )
-> willReturn ( null );
2016-01-14 09:23:07 -05:00
$manager -> expects ( $this -> once ())
-> method ( 'getAppInfo' )
-> with ( 'test' )
-> willReturn ([
'types' => [ $type ],
]);
2022-12-08 04:55:19 -05:00
$this -> eventDispatcher -> expects ( $this -> never ()) -> method ( 'dispatchTyped' ) -> with ( new AppEnableEvent ( 'test' , [ 'group1' , 'group2' ]));
2016-01-14 09:23:07 -05:00
$manager -> enableAppForGroups ( 'test' , $groups );
}
2014-11-07 08:26:12 -05:00
public function testIsInstalledEnabled () {
2015-04-01 11:19:44 -04:00
$this -> appConfig -> setValue ( 'test' , 'enabled' , 'yes' );
$this -> assertTrue ( $this -> manager -> isInstalled ( 'test' ));
2014-11-07 08:26:12 -05:00
}
public function testIsInstalledDisabled () {
2015-04-01 11:19:44 -04:00
$this -> appConfig -> setValue ( 'test' , 'enabled' , 'no' );
$this -> assertFalse ( $this -> manager -> isInstalled ( 'test' ));
2014-11-07 08:26:12 -05:00
}
public function testIsInstalledEnabledForGroups () {
2015-04-01 11:19:44 -04:00
$this -> appConfig -> setValue ( 'test' , 'enabled' , '["foo"]' );
$this -> assertTrue ( $this -> manager -> isInstalled ( 'test' ));
2014-11-07 08:26:12 -05:00
}
2016-07-14 07:49:18 -04:00
private function newUser ( $uid ) {
2019-02-22 07:07:26 -05:00
$user = $this -> createMock ( IUser :: class );
$user -> method ( 'getUID' )
-> willReturn ( $uid );
2016-07-14 07:49:18 -04:00
2019-02-22 07:07:26 -05:00
return $user ;
2016-07-14 07:49:18 -04:00
}
2014-11-07 08:26:12 -05:00
public function testIsEnabledForUserEnabled () {
2015-04-01 11:19:44 -04:00
$this -> appConfig -> setValue ( 'test' , 'enabled' , 'yes' );
2016-07-14 07:49:18 -04:00
$user = $this -> newUser ( 'user1' );
2015-04-01 11:19:44 -04:00
$this -> assertTrue ( $this -> manager -> isEnabledForUser ( 'test' , $user ));
2014-11-07 08:26:12 -05:00
}
public function testIsEnabledForUserDisabled () {
2015-04-01 11:19:44 -04:00
$this -> appConfig -> setValue ( 'test' , 'enabled' , 'no' );
2016-07-14 07:49:18 -04:00
$user = $this -> newUser ( 'user1' );
2015-04-01 11:19:44 -04:00
$this -> assertFalse ( $this -> manager -> isEnabledForUser ( 'test' , $user ));
2014-11-07 08:26:12 -05:00
}
2016-11-17 06:30:52 -05:00
public function testGetAppPath () {
$this -> assertEquals ( \OC :: $SERVERROOT . '/apps/files' , $this -> manager -> getAppPath ( 'files' ));
}
2020-01-22 15:14:36 -05:00
public function testGetAppPathSymlink () {
$fakeAppDirname = sha1 ( uniqid ( 'test' , true ));
$fakeAppPath = sys_get_temp_dir () . '/' . $fakeAppDirname ;
$fakeAppLink = \OC :: $SERVERROOT . '/' . $fakeAppDirname ;
mkdir ( $fakeAppPath );
if ( symlink ( $fakeAppPath , $fakeAppLink ) === false ) {
$this -> markTestSkipped ( 'Failed to create symlink' );
}
// Use the symlink as the app path
\OC :: $APPSROOTS [] = [
'path' => $fakeAppLink ,
'url' => \OC :: $WEBROOT . '/' . $fakeAppDirname ,
'writable' => false ,
];
$fakeTestAppPath = $fakeAppPath . '/' . 'test-test-app' ;
mkdir ( $fakeTestAppPath );
$generatedAppPath = $this -> manager -> getAppPath ( 'test-test-app' );
rmdir ( $fakeTestAppPath );
unlink ( $fakeAppLink );
rmdir ( $fakeAppPath );
$this -> assertEquals ( $fakeAppLink . '/test-test-app' , $generatedAppPath );
}
2016-11-17 06:30:52 -05:00
public function testGetAppPathFail () {
$this -> expectException ( AppPathNotFoundException :: class );
$this -> manager -> getAppPath ( 'testnotexisting' );
}
2014-11-07 08:26:12 -05:00
public function testIsEnabledForUserEnabledForGroup () {
2016-07-14 07:49:18 -04:00
$user = $this -> newUser ( 'user1' );
2015-04-01 11:19:44 -04:00
$this -> groupManager -> expects ( $this -> once ())
2014-11-07 08:26:12 -05:00
-> method ( 'getUserGroupIds' )
-> with ( $user )
2020-03-26 04:30:18 -04:00
-> willReturn ([ 'foo' , 'bar' ]);
2014-11-07 08:26:12 -05:00
2015-04-01 11:19:44 -04:00
$this -> appConfig -> setValue ( 'test' , 'enabled' , '["foo"]' );
$this -> assertTrue ( $this -> manager -> isEnabledForUser ( 'test' , $user ));
2014-11-07 08:26:12 -05:00
}
public function testIsEnabledForUserDisabledForGroup () {
2016-07-14 07:49:18 -04:00
$user = $this -> newUser ( 'user1' );
2015-04-01 11:19:44 -04:00
$this -> groupManager -> expects ( $this -> once ())
2014-11-07 08:26:12 -05:00
-> method ( 'getUserGroupIds' )
-> with ( $user )
2020-03-26 04:30:18 -04:00
-> willReturn ([ 'bar' ]);
2014-11-07 08:26:12 -05:00
2015-04-01 11:19:44 -04:00
$this -> appConfig -> setValue ( 'test' , 'enabled' , '["foo"]' );
$this -> assertFalse ( $this -> manager -> isEnabledForUser ( 'test' , $user ));
2014-11-07 08:26:12 -05:00
}
public function testIsEnabledForUserLoggedOut () {
2015-04-01 11:19:44 -04:00
$this -> appConfig -> setValue ( 'test' , 'enabled' , '["foo"]' );
2017-03-20 05:21:08 -04:00
$this -> assertFalse ( $this -> manager -> isEnabledForUser ( 'test' ));
2014-11-07 08:26:12 -05:00
}
public function testIsEnabledForUserLoggedIn () {
2016-07-14 07:49:18 -04:00
$user = $this -> newUser ( 'user1' );
2014-11-07 08:26:12 -05:00
2015-04-01 11:19:44 -04:00
$this -> userSession -> expects ( $this -> once ())
2014-11-07 08:26:12 -05:00
-> method ( 'getUser' )
2020-03-25 17:21:27 -04:00
-> willReturn ( $user );
2015-04-01 11:19:44 -04:00
$this -> groupManager -> expects ( $this -> once ())
2014-11-07 08:26:12 -05:00
-> method ( 'getUserGroupIds' )
-> with ( $user )
2020-03-26 04:30:18 -04:00
-> willReturn ([ 'foo' , 'bar' ]);
2014-11-07 08:26:12 -05:00
2015-04-01 11:19:44 -04:00
$this -> appConfig -> setValue ( 'test' , 'enabled' , '["foo"]' );
$this -> assertTrue ( $this -> manager -> isEnabledForUser ( 'test' ));
2014-11-07 08:26:12 -05:00
}
2015-02-02 08:47:29 -05:00
public function testGetInstalledApps () {
2015-04-01 11:19:44 -04:00
$this -> appConfig -> setValue ( 'test1' , 'enabled' , 'yes' );
$this -> appConfig -> setValue ( 'test2' , 'enabled' , 'no' );
$this -> appConfig -> setValue ( 'test3' , 'enabled' , '["foo"]' );
2016-09-19 13:43:47 -04:00
$apps = [
2018-06-29 04:46:09 -04:00
'cloud_federation_api' ,
2016-09-19 13:43:47 -04:00
'dav' ,
'federatedfilesharing' ,
'files' ,
2016-11-17 06:14:13 -05:00
'lookup_server_connector' ,
2017-05-20 14:58:36 -04:00
'oauth2' ,
2016-09-19 13:43:47 -04:00
'provisioning_api' ,
2019-09-17 10:33:27 -04:00
'settings' ,
2016-09-19 13:43:47 -04:00
'test1' ,
'test3' ,
2022-10-14 09:25:02 -04:00
'theming' ,
2016-09-19 13:43:47 -04:00
'twofactor_backupcodes' ,
2019-12-10 09:08:19 -05:00
'viewer' ,
2016-09-19 13:43:47 -04:00
'workflowengine' ,
];
2016-09-02 06:53:44 -04:00
$this -> assertEquals ( $apps , $this -> manager -> getInstalledApps ());
2015-02-02 08:47:29 -05:00
}
public function testGetAppsForUser () {
2016-07-14 07:49:18 -04:00
$user = $this -> newUser ( 'user1' );
2015-04-01 11:19:44 -04:00
$this -> groupManager -> expects ( $this -> any ())
2015-02-02 08:47:29 -05:00
-> method ( 'getUserGroupIds' )
-> with ( $user )
2020-03-26 04:30:18 -04:00
-> willReturn ([ 'foo' , 'bar' ]);
2015-02-02 08:47:29 -05:00
2015-04-01 11:19:44 -04:00
$this -> appConfig -> setValue ( 'test1' , 'enabled' , 'yes' );
$this -> appConfig -> setValue ( 'test2' , 'enabled' , 'no' );
$this -> appConfig -> setValue ( 'test3' , 'enabled' , '["foo"]' );
$this -> appConfig -> setValue ( 'test4' , 'enabled' , '["asd"]' );
2016-09-02 06:53:44 -04:00
$enabled = [
2018-06-29 04:46:09 -04:00
'cloud_federation_api' ,
2016-09-02 06:53:44 -04:00
'dav' ,
'federatedfilesharing' ,
'files' ,
2016-11-17 06:14:13 -05:00
'lookup_server_connector' ,
2017-05-20 14:58:36 -04:00
'oauth2' ,
2016-09-19 13:43:47 -04:00
'provisioning_api' ,
2019-09-17 10:33:27 -04:00
'settings' ,
2016-09-02 06:53:44 -04:00
'test1' ,
'test3' ,
2022-10-14 09:25:02 -04:00
'theming' ,
2016-09-02 06:53:44 -04:00
'twofactor_backupcodes' ,
2019-12-10 09:08:19 -05:00
'viewer' ,
2017-05-20 14:58:36 -04:00
'workflowengine' ,
2016-09-02 06:53:44 -04:00
];
$this -> assertEquals ( $enabled , $this -> manager -> getEnabledAppsForUser ( $user ));
2015-02-02 08:47:29 -05:00
}
2015-07-07 06:12:54 -04:00
public function testGetAppsNeedingUpgrade () {
2019-09-05 06:55:24 -04:00
/** @var AppManager|MockObject $manager */
2017-03-20 05:21:08 -04:00
$manager = $this -> getMockBuilder ( AppManager :: class )
2024-03-06 05:13:29 -05:00
-> setConstructorArgs ([
$this -> userSession ,
$this -> config ,
$this -> groupManager ,
$this -> cacheFactory ,
$this -> eventDispatcher ,
$this -> logger ,
])
-> onlyMethods ([ 'getAppInfo' ])
2015-07-07 06:12:54 -04:00
-> getMock ();
$appInfos = [
2018-06-29 04:46:09 -04:00
'cloud_federation_api' => [ 'id' => 'cloud_federation_api' ],
2015-11-23 07:13:26 -05:00
'dav' => [ 'id' => 'dav' ],
'files' => [ 'id' => 'files' ],
2016-02-04 06:07:25 -05:00
'federatedfilesharing' => [ 'id' => 'federatedfilesharing' ],
2016-09-19 13:43:47 -04:00
'provisioning_api' => [ 'id' => 'provisioning_api' ],
2016-11-17 06:14:13 -05:00
'lookup_server_connector' => [ 'id' => 'lookup_server_connector' ],
2015-08-20 05:14:30 -04:00
'test1' => [ 'id' => 'test1' , 'version' => '1.0.1' , 'requiremax' => '9.0.0' ],
2015-07-07 06:12:54 -04:00
'test2' => [ 'id' => 'test2' , 'version' => '1.0.0' , 'requiremin' => '8.2.0' ],
'test3' => [ 'id' => 'test3' , 'version' => '1.2.4' , 'requiremin' => '9.0.0' ],
2015-08-20 05:14:30 -04:00
'test4' => [ 'id' => 'test4' , 'version' => '3.0.0' , 'requiremin' => '8.1.0' ],
2015-07-07 06:12:54 -04:00
'testnoversion' => [ 'id' => 'testnoversion' , 'requiremin' => '8.2.0' ],
2019-09-17 10:33:27 -04:00
'settings' => [ 'id' => 'settings' ],
2022-10-14 09:25:02 -04:00
'theming' => [ 'id' => 'theming' ],
2016-09-02 06:53:44 -04:00
'twofactor_backupcodes' => [ 'id' => 'twofactor_backupcodes' ],
2019-12-10 09:08:19 -05:00
'viewer' => [ 'id' => 'viewer' ],
2016-07-26 05:16:34 -04:00
'workflowengine' => [ 'id' => 'workflowengine' ],
2017-05-20 14:58:36 -04:00
'oauth2' => [ 'id' => 'oauth2' ],
2015-07-07 06:12:54 -04:00
];
2017-03-20 05:21:08 -04:00
$manager -> expects ( $this -> any ())
2015-07-07 06:12:54 -04:00
-> method ( 'getAppInfo' )
2020-03-25 17:21:27 -04:00
-> willReturnCallback (
2020-04-09 07:53:40 -04:00
function ( $appId ) use ( $appInfos ) {
2015-07-07 06:12:54 -04:00
return $appInfos [ $appId ];
}
2020-03-25 17:21:27 -04:00
);
2015-07-07 06:12:54 -04:00
$this -> appConfig -> setValue ( 'test1' , 'enabled' , 'yes' );
$this -> appConfig -> setValue ( 'test1' , 'installed_version' , '1.0.0' );
$this -> appConfig -> setValue ( 'test2' , 'enabled' , 'yes' );
$this -> appConfig -> setValue ( 'test2' , 'installed_version' , '1.0.0' );
$this -> appConfig -> setValue ( 'test3' , 'enabled' , 'yes' );
$this -> appConfig -> setValue ( 'test3' , 'installed_version' , '1.0.0' );
2015-08-20 05:14:30 -04:00
$this -> appConfig -> setValue ( 'test4' , 'enabled' , 'yes' );
$this -> appConfig -> setValue ( 'test4' , 'installed_version' , '2.4.0' );
2015-07-07 06:12:54 -04:00
2017-03-20 05:21:08 -04:00
$apps = $manager -> getAppsNeedingUpgrade ( '8.2.0' );
2015-07-07 06:12:54 -04:00
$this -> assertCount ( 2 , $apps );
$this -> assertEquals ( 'test1' , $apps [ 0 ][ 'id' ]);
2015-08-20 05:14:30 -04:00
$this -> assertEquals ( 'test4' , $apps [ 1 ][ 'id' ]);
2015-07-07 06:12:54 -04:00
}
public function testGetIncompatibleApps () {
2019-09-05 06:55:24 -04:00
/** @var AppManager|MockObject $manager */
2017-03-20 05:21:08 -04:00
$manager = $this -> getMockBuilder ( AppManager :: class )
2024-03-06 05:13:29 -05:00
-> setConstructorArgs ([
$this -> userSession ,
$this -> config ,
$this -> groupManager ,
$this -> cacheFactory ,
$this -> eventDispatcher ,
$this -> logger ,
])
-> onlyMethods ([ 'getAppInfo' ])
2015-07-07 06:12:54 -04:00
-> getMock ();
$appInfos = [
2018-06-29 04:46:09 -04:00
'cloud_federation_api' => [ 'id' => 'cloud_federation_api' ],
2015-11-23 07:13:26 -05:00
'dav' => [ 'id' => 'dav' ],
'files' => [ 'id' => 'files' ],
2016-02-04 06:07:25 -05:00
'federatedfilesharing' => [ 'id' => 'federatedfilesharing' ],
2016-09-19 13:43:47 -04:00
'provisioning_api' => [ 'id' => 'provisioning_api' ],
2016-11-17 06:14:13 -05:00
'lookup_server_connector' => [ 'id' => 'lookup_server_connector' ],
2015-07-07 06:12:54 -04:00
'test1' => [ 'id' => 'test1' , 'version' => '1.0.1' , 'requiremax' => '8.0.0' ],
'test2' => [ 'id' => 'test2' , 'version' => '1.0.0' , 'requiremin' => '8.2.0' ],
'test3' => [ 'id' => 'test3' , 'version' => '1.2.4' , 'requiremin' => '9.0.0' ],
2019-09-17 10:33:27 -04:00
'settings' => [ 'id' => 'settings' ],
2015-07-07 06:12:54 -04:00
'testnoversion' => [ 'id' => 'testnoversion' , 'requiremin' => '8.2.0' ],
2022-10-14 09:25:02 -04:00
'theming' => [ 'id' => 'theming' ],
2016-09-02 06:53:44 -04:00
'twofactor_backupcodes' => [ 'id' => 'twofactor_backupcodes' ],
2016-07-26 05:16:34 -04:00
'workflowengine' => [ 'id' => 'workflowengine' ],
2017-05-20 14:58:36 -04:00
'oauth2' => [ 'id' => 'oauth2' ],
2019-12-10 09:08:19 -05:00
'viewer' => [ 'id' => 'viewer' ],
2015-07-07 06:12:54 -04:00
];
2017-03-20 05:21:08 -04:00
$manager -> expects ( $this -> any ())
2015-07-07 06:12:54 -04:00
-> method ( 'getAppInfo' )
2020-03-25 17:21:27 -04:00
-> willReturnCallback (
2020-04-09 07:53:40 -04:00
function ( $appId ) use ( $appInfos ) {
2015-07-07 06:12:54 -04:00
return $appInfos [ $appId ];
}
2020-03-25 17:21:27 -04:00
);
2015-07-07 06:12:54 -04:00
$this -> appConfig -> setValue ( 'test1' , 'enabled' , 'yes' );
$this -> appConfig -> setValue ( 'test2' , 'enabled' , 'yes' );
$this -> appConfig -> setValue ( 'test3' , 'enabled' , 'yes' );
2017-03-20 05:21:08 -04:00
$apps = $manager -> getIncompatibleApps ( '8.2.0' );
2015-07-07 06:12:54 -04:00
$this -> assertCount ( 2 , $apps );
$this -> assertEquals ( 'test1' , $apps [ 0 ][ 'id' ]);
$this -> assertEquals ( 'test3' , $apps [ 1 ][ 'id' ]);
}
2019-06-25 09:20:06 -04:00
public function testGetEnabledAppsForGroup () {
$group = $this -> createMock ( IGroup :: class );
$group -> expects ( $this -> any ())
-> method ( 'getGID' )
2020-03-25 17:21:27 -04:00
-> willReturn ( 'foo' );
2019-06-25 09:20:06 -04:00
$this -> appConfig -> setValue ( 'test1' , 'enabled' , 'yes' );
$this -> appConfig -> setValue ( 'test2' , 'enabled' , 'no' );
$this -> appConfig -> setValue ( 'test3' , 'enabled' , '["foo"]' );
$this -> appConfig -> setValue ( 'test4' , 'enabled' , '["asd"]' );
$enabled = [
'cloud_federation_api' ,
'dav' ,
'federatedfilesharing' ,
'files' ,
'lookup_server_connector' ,
'oauth2' ,
'provisioning_api' ,
2019-09-17 10:33:27 -04:00
'settings' ,
2019-06-25 09:20:06 -04:00
'test1' ,
'test3' ,
2022-10-14 09:25:02 -04:00
'theming' ,
2019-06-25 09:20:06 -04:00
'twofactor_backupcodes' ,
2019-12-10 09:08:19 -05:00
'viewer' ,
2019-06-25 09:20:06 -04:00
'workflowengine' ,
];
$this -> assertEquals ( $enabled , $this -> manager -> getEnabledAppsForGroup ( $group ));
}
public function testGetAppRestriction () {
$this -> appConfig -> setValue ( 'test1' , 'enabled' , 'yes' );
$this -> appConfig -> setValue ( 'test2' , 'enabled' , 'no' );
$this -> appConfig -> setValue ( 'test3' , 'enabled' , '["foo"]' );
$this -> assertEquals ([], $this -> manager -> getAppRestriction ( 'test1' ));
$this -> assertEquals ([], $this -> manager -> getAppRestriction ( 'test2' ));
$this -> assertEquals ([ 'foo' ], $this -> manager -> getAppRestriction ( 'test3' ));
}
2023-03-29 16:36:45 -04:00
public function provideDefaultApps () : array {
return [
// none specified, default to files
[
'' ,
2023-09-26 08:59:05 -04:00
'' ,
'{}' ,
2023-09-25 08:21:23 -04:00
true ,
2023-03-29 16:36:45 -04:00
'files' ,
],
2023-09-25 08:21:23 -04:00
// none specified, without fallback
[
'' ,
'' ,
'{}' ,
false ,
'' ,
],
2023-03-29 16:36:45 -04:00
// unexisting or inaccessible app specified, default to files
[
'unexist' ,
2023-09-26 08:59:05 -04:00
'' ,
'{}' ,
2023-09-25 08:21:23 -04:00
true ,
2023-03-29 16:36:45 -04:00
'files' ,
],
2023-09-25 08:21:23 -04:00
// unexisting or inaccessible app specified, without fallbacks
[
'unexist' ,
'' ,
'{}' ,
false ,
'' ,
],
2023-03-29 16:36:45 -04:00
// non-standard app
[
'settings' ,
2023-09-26 08:59:05 -04:00
'' ,
'{}' ,
2023-09-25 08:21:23 -04:00
true ,
'settings' ,
],
// non-standard app, without fallback
[
'settings' ,
'' ,
'{}' ,
false ,
2023-03-29 16:36:45 -04:00
'settings' ,
],
// non-standard app with fallback
[
'unexist,settings' ,
2023-09-26 08:59:05 -04:00
'' ,
'{}' ,
2023-09-25 08:21:23 -04:00
true ,
2023-09-26 08:59:05 -04:00
'settings' ,
],
2023-11-09 10:41:21 -05:00
// system default app and user apporder
[
// system default is settings
'unexist,settings' ,
'' ,
// apporder says default app is files (order is lower)
'{"files_id":{"app":"files","order":1},"settings_id":{"app":"settings","order":2}}' ,
true ,
// system default should override apporder
'settings'
],
2023-09-26 08:59:05 -04:00
// user-customized defaultapp
2023-09-25 08:21:23 -04:00
[
'' ,
'files' ,
'' ,
true ,
'files' ,
],
// user-customized defaultapp with systemwide
[
'unexist,settings' ,
'files' ,
'' ,
true ,
'files' ,
],
// user-customized defaultapp with system wide and apporder
2023-09-26 08:59:05 -04:00
[
'unexist,settings' ,
'files' ,
2023-11-09 10:41:21 -05:00
'{"settings_id":{"app":"settings","order":1},"files_id":{"app":"files","order":2}}' ,
2023-09-25 08:21:23 -04:00
true ,
2023-09-26 08:59:05 -04:00
'files' ,
],
// user-customized apporder fallback
[
'' ,
'' ,
2023-11-09 10:41:21 -05:00
'{"settings_id":{"app":"settings","order":1},"files":{"app":"files","order":2}}' ,
2023-09-25 08:21:23 -04:00
true ,
2023-03-29 16:36:45 -04:00
'settings' ,
],
2023-11-09 10:41:21 -05:00
// user-customized apporder fallback with missing app key (entries added by closures does not always have an app key set (Nextcloud 27 spreed app for example))
[
'' ,
'' ,
'{"spreed":{"order":1},"files":{"app":"files","order":2}}' ,
true ,
'files' ,
],
2023-09-25 08:21:23 -04:00
// user-customized apporder, but called without fallback
[
'' ,
'' ,
2023-11-08 08:15:25 -05:00
'{"settings":{"app":"settings","order":1},"files":{"app":"files","order":2}}' ,
2023-09-25 08:21:23 -04:00
false ,
'' ,
],
2023-11-09 10:41:21 -05:00
// user-customized apporder with an app that has multiple routes
[
'' ,
'' ,
'{"settings_id":{"app":"settings","order":1},"settings_id_2":{"app":"settings","order":3},"id_files":{"app":"files","order":2}}' ,
true ,
'settings' ,
],
2023-03-29 16:36:45 -04:00
];
}
/**
* @ dataProvider provideDefaultApps
*/
2023-09-25 08:21:23 -04:00
public function testGetDefaultAppForUser ( $defaultApps , $userDefaultApps , $userApporder , $withFallbacks , $expectedApp ) {
2023-03-29 16:36:45 -04:00
$user = $this -> newUser ( 'user1' );
$this -> userSession -> expects ( $this -> once ())
-> method ( 'getUser' )
-> willReturn ( $user );
$this -> config -> expects ( $this -> once ())
-> method ( 'getSystemValueString' )
-> with ( 'defaultapp' , $this -> anything ())
-> willReturn ( $defaultApps );
2023-09-26 08:59:05 -04:00
$this -> config -> expects ( $this -> atLeastOnce ())
2023-08-14 11:03:56 -04:00
-> method ( 'getUserValue' )
2023-09-26 08:59:05 -04:00
-> willReturnMap ([
[ 'user1' , 'core' , 'defaultapp' , '' , $userDefaultApps ],
[ 'user1' , 'core' , 'apporder' , '[]' , $userApporder ],
]);
2023-08-14 11:03:56 -04:00
2023-09-25 08:21:23 -04:00
$this -> assertEquals ( $expectedApp , $this -> manager -> getDefaultAppForUser ( null , $withFallbacks ));
2023-03-29 16:36:45 -04:00
}
2024-07-13 10:51:16 -04:00
public static function isBackendRequiredDataProvider () : array {
return [
// backend available
[
'caldav' ,
[ 'app1' => [ 'caldav' ]],
true ,
],
[
'caldav' ,
[ 'app1' => [], 'app2' => [ 'foo' ], 'app3' => [ 'caldav' ]],
true ,
],
// backend not available
[
'caldav' ,
[ 'app3' => [], 'app1' => [ 'foo' ], 'app2' => [ 'bar' , 'baz' ]],
false ,
],
// no app available
[
'caldav' ,
[],
false ,
],
];
}
/**
* @ dataProvider isBackendRequiredDataProvider
*/
public function testIsBackendRequired (
string $backend ,
array $appBackends ,
bool $expected ,
) : void {
$appInfoData = array_map (
static fn ( array $backends ) => [ 'dependencies' => [ 'backend' => $backends ]],
$appBackends ,
);
$reflection = new \ReflectionClass ( $this -> manager );
$property = $reflection -> getProperty ( 'appInfos' );
$property -> setValue ( $this -> manager , $appInfoData );
$this -> assertEquals ( $expected , $this -> manager -> isBackendRequired ( $backend ));
}
2014-11-07 08:26:12 -05:00
}