diff options
Diffstat (limited to 'tests')
23 files changed, 1844 insertions, 1546 deletions
diff --git a/tests/Core/Controller/LoginControllerTest.php b/tests/Core/Controller/LoginControllerTest.php index ff50ac98fbd..d16b9b114f3 100644 --- a/tests/Core/Controller/LoginControllerTest.php +++ b/tests/Core/Controller/LoginControllerTest.php @@ -322,6 +322,8 @@ class LoginControllerTest extends TestCase { $this->userSession->expects($this->never()) ->method('createSessionToken'); + $this->userSession->expects($this->never()) + ->method('createRememberMeToken'); $this->config->expects($this->never()) ->method('deleteUserValue'); @@ -363,7 +365,7 @@ class LoginControllerTest extends TestCase { ->with($user, $password); $this->userSession->expects($this->once()) ->method('createSessionToken') - ->with($this->request, $user->getUID(), $user, $password); + ->with($this->request, $user->getUID(), $user, $password, false); $this->twoFactorManager->expects($this->once()) ->method('isTwoFactorAuthenticated') ->with($user) @@ -371,11 +373,63 @@ class LoginControllerTest extends TestCase { $this->config->expects($this->once()) ->method('deleteUserValue') ->with('uid', 'core', 'lostpassword'); + $this->userSession->expects($this->never()) + ->method('createRememberMeToken'); $expected = new \OCP\AppFramework\Http\RedirectResponse($indexPageUrl); $this->assertEquals($expected, $this->loginController->tryLogin($user, $password, null)); } + public function testLoginWithValidCredentialsAndRememberMe() { + /** @var IUser | \PHPUnit_Framework_MockObject_MockObject $user */ + $user = $this->getMockBuilder('\OCP\IUser')->getMock(); + $user->expects($this->any()) + ->method('getUID') + ->will($this->returnValue('uid')); + $password = 'secret'; + $indexPageUrl = \OC_Util::getDefaultPageUrl(); + + $this->request + ->expects($this->exactly(2)) + ->method('getRemoteAddress') + ->willReturn('192.168.0.1'); + $this->request + ->expects($this->once()) + ->method('passesCSRFCheck') + ->willReturn(true); + $this->throttler + ->expects($this->once()) + ->method('sleepDelay') + ->with('192.168.0.1'); + $this->throttler + ->expects($this->once()) + ->method('getDelay') + ->with('192.168.0.1') + ->willReturn(200); + $this->userManager->expects($this->once()) + ->method('checkPassword') + ->will($this->returnValue($user)); + $this->userSession->expects($this->once()) + ->method('login') + ->with($user, $password); + $this->userSession->expects($this->once()) + ->method('createSessionToken') + ->with($this->request, $user->getUID(), $user, $password, true); + $this->twoFactorManager->expects($this->once()) + ->method('isTwoFactorAuthenticated') + ->with($user) + ->will($this->returnValue(false)); + $this->config->expects($this->once()) + ->method('deleteUserValue') + ->with('uid', 'core', 'lostpassword'); + $this->userSession->expects($this->once()) + ->method('createRememberMeToken') + ->with($user); + + $expected = new \OCP\AppFramework\Http\RedirectResponse($indexPageUrl); + $this->assertEquals($expected, $this->loginController->tryLogin($user, $password, null, true)); + } + public function testLoginWithoutPassedCsrfCheckAndNotLoggedIn() { /** @var IUser | \PHPUnit_Framework_MockObject_MockObject $user */ $user = $this->getMockBuilder('\OCP\IUser')->getMock(); @@ -408,6 +462,8 @@ class LoginControllerTest extends TestCase { ->will($this->returnValue(false)); $this->config->expects($this->never()) ->method('deleteUserValue'); + $this->userSession->expects($this->never()) + ->method('createRememberMeToken'); $expected = new \OCP\AppFramework\Http\RedirectResponse(\OC_Util::getDefaultPageUrl()); $this->assertEquals($expected, $this->loginController->tryLogin('Jane', $password, $originalUrl)); @@ -450,6 +506,8 @@ class LoginControllerTest extends TestCase { ->will($this->returnValue($redirectUrl)); $this->config->expects($this->never()) ->method('deleteUserValue'); + $this->userSession->expects($this->never()) + ->method('createRememberMeToken'); $expected = new \OCP\AppFramework\Http\RedirectResponse($redirectUrl); $this->assertEquals($expected, $this->loginController->tryLogin('Jane', $password, $originalUrl)); @@ -488,7 +546,7 @@ class LoginControllerTest extends TestCase { ->will($this->returnValue($user)); $this->userSession->expects($this->once()) ->method('createSessionToken') - ->with($this->request, $user->getUID(), 'Jane', $password); + ->with($this->request, $user->getUID(), 'Jane', $password, false); $this->userSession->expects($this->once()) ->method('isLoggedIn') ->with() @@ -540,7 +598,7 @@ class LoginControllerTest extends TestCase { ->with('john@doe.com', $password); $this->userSession->expects($this->once()) ->method('createSessionToken') - ->with($this->request, $user->getUID(), 'john@doe.com', $password); + ->with($this->request, $user->getUID(), 'john@doe.com', $password, false); $this->twoFactorManager->expects($this->once()) ->method('isTwoFactorAuthenticated') ->with($user) @@ -564,6 +622,8 @@ class LoginControllerTest extends TestCase { $this->config->expects($this->once()) ->method('deleteUserValue') ->with('john', 'core', 'lostpassword'); + $this->userSession->expects($this->never()) + ->method('createRememberMeToken'); $expected = new RedirectResponse($challengeUrl); $this->assertEquals($expected, $this->loginController->tryLogin('john@doe.com', $password, null)); @@ -605,7 +665,7 @@ class LoginControllerTest extends TestCase { ->with('john@doe.com', $password); $this->userSession->expects($this->once()) ->method('createSessionToken') - ->with($this->request, $user->getUID(), 'john@doe.com', $password); + ->with($this->request, $user->getUID(), 'john@doe.com', $password, false); $this->twoFactorManager->expects($this->once()) ->method('isTwoFactorAuthenticated') ->with($user) @@ -628,6 +688,8 @@ class LoginControllerTest extends TestCase { $this->config->expects($this->once()) ->method('deleteUserValue') ->with('john', 'core', 'lostpassword'); + $this->userSession->expects($this->never()) + ->method('createRememberMeToken'); $expected = new RedirectResponse($challengeUrl); $this->assertEquals($expected, $this->loginController->tryLogin('john@doe.com', $password, null)); @@ -680,6 +742,8 @@ class LoginControllerTest extends TestCase { ->with('login', '192.168.0.1', ['user' => 'john@doe.com']); $this->config->expects($this->never()) ->method('deleteUserValue'); + $this->userSession->expects($this->never()) + ->method('createRememberMeToken'); $expected = new RedirectResponse(''); $this->assertEquals($expected, $this->loginController->tryLogin('john@doe.com', 'just wrong', null)); diff --git a/tests/Settings/Controller/AppSettingsControllerTest.php b/tests/Settings/Controller/AppSettingsControllerTest.php index 9dcc55e135b..a3e4a6fd828 100644 --- a/tests/Settings/Controller/AppSettingsControllerTest.php +++ b/tests/Settings/Controller/AppSettingsControllerTest.php @@ -2,6 +2,7 @@ /** * @author Lukas Reschke <lukas@owncloud.com> * + * @copyright Copyright (c) 2016, Lukas Reschke <lukas@statuscode.ch> * @copyright Copyright (c) 2015, ownCloud, Inc. * @license AGPL-3.0 * @@ -21,18 +22,19 @@ namespace Tests\Settings\Controller; +use OC\App\AppStore\Fetcher\AppFetcher; +use OC\App\AppStore\Fetcher\CategoryFetcher; use OC\Settings\Controller\AppSettingsController; use OCP\AppFramework\Http\ContentSecurityPolicy; -use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\TemplateResponse; +use OCP\L10N\IFactory; use Test\TestCase; use OCP\IRequest; use OCP\IL10N; use OCP\IConfig; -use OCP\ICache; use OCP\INavigationManager; use OCP\App\IAppManager; -use OC\OCSClient; /** * Class AppSettingsControllerTest @@ -42,95 +44,53 @@ use OC\OCSClient; class AppSettingsControllerTest extends TestCase { /** @var AppSettingsController */ private $appSettingsController; - /** @var IRequest */ + /** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */ private $request; - /** @var IL10N */ + /** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */ private $l10n; - /** @var IConfig */ + /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ private $config; - /** @var ICache */ - private $cache; - /** @var INavigationManager */ + /** @var INavigationManager|\PHPUnit_Framework_MockObject_MockObject */ private $navigationManager; - /** @var IAppManager */ + /** @var IAppManager|\PHPUnit_Framework_MockObject_MockObject */ private $appManager; - /** @var OCSClient */ - private $ocsClient; + /** @var CategoryFetcher|\PHPUnit_Framework_MockObject_MockObject */ + private $categoryFetcher; + /** @var AppFetcher|\PHPUnit_Framework_MockObject_MockObject */ + private $appFetcher; + /** @var IFactory|\PHPUnit_Framework_MockObject_MockObject */ + private $l10nFactory; public function setUp() { parent::setUp(); - $this->request = $this->getMockBuilder('\OCP\IRequest') - ->disableOriginalConstructor()->getMock(); - $this->l10n = $this->getMockBuilder('\OCP\IL10N') - ->disableOriginalConstructor()->getMock(); + $this->request = $this->createMock(IRequest::class); + $this->l10n = $this->createMock(IL10N::class); $this->l10n->expects($this->any()) ->method('t') ->will($this->returnArgument(0)); - $this->config = $this->getMockBuilder('\OCP\IConfig') - ->disableOriginalConstructor()->getMock(); - $cacheFactory = $this->getMockBuilder('\OCP\ICacheFactory') - ->disableOriginalConstructor()->getMock(); - $this->cache = $this->getMockBuilder('\OCP\ICache') - ->disableOriginalConstructor()->getMock(); - $cacheFactory - ->expects($this->once()) - ->method('create') - ->with('settings') - ->will($this->returnValue($this->cache)); - - $this->navigationManager = $this->getMockBuilder('\OCP\INavigationManager') - ->disableOriginalConstructor()->getMock(); - $this->appManager = $this->getMockBuilder('\OCP\App\IAppManager') - ->disableOriginalConstructor()->getMock(); - $this->ocsClient = $this->getMockBuilder('\OC\OCSClient') - ->disableOriginalConstructor()->getMock(); + $this->config = $this->createMock(IConfig::class); + $this->navigationManager = $this->createMock(INavigationManager::class); + $this->appManager = $this->createMock(IAppManager::class); + $this->categoryFetcher = $this->createMock(CategoryFetcher::class); + $this->appFetcher = $this->createMock(AppFetcher::class); + $this->l10nFactory = $this->createMock(IFactory::class); $this->appSettingsController = new AppSettingsController( 'settings', $this->request, $this->l10n, $this->config, - $cacheFactory, $this->navigationManager, $this->appManager, - $this->ocsClient + $this->categoryFetcher, + $this->appFetcher, + $this->l10nFactory ); } - public function testChangeExperimentalConfigStateTrue() { - $this->config - ->expects($this->once()) - ->method('setSystemValue') - ->with('appstore.experimental.enabled', true); - $this->appManager - ->expects($this->once()) - ->method('clearAppsCache'); - $this->assertEquals(new DataResponse(), $this->appSettingsController->changeExperimentalConfigState(true)); - } - - public function testChangeExperimentalConfigStateFalse() { - $this->config - ->expects($this->once()) - ->method('setSystemValue') - ->with('appstore.experimental.enabled', false); - $this->appManager - ->expects($this->once()) - ->method('clearAppsCache'); - $this->assertEquals(new DataResponse(), $this->appSettingsController->changeExperimentalConfigState(false)); - } - - public function testListCategoriesCached() { - $this->cache - ->expects($this->exactly(2)) - ->method('get') - ->with('listCategories') - ->will($this->returnValue(['CachedArray'])); - $this->assertSame(['CachedArray'], $this->appSettingsController->listCategories()); - } - - public function testListCategoriesNotCachedWithoutAppStore() { - $expected = [ + public function testListCategories() { + $expected = new JSONResponse([ [ 'id' => 0, 'ident' => 'enabled', @@ -141,115 +101,69 @@ class AppSettingsControllerTest extends TestCase { 'ident' => 'disabled', 'displayName' => 'Not enabled', ], - ]; - $this->cache - ->expects($this->once()) - ->method('get') - ->with('listCategories') - ->will($this->returnValue(null)); - $this->cache - ->expects($this->once()) - ->method('set') - ->with('listCategories', $expected, 3600); - - - $this->assertSame($expected, $this->appSettingsController->listCategories()); - } - - public function testListCategoriesNotCachedWithAppStore() { - $expected = [ [ - 'id' => 0, - 'ident' => 'enabled', - 'displayName' => 'Enabled', + 'id' => 'auth', + 'ident' => 'auth', + 'displayName' => 'Authentication & authorization', ], [ - 'id' => 1, - 'ident' => 'disabled', - 'displayName' => 'Not enabled', + 'id' => 'customization', + 'ident' => 'customization', + 'displayName' => 'Customization', ], [ - 'id' => 0, - 'ident' => 'tools', - 'displayName' => 'Tools', + 'id' => 'files', + 'ident' => 'files', + 'displayName' => 'Files', ], [ - 'id' => 1, - 'ident' => 'games', - 'displayName' => 'Games', + 'id' => 'integration', + 'ident' => 'integration', + 'displayName' => 'Integration', ], [ - 'id' => 2, - 'ident' => 'productivity', - 'displayName' => 'Productivity', + 'id' => 'monitoring', + 'ident' => 'monitoring', + 'displayName' => 'Monitoring', ], [ - 'id' => 3, + 'id' => 'multimedia', 'ident' => 'multimedia', 'displayName' => 'Multimedia', ], - ]; + [ + 'id' => 'office', + 'ident' => 'office', + 'displayName' => 'Office & text', + ], + [ + 'id' => 'organization', + 'ident' => 'organization', + 'displayName' => 'Organization', + ], + [ + 'id' => 'social', + 'ident' => 'social', + 'displayName' => 'Social & communication', + ], + [ + 'id' => 'tools', + 'ident' => 'tools', + 'displayName' => 'Tools', + ], + ]); - $this->cache + $this->categoryFetcher ->expects($this->once()) ->method('get') - ->with('listCategories') - ->will($this->returnValue(null)); - $this->cache - ->expects($this->once()) - ->method('set') - ->with('listCategories', $expected, 3600); - - $this->ocsClient - ->expects($this->once()) - ->method('isAppStoreEnabled') - ->will($this->returnValue(true)); - $this->ocsClient - ->expects($this->once()) - ->method('getCategories') - ->will($this->returnValue( - [ - 'ownCloud Tools', - 'Games', - 'ownCloud Productivity', - 'Multimedia', - ] - )); + ->willReturn(json_decode('[{"id":"auth","translations":{"cs":{"name":"Autentizace & autorizace","description":"Aplikace poskytující služby dodatečného ověření nebo přihlášení"},"hu":{"name":"Azonosítás és hitelesítés","description":"Apps that provide additional authentication or authorization services"},"de":{"name":"Authentifizierung & Authorisierung","description":"Apps die zusätzliche Autentifizierungs- oder Autorisierungsdienste bereitstellen"},"nl":{"name":"Authenticatie & authorisatie","description":"Apps die aanvullende authenticatie- en autorisatiediensten bieden"},"nb":{"name":"Pålogging og tilgangsstyring","description":"Apper for å tilby ekstra pålogging eller tilgangsstyring"},"it":{"name":"Autenticazione e autorizzazione","description":"Apps that provide additional authentication or authorization services"},"fr":{"name":"Authentification et autorisations","description":"Applications qui fournissent des services d\'authentification ou d\'autorisations additionnels."},"ru":{"name":"Аутентификация и авторизация","description":"Apps that provide additional authentication or authorization services"},"en":{"name":"Authentication & authorization","description":"Apps that provide additional authentication or authorization services"}}},{"id":"customization","translations":{"cs":{"name":"Přizpůsobení","description":"Motivy a aplikace měnící rozvržení a uživatelské rozhraní"},"it":{"name":"Personalizzazione","description":"Applicazioni di temi, modifiche della disposizione e UX"},"de":{"name":"Anpassung","description":"Apps zur Änderung von Themen, Layout und Benutzererfahrung"},"hu":{"name":"Személyre szabás","description":"Témák, elrendezések felhasználói felület módosító alkalmazások"},"nl":{"name":"Maatwerk","description":"Thema\'s, layout en UX aanpassingsapps"},"nb":{"name":"Tilpasning","description":"Apper for å endre Tema, utseende og brukeropplevelse"},"fr":{"name":"Personalisation","description":"Thèmes, apparence et applications modifiant l\'expérience utilisateur"},"ru":{"name":"Настройка","description":"Themes, layout and UX change apps"},"en":{"name":"Customization","description":"Themes, layout and UX change apps"}}},{"id":"files","translations":{"cs":{"name":"Soubory","description":"Aplikace rozšiřující správu souborů nebo aplikaci Soubory"},"it":{"name":"File","description":"Applicazioni di gestione dei file ed estensione dell\'applicazione FIle"},"de":{"name":"Dateien","description":"Dateimanagement sowie Erweiterungs-Apps für die Dateien-App"},"hu":{"name":"Fájlok","description":"Fájl kezelő és kiegészítő alkalmazások"},"nl":{"name":"Bestanden","description":"Bestandebeheer en uitbreidingen van bestand apps"},"nb":{"name":"Filer","description":"Apper for filhåndtering og filer"},"fr":{"name":"Fichiers","description":"Applications de gestion de fichiers et extensions à l\'application Fichiers"},"ru":{"name":"Файлы","description":"Расширение: файлы и управление файлами"},"en":{"name":"Files","description":"File management and Files app extension apps"}}},{"id":"integration","translations":{"it":{"name":"Integrazione","description":"Applicazioni che collegano Nextcloud con altri servizi e piattaforme"},"hu":{"name":"Integráció","description":"Apps that connect Nextcloud with other services and platforms"},"nl":{"name":"Integratie","description":"Apps die Nextcloud verbinden met andere services en platformen"},"nb":{"name":"Integrasjon","description":"Apper som kobler Nextcloud med andre tjenester og plattformer"},"de":{"name":"Integration","description":"Apps die Nextcloud mit anderen Diensten und Plattformen verbinden"},"cs":{"name":"Propojení","description":"Aplikace propojující NextCloud s dalšími službami a platformami"},"fr":{"name":"Intégration","description":"Applications qui connectent Nextcloud avec d\'autres services et plateformes"},"ru":{"name":"Интеграция","description":"Приложения, соединяющие Nextcloud с другими службами и платформами"},"en":{"name":"Integration","description":"Apps that connect Nextcloud with other services and platforms"}}},{"id":"monitoring","translations":{"nb":{"name":"Overvåking","description":"Apper for statistikk, systemdiagnose og aktivitet"},"it":{"name":"Monitoraggio","description":"Applicazioni di statistiche, diagnostica di sistema e attività"},"de":{"name":"Überwachung","description":"Datenstatistiken-, Systemdiagnose- und Aktivitäten-Apps"},"hu":{"name":"Megfigyelés","description":"Data statistics, system diagnostics and activity apps"},"nl":{"name":"Monitoren","description":"Gegevensstatistiek, systeem diagnose en activiteit apps"},"cs":{"name":"Kontrola","description":"Datové statistiky, diagnózy systému a aktivity aplikací"},"fr":{"name":"Surveillance","description":"Applications de statistiques sur les données, de diagnostics systèmes et d\'activité."},"ru":{"name":"Мониторинг","description":"Статистика данных, диагностика системы и активность приложений"},"en":{"name":"Monitoring","description":"Data statistics, system diagnostics and activity apps"}}},{"id":"multimedia","translations":{"nb":{"name":"Multimedia","description":"Apper for lyd, film og bilde"},"it":{"name":"Multimedia","description":"Applicazioni per audio, video e immagini"},"de":{"name":"Multimedia","description":"Audio-, Video- und Bilder-Apps"},"hu":{"name":"Multimédia","description":"Hang, videó és kép alkalmazások"},"nl":{"name":"Multimedia","description":"Audio, video en afbeelding apps"},"en":{"name":"Multimedia","description":"Audio, video and picture apps"},"cs":{"name":"Multimédia","description":"Aplikace audia, videa a obrázků"},"fr":{"name":"Multimédia","description":"Applications audio, vidéo et image"},"ru":{"name":"Мультимедиа","description":"Приложение аудио, видео и изображения"}}},{"id":"office","translations":{"nb":{"name":"Kontorstøtte og tekst","description":"Apper for Kontorstøtte og tekstbehandling"},"it":{"name":"Ufficio e testo","description":"Applicazione per ufficio ed elaborazione di testi"},"de":{"name":"Büro & Text","description":"Büro- und Textverarbeitungs-Apps"},"hu":{"name":"Iroda és szöveg","description":"Irodai és szöveg feldolgozó alkalmazások"},"nl":{"name":"Office & tekst","description":"Office en tekstverwerkingsapps"},"cs":{"name":"Kancelář a text","description":"Aplikace pro kancelář a zpracování textu"},"fr":{"name":"Bureautique & texte","description":"Applications de bureautique et de traitement de texte"},"en":{"name":"Office & text","description":"Office and text processing apps"}}},{"id":"organization","translations":{"nb":{"name":"Organisering","description":"Apper for tidsstyring, oppgaveliste og kalender"},"it":{"name":"Organizzazione","description":"Applicazioni di gestione del tempo, elenco delle cose da fare e calendario"},"hu":{"name":"Szervezet","description":"Időbeosztás, teendő lista és naptár alkalmazások"},"nl":{"name":"Organisatie","description":"Tijdmanagement, takenlijsten en agenda apps"},"cs":{"name":"Organizace","description":"Aplikace pro správu času, plánování a kalendáře"},"de":{"name":"Organisation","description":"Time management, Todo list and calendar apps"},"fr":{"name":"Organisation","description":"Applications de gestion du temps, de listes de tâches et d\'agendas"},"ru":{"name":"Организация","description":"Приложения по управлению временем, список задач и календарь"},"en":{"name":"Organization","description":"Time management, Todo list and calendar apps"}}},{"id":"social","translations":{"nb":{"name":"Sosialt og kommunikasjon","description":"Apper for meldinger, kontakthåndtering og sosiale medier"},"it":{"name":"Sociale e comunicazione","description":"Applicazioni di messaggistica, gestione dei contatti e reti sociali"},"de":{"name":"Kommunikation","description":"Nachrichten-, Kontaktverwaltungs- und Social-Media-Apps"},"hu":{"name":"Közösségi és kommunikáció","description":"Üzenetküldő, kapcsolat kezelő és közösségi média alkalmazások"},"nl":{"name":"Sociaal & communicatie","description":"Messaging, contactbeheer en social media apps"},"cs":{"name":"Sociální sítě a komunikace","description":"Aplikace pro zasílání zpráv, správu kontaktů a sociální sítě"},"fr":{"name":"Social & communication","description":"Applications de messagerie, de gestion de contacts et de réseaux sociaux"},"ru":{"name":"Социальное и связь","description":"Общение, управление контактами и социальное медиа-приложение"},"en":{"name":"Social & communication","description":"Messaging, contact management and social media apps"}}},{"id":"tools","translations":{"nb":{"name":"Verktøy","description":"Alt annet"},"it":{"name":"Strumenti","description":"Tutto il resto"},"hu":{"name":"Eszközök","description":"Minden más"},"nl":{"name":"Tools","description":"De rest"},"de":{"name":"Werkzeuge","description":"Alles Andere"},"en":{"name":"Tools","description":"Everything else"},"cs":{"name":"Nástroje","description":"Vše ostatní"},"fr":{"name":"Outils","description":"Tout le reste"},"ru":{"name":"Приложения","description":"Что-то еще"}}}]', true)); - $this->assertSame($expected, $this->appSettingsController->listCategories()); + $this->assertEquals($expected, $this->appSettingsController->listCategories()); } public function testViewApps() { $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstore.experimental.enabled', false); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(true)); - $this->navigationManager ->expects($this->once()) - ->method('setActiveEntry') - ->with('core_apps'); - - $policy = new ContentSecurityPolicy(); - $policy->addAllowedImageDomain('https://apps.owncloud.com'); - - $expected = new TemplateResponse('settings', 'apps', ['experimentalEnabled' => false, 'category' => 'enabled', 'appstoreEnabled' => true], 'user'); - $expected->setContentSecurityPolicy($policy); - - $this->assertEquals($expected, $this->appSettingsController->viewApps()); - } - - public function testViewAppsNotEnabled() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstore.experimental.enabled', false); - $this->config - ->expects($this->at(1)) ->method('getSystemValue') ->with('appstoreenabled', true) ->will($this->returnValue(true)); @@ -259,21 +173,17 @@ class AppSettingsControllerTest extends TestCase { ->with('core_apps'); $policy = new ContentSecurityPolicy(); - $policy->addAllowedImageDomain('https://apps.owncloud.com'); + $policy->addAllowedImageDomain('https://usercontent.apps.nextcloud.com'); - $expected = new TemplateResponse('settings', 'apps', ['experimentalEnabled' => false, 'category' => 'disabled', 'appstoreEnabled' => true], 'user'); + $expected = new TemplateResponse('settings', 'apps', ['category' => 'enabled', 'appstoreEnabled' => true], 'user'); $expected->setContentSecurityPolicy($policy); - $this->assertEquals($expected, $this->appSettingsController->viewApps('disabled')); + $this->assertEquals($expected, $this->appSettingsController->viewApps()); } public function testViewAppsAppstoreNotEnabled() { $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstore.experimental.enabled', false); - $this->config - ->expects($this->at(1)) + ->expects($this->once()) ->method('getSystemValue') ->with('appstoreenabled', true) ->will($this->returnValue(false)); @@ -283,9 +193,9 @@ class AppSettingsControllerTest extends TestCase { ->with('core_apps'); $policy = new ContentSecurityPolicy(); - $policy->addAllowedImageDomain('https://apps.owncloud.com'); + $policy->addAllowedImageDomain('https://usercontent.apps.nextcloud.com'); - $expected = new TemplateResponse('settings', 'apps', ['experimentalEnabled' => false, 'category' => 'enabled', 'appstoreEnabled' => false], 'user'); + $expected = new TemplateResponse('settings', 'apps', ['category' => 'enabled', 'appstoreEnabled' => false], 'user'); $expected->setContentSecurityPolicy($policy); $this->assertEquals($expected, $this->appSettingsController->viewApps()); diff --git a/tests/data/testapp.tar.gz b/tests/data/testapp.tar.gz Binary files differnew file mode 100644 index 00000000000..b9184c8c378 --- /dev/null +++ b/tests/data/testapp.tar.gz diff --git a/tests/data/testapp1.tar.gz b/tests/data/testapp1.tar.gz Binary files differnew file mode 100644 index 00000000000..f864edb2a6d --- /dev/null +++ b/tests/data/testapp1.tar.gz diff --git a/tests/enable_all.php b/tests/enable_all.php index afea5c89665..655597be7c8 100644 --- a/tests/enable_all.php +++ b/tests/enable_all.php @@ -10,7 +10,7 @@ require_once __DIR__.'/../lib/base.php'; function enableApp($app) { try { - OC_App::enable($app); + (new \OC_App())->enable($app); } catch (Exception $e) { echo $e; } diff --git a/tests/lib/App/AppStore/Fetcher/AppFetcherTest.php b/tests/lib/App/AppStore/Fetcher/AppFetcherTest.php new file mode 100644 index 00000000000..3b0418a7eba --- /dev/null +++ b/tests/lib/App/AppStore/Fetcher/AppFetcherTest.php @@ -0,0 +1,39 @@ +<?php +/** + * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch> + * + * @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 Test\App\AppStore\Fetcher; + +use OC\App\AppStore\Fetcher\AppFetcher; + +class AppFetcherTest extends FetcherBase { + public function setUp() { + parent::setUp(); + $this->fileName = 'apps.json'; + $this->endpoint = 'https://apps.nextcloud.com/api/v1/platform/9.2.0/apps.json'; + + $this->fetcher = new AppFetcher( + $this->appData, + $this->clientService, + $this->timeFactory, + $this->config + ); + } +} diff --git a/tests/lib/App/AppStore/Fetcher/CategoryFetcherTest.php b/tests/lib/App/AppStore/Fetcher/CategoryFetcherTest.php new file mode 100644 index 00000000000..db4354119a0 --- /dev/null +++ b/tests/lib/App/AppStore/Fetcher/CategoryFetcherTest.php @@ -0,0 +1,38 @@ +<?php +/** + * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch> + * + * @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 Test\App\AppStore\Fetcher; + +use OC\App\AppStore\Fetcher\CategoryFetcher; + +class CategoryFetcherTest extends FetcherBase { + public function setUp() { + parent::setUp(); + $this->fileName = 'categories.json'; + $this->endpoint = 'https://apps.nextcloud.com/api/v1/categories.json'; + + $this->fetcher = new CategoryFetcher( + $this->appData, + $this->clientService, + $this->timeFactory + ); + } +} diff --git a/tests/lib/App/AppStore/Fetcher/FetcherBase.php b/tests/lib/App/AppStore/Fetcher/FetcherBase.php new file mode 100644 index 00000000000..66df81f1b2e --- /dev/null +++ b/tests/lib/App/AppStore/Fetcher/FetcherBase.php @@ -0,0 +1,246 @@ +<?php +/** + * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch> + * + * @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 Test\App\AppStore\Fetcher; + +use OC\App\AppStore\Fetcher\AppFetcher; +use OC\App\AppStore\Fetcher\Fetcher; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\Files\IAppData; +use OCP\Files\NotFoundException; +use OCP\Files\SimpleFS\ISimpleFile; +use OCP\Files\SimpleFS\ISimpleFolder; +use OCP\Http\Client\IClient; +use OCP\Http\Client\IClientService; +use OCP\Http\Client\IResponse; +use OCP\IConfig; +use Test\TestCase; + +abstract class FetcherBase extends TestCase { + /** @var IAppData|\PHPUnit_Framework_MockObject_MockObject */ + protected $appData; + /** @var IClientService|\PHPUnit_Framework_MockObject_MockObject */ + protected $clientService; + /** @var ITimeFactory|\PHPUnit_Framework_MockObject_MockObject */ + protected $timeFactory; + /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ + protected $config; + /** @var Fetcher */ + protected $fetcher; + /** @var string */ + protected $fileName; + /** @var string */ + protected $endpoint; + + public function setUp() { + parent::setUp(); + $this->appData = $this->createMock(IAppData::class); + $this->clientService = $this->createMock(IClientService::class); + $this->timeFactory = $this->createMock(ITimeFactory::class); + $this->config = $this->createMock(IConfig::class); + } + + public function testGetWithAlreadyExistingFileAndUpToDateTimestamp() { + $folder = $this->createMock(ISimpleFolder::class); + $file = $this->createMock(ISimpleFile::class); + $this->appData + ->expects($this->once()) + ->method('getFolder') + ->with('/') + ->willReturn($folder); + $folder + ->expects($this->once()) + ->method('getFile') + ->with($this->fileName) + ->willReturn($file); + $file + ->expects($this->once()) + ->method('getContent') + ->willReturn('{"timestamp":1200,"data":[{"id":"MyApp"}]}'); + $this->timeFactory + ->expects($this->once()) + ->method('getTime') + ->willReturn(1499); + + $expected = [ + [ + 'id' => 'MyApp', + ], + ]; + $this->assertSame($expected, $this->fetcher->get()); + } + + public function testGetWithNotExistingFileAndUpToDateTimestamp() { + $folder = $this->createMock(ISimpleFolder::class); + $file = $this->createMock(ISimpleFile::class); + $this->appData + ->expects($this->once()) + ->method('getFolder') + ->with('/') + ->willReturn($folder); + $folder + ->expects($this->at(0)) + ->method('getFile') + ->with($this->fileName) + ->willThrowException(new NotFoundException()); + $folder + ->expects($this->at(1)) + ->method('newFile') + ->with($this->fileName) + ->willReturn($file); + $client = $this->createMock(IClient::class); + $this->clientService + ->expects($this->once()) + ->method('newClient') + ->willReturn($client); + $response = $this->createMock(IResponse::class); + $client + ->expects($this->once()) + ->method('get') + ->with($this->endpoint) + ->willReturn($response); + $response + ->expects($this->once()) + ->method('getBody') + ->willReturn('[{"id":"MyNewApp", "foo": "foo"}, {"id":"bar"}]'); + $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1502}'; + $file + ->expects($this->at(0)) + ->method('putContent') + ->with($fileData); + $file + ->expects($this->at(1)) + ->method('getContent') + ->willReturn($fileData); + $this->timeFactory + ->expects($this->at(0)) + ->method('getTime') + ->willReturn(1502); + + $expected = [ + [ + 'id' => 'MyNewApp', + 'foo' => 'foo', + ], + [ + 'id' => 'bar', + ], + ]; + $this->assertSame($expected, $this->fetcher->get()); + } + + public function testGetWithAlreadyExistingFileAndOutdatedTimestamp() { + $folder = $this->createMock(ISimpleFolder::class); + $file = $this->createMock(ISimpleFile::class); + $this->appData + ->expects($this->once()) + ->method('getFolder') + ->with('/') + ->willReturn($folder); + $folder + ->expects($this->once()) + ->method('getFile') + ->with($this->fileName) + ->willReturn($file); + $file + ->expects($this->at(0)) + ->method('getContent') + ->willReturn('{"timestamp":1200,"data":{"MyApp":{"id":"MyApp"}}}'); + $this->timeFactory + ->expects($this->at(0)) + ->method('getTime') + ->willReturn(1501); + $client = $this->createMock(IClient::class); + $this->clientService + ->expects($this->once()) + ->method('newClient') + ->willReturn($client); + $response = $this->createMock(IResponse::class); + $client + ->expects($this->once()) + ->method('get') + ->with($this->endpoint) + ->willReturn($response); + $response + ->expects($this->once()) + ->method('getBody') + ->willReturn('[{"id":"MyNewApp", "foo": "foo"}, {"id":"bar"}]'); + $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1502}'; + $file + ->expects($this->at(1)) + ->method('putContent') + ->with($fileData); + $file + ->expects($this->at(2)) + ->method('getContent') + ->willReturn($fileData); + $this->timeFactory + ->expects($this->at(1)) + ->method('getTime') + ->willReturn(1502); + + $expected = [ + [ + 'id' => 'MyNewApp', + 'foo' => 'foo', + ], + [ + 'id' => 'bar', + ], + ]; + $this->assertSame($expected, $this->fetcher->get()); + } + + public function testGetWithExceptionInClient() { + $folder = $this->createMock(ISimpleFolder::class); + $file = $this->createMock(ISimpleFile::class); + $this->appData + ->expects($this->once()) + ->method('getFolder') + ->with('/') + ->willReturn($folder); + $folder + ->expects($this->once()) + ->method('getFile') + ->with($this->fileName) + ->willReturn($file); + $file + ->expects($this->at(0)) + ->method('getContent') + ->willReturn('{"timestamp":1200,"data":{"MyApp":{"id":"MyApp"}}}'); + $this->timeFactory + ->expects($this->at(0)) + ->method('getTime') + ->willReturn(1501); + $client = $this->createMock(IClient::class); + $this->clientService + ->expects($this->once()) + ->method('newClient') + ->willReturn($client); + $client + ->expects($this->once()) + ->method('get') + ->with($this->endpoint) + ->willThrowException(new \Exception()); + + $this->assertSame([], $this->fetcher->get()); + } +} diff --git a/tests/lib/App/AppStore/Version/VersionParserTest.php b/tests/lib/App/AppStore/Version/VersionParserTest.php new file mode 100644 index 00000000000..ebfa98ade39 --- /dev/null +++ b/tests/lib/App/AppStore/Version/VersionParserTest.php @@ -0,0 +1,99 @@ +<?php +/** + * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch> + * + * @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 Test\App\AppStore\Version; + +use OC\App\AppStore\Version\Version; +use OC\App\AppStore\Version\VersionParser; +use Test\TestCase; + +class VersionParserTest extends TestCase { + /** @var VersionParser */ + private $versionParser; + + public function setUp() { + parent::setUp(); + $this->versionParser = new VersionParser(); + } + + /** + * @return array + */ + public function versionProvider() { + return [ + [ + '*', + new Version('', ''), + ], + [ + '<=8.1.2', + new Version('', '8.1.2'), + ], + [ + '<=9', + new Version('', '9'), + ], + [ + '>=9.3.2', + new Version('9.3.2', ''), + ], + [ + '>=8.1.2 <=9.3.2', + new Version('8.1.2', '9.3.2'), + ], + [ + '>=8.2 <=9.1', + new Version('8.2', '9.1'), + ], + [ + '>=9 <=11', + new Version('9', '11'), + ], + ]; + } + + /** + * @dataProvider versionProvider + * + * @param string $input + * @param Version $expected + */ + public function testGetVersion($input, + Version $expected) { + $this->assertEquals($expected, $this->versionParser->getVersion($input)); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage Version cannot be parsed: BogusVersion + */ + public function testGetVersionException() { + $this->versionParser->getVersion('BogusVersion'); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage Version cannot be parsed: >=8.2 <=9.1a + */ + public function testGetVersionExceptionWithMultiple() { + $this->versionParser->getVersion('>=8.2 <=9.1a'); + } +} diff --git a/tests/lib/App/AppStore/Version/VersionTest.php b/tests/lib/App/AppStore/Version/VersionTest.php new file mode 100644 index 00000000000..969c96a57a8 --- /dev/null +++ b/tests/lib/App/AppStore/Version/VersionTest.php @@ -0,0 +1,37 @@ +<?php +/** + * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch> + * + * @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 Test\App\AppStore\Version; + +use OC\App\AppStore\Version\Version; +use Test\TestCase; + +class VersionTest extends TestCase { + public function testGetMinimumVersion() { + $version = new Version('9', '10'); + $this->assertSame('9', $version->getMinimumVersion()); + } + + public function testGetMaximumVersion() { + $version = new Version('9', '10'); + $this->assertSame('10', $version->getMaximumVersion()); + } +} diff --git a/tests/lib/App/DependencyAnalyzerTest.php b/tests/lib/App/DependencyAnalyzerTest.php index c41829b796b..fd44954eaf4 100644 --- a/tests/lib/App/DependencyAnalyzerTest.php +++ b/tests/lib/App/DependencyAnalyzerTest.php @@ -1,9 +1,10 @@ <?php - /** * @author Thomas Müller + * @author Lukas Reschke * @copyright 2014 Thomas Müller deepdiver@owncloud.com - * later. + * @copyright 2016 Lukas Reschke <lukas@statuscode.ch> + * * See the COPYING-README file. */ @@ -187,7 +188,7 @@ class DependencyAnalyzerTest extends TestCase { 'dependencies' => array() ); if (!is_null($oc)) { - $app['dependencies']['owncloud'] = $oc; + $app['dependencies'] = $oc; } $missing = $this->analyser->analyze($app); @@ -200,18 +201,216 @@ class DependencyAnalyzerTest extends TestCase { * @return array */ function providesOC() { - return array( + return [ // no version -> no missing dependency - array(array(), null), - array(array(), array('@attributes' => array('min-version' => '8', 'max-version' => '8'))), - array(array(), array('@attributes' => array('min-version' => '8.0', 'max-version' => '8.0'))), - array(array(), array('@attributes' => array('min-version' => '8.0.2', 'max-version' => '8.0.2'))), - array(array('Server version 8.0.3 or higher is required.'), array('@attributes' => array('min-version' => '8.0.3'))), - array(array('Server version 9 or higher is required.'), array('@attributes' => array('min-version' => '9'))), - array(array('Server version 10 or higher is required.'), array('@attributes' => array('min-version' => '9.1'))), - array(array('Server version 11 or higher is required.'), array('@attributes' => array('min-version' => '9.2'))), - [['Server version 8.0.1 or lower is required.'], ['@attributes' => ['max-version' => '8.0.1']]], - ); + [ + [], + null, + ], + [ + [], + [ + 'nextcloud' => [ + '@attributes' => [ + 'min-version' => '8', + 'max-version' => '8', + ], + ], + ], + ], + [ + [], + [ + 'nextcloud' => [ + '@attributes' => [ + 'min-version' => '8.0', + 'max-version' => '8.0', + ], + ], + ], + ], + [ + [], + [ + 'nextcloud' => [ + '@attributes' => [ + 'min-version' => '8.0.2', + 'max-version' => '8.0.2' + ], + ], + ], + ], + [ + [ + 'Server version 8.0.3 or higher is required.', + ], + [ + 'nextcloud' => [ + '@attributes' => [ + 'min-version' => '8.0.3' + ], + ], + ], + ], + [ + [ + 'Server version 9 or higher is required.', + ], + [ + 'nextcloud' => [ + '@attributes' => [ + 'min-version' => '9' + ], + ], + ], + ], + [ + [ + 'Server version 10 or higher is required.', + ], + [ + 'nextcloud' => [ + '@attributes' => [ + 'min-version' => '10' + ], + ], + 'owncloud' => [ + '@attributes' => [ + 'min-version' => '9' + ], + ], + ], + ], + [ + [ + 'Server version 10 or higher is required.', + ], + [ + 'nextcloud' => [ + '@attributes' => [ + 'min-version' => '9.1', + ], + ], + ], + ], + [ + [ + 'Server version 11 or higher is required.', + ], + [ + 'nextcloud' => [ + '@attributes' => [ + 'min-version' => '9.2', + ], + ], + ], + ], + [ + [ + 'Server version 8.0.1 or lower is required.', + ], + [ + 'nextcloud' => [ + '@attributes' => [ + 'max-version' => '8.0.1', + ], + ], + ], + ], + [ + [], + [ + 'owncloud' => [ + '@attributes' => [ + 'min-version' => '8', + 'max-version' => '8', + ], + ], + ], + ], + [ + [], + [ + 'owncloud' => [ + '@attributes' => [ + 'min-version' => '8.0', + 'max-version' => '8.0', + ], + ], + ], + ], + [ + [], + [ + 'owncloud' => [ + '@attributes' => [ + 'min-version' => '8.0.2', + 'max-version' => '8.0.2' + ], + ], + ], + ], + [ + [ + 'Server version 8.0.3 or higher is required.', + ], + [ + 'owncloud' => [ + '@attributes' => [ + 'min-version' => '8.0.3' + ], + ], + ], + ], + [ + [ + 'Server version 9 or higher is required.', + ], + [ + 'owncloud' => [ + '@attributes' => [ + 'min-version' => '9' + ], + ], + ], + ], + [ + [ + 'Server version 10 or higher is required.', + ], + [ + 'owncloud' => [ + '@attributes' => [ + 'min-version' => '9.1', + ], + ], + ], + ], + [ + [ + 'Server version 11 or higher is required.', + ], + [ + 'owncloud' => [ + '@attributes' => [ + 'min-version' => '9.2', + ], + ], + ], + ], + [ + [ + 'Server version 8.0.1 or lower is required.', + ], + [ + 'owncloud' => [ + '@attributes' => [ + 'max-version' => '8.0.1', + ], + ], + ], + ], + ]; } /** diff --git a/tests/lib/AppTest.php b/tests/lib/AppTest.php index b7263adb78b..971d86cf6a4 100644 --- a/tests/lib/AppTest.php +++ b/tests/lib/AppTest.php @@ -264,6 +264,40 @@ class AppTest extends \Test\TestCase { ), true ), + [ + '9.2.0.0', + [ + 'dependencies' => [ + 'owncloud' => [ + '@attributes' => [ + 'min-version' => '9.0', + 'max-version' => '9.1', + ], + ], + 'nextcloud' => [ + '@attributes' => [ + 'min-version' => '9.1', + 'max-version' => '9.2', + ], + ], + ], + ], + true + ], + [ + '9.2.0.0', + [ + 'dependencies' => [ + 'nextcloud' => [ + '@attributes' => [ + 'min-version' => '9.1', + 'max-version' => '9.2', + ], + ], + ], + ], + true + ], ); } diff --git a/tests/lib/Authentication/Token/DefaultTokenMapperTest.php b/tests/lib/Authentication/Token/DefaultTokenMapperTest.php index d71d9468477..418a4d14f62 100644 --- a/tests/lib/Authentication/Token/DefaultTokenMapperTest.php +++ b/tests/lib/Authentication/Token/DefaultTokenMapperTest.php @@ -130,6 +130,7 @@ class DefaultTokenMapperTest extends TestCase { $token->setName('Firefox on Android'); $token->setToken('1504445f1524fc801035448a95681a9378ba2e83930c814546c56e5d6ebde221198792fd900c88ed5ead0555780dad1ebce3370d7e154941cd5de87eb419899b'); $token->setType(IToken::TEMPORARY_TOKEN); + $token->setRemember(IToken::DO_NOT_REMEMBER); $token->setLastActivity($this->time - 60 * 60 * 24 * 3); $token->setLastCheck($this->time - 10); diff --git a/tests/lib/Authentication/Token/DefaultTokenProviderTest.php b/tests/lib/Authentication/Token/DefaultTokenProviderTest.php index 7f90cf051f4..5e4d4f94366 100644 --- a/tests/lib/Authentication/Token/DefaultTokenProviderTest.php +++ b/tests/lib/Authentication/Token/DefaultTokenProviderTest.php @@ -1,8 +1,8 @@ <?php - /** * @author Christoph Wurst <christoph@owncloud.com> * + * @copyright Copyright (c) 2016, Lukas Reschke <lukas@statuscode.ch> * @copyright Copyright (c) 2016, ownCloud, Inc. * @license AGPL-3.0 * @@ -25,7 +25,7 @@ namespace Test\Authentication\Token; use OC\Authentication\Token\DefaultToken; use OC\Authentication\Token\DefaultTokenProvider; use OC\Authentication\Token\IToken; -use OCP\AppFramework\Db\DoesNotExistException; +use OCP\AppFramework\Db\Mapper; use OCP\AppFramework\Utility\ITimeFactory; use OCP\IConfig; use OCP\ILogger; @@ -35,13 +35,19 @@ use Test\TestCase; class DefaultTokenProviderTest extends TestCase { - /** @var DefaultTokenProvider */ + /** @var DefaultTokenProvider|\PHPUnit_Framework_MockObject_MockObject */ private $tokenProvider; + /** @var Mapper|\PHPUnit_Framework_MockObject_MockObject */ private $mapper; + /** @var ICrypto|\PHPUnit_Framework_MockObject_MockObject */ private $crypto; + /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ private $config; + /** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */ private $logger; + /** @var ITimeFactory|\PHPUnit_Framework_MockObject_MockObject */ private $timeFactory; + /** @var int */ private $time; protected function setUp() { @@ -81,6 +87,7 @@ class DefaultTokenProviderTest extends TestCase { $toInsert->setName($name); $toInsert->setToken(hash('sha512', $token . '1f4h9s')); $toInsert->setType($type); + $toInsert->setRemember(IToken::DO_NOT_REMEMBER); $toInsert->setLastActivity($this->time); $this->config->expects($this->any()) @@ -95,7 +102,7 @@ class DefaultTokenProviderTest extends TestCase { ->method('insert') ->with($this->equalTo($toInsert)); - $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type); + $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER); $this->assertEquals($toInsert, $actual); } @@ -245,15 +252,128 @@ class DefaultTokenProviderTest extends TestCase { public function testInvalidateOldTokens() { $defaultSessionLifetime = 60 * 60 * 24; - $this->config->expects($this->once()) + $defaultRememberMeLifetime = 60 * 60 * 24 * 15; + $this->config->expects($this->exactly(2)) ->method('getSystemValue') - ->with('session_lifetime', $defaultSessionLifetime) - ->will($this->returnValue(150)); - $this->mapper->expects($this->once()) + ->will($this->returnValueMap([ + ['session_lifetime', $defaultSessionLifetime, 150], + ['remember_login_cookie_lifetime', $defaultRememberMeLifetime, 300], + ])); + $this->mapper->expects($this->at(0)) ->method('invalidateOld') ->with($this->time - 150); + $this->mapper->expects($this->at(1)) + ->method('invalidateOld') + ->with($this->time - 300); $this->tokenProvider->invalidateOldTokens(); } + public function testRenewSessionTokenWithoutPassword() { + $token = $this->getMockBuilder(DefaultToken::class) + ->disableOriginalConstructor() + ->setMethods(['getUID', 'getLoginName', 'getPassword', 'getName']) + ->getMock(); + $token + ->expects($this->at(0)) + ->method('getUID') + ->willReturn('UserUid'); + $token + ->expects($this->at(1)) + ->method('getLoginName') + ->willReturn('UserLoginName'); + $token + ->expects($this->at(2)) + ->method('getPassword') + ->willReturn(null); + $token + ->expects($this->at(3)) + ->method('getName') + ->willReturn('MyTokenName'); + $this->config + ->expects($this->exactly(2)) + ->method('getSystemValue') + ->with('secret') + ->willReturn('MyInstanceSecret'); + $this->mapper + ->expects($this->at(0)) + ->method('getToken') + ->with(hash('sha512', 'oldId' . 'MyInstanceSecret')) + ->willReturn($token); + $newToken = new DefaultToken(); + $newToken->setUid('UserUid'); + $newToken->setLoginName('UserLoginName'); + $newToken->setName('MyTokenName'); + $newToken->setToken(hash('sha512', 'newId' . 'MyInstanceSecret')); + $newToken->setType(IToken::TEMPORARY_TOKEN); + $newToken->setLastActivity(1313131); + $this->mapper + ->expects($this->at(1)) + ->method('insert') + ->with($newToken); + + $this->tokenProvider->renewSessionToken('oldId', 'newId'); + } + + public function testRenewSessionTokenWithPassword() { + $token = $this->getMockBuilder(DefaultToken::class) + ->disableOriginalConstructor() + ->setMethods(['getUID', 'getLoginName', 'getPassword', 'getName']) + ->getMock(); + $token + ->expects($this->at(0)) + ->method('getUID') + ->willReturn('UserUid'); + $token + ->expects($this->at(1)) + ->method('getLoginName') + ->willReturn('UserLoginName'); + $token + ->expects($this->at(2)) + ->method('getPassword') + ->willReturn('EncryptedPassword'); + $token + ->expects($this->at(3)) + ->method('getPassword') + ->willReturn('EncryptedPassword'); + $token + ->expects($this->at(4)) + ->method('getName') + ->willReturn('MyTokenName'); + $this->crypto + ->expects($this->any(0)) + ->method('decrypt') + ->with('EncryptedPassword', 'oldIdMyInstanceSecret') + ->willReturn('ClearTextPassword'); + $this->crypto + ->expects($this->any(1)) + ->method('encrypt') + ->with('ClearTextPassword', 'newIdMyInstanceSecret') + ->willReturn('EncryptedPassword'); + $this->config + ->expects($this->exactly(4)) + ->method('getSystemValue') + ->with('secret') + ->willReturn('MyInstanceSecret'); + $this->mapper + ->expects($this->at(0)) + ->method('getToken') + ->with(hash('sha512', 'oldId' . 'MyInstanceSecret')) + ->willReturn($token); + $newToken = new DefaultToken(); + $newToken->setUid('UserUid'); + $newToken->setLoginName('UserLoginName'); + $newToken->setName('MyTokenName'); + $newToken->setToken(hash('sha512', 'newId' . 'MyInstanceSecret')); + $newToken->setType(IToken::TEMPORARY_TOKEN); + $newToken->setLastActivity(1313131); + $newToken->setPassword('EncryptedPassword'); + $this->mapper + ->expects($this->at(1)) + ->method('insert') + ->with($newToken); + + $this->tokenProvider->renewSessionToken('oldId', 'newId'); + } + } diff --git a/tests/lib/Authentication/TwoFactorAuth/ManagerTest.php b/tests/lib/Authentication/TwoFactorAuth/ManagerTest.php index 72b70d817d2..52f3ca28500 100644 --- a/tests/lib/Authentication/TwoFactorAuth/ManagerTest.php +++ b/tests/lib/Authentication/TwoFactorAuth/ManagerTest.php @@ -233,8 +233,15 @@ class ManagerTest extends TestCase { ->with($this->user, $challenge) ->will($this->returnValue(true)); $this->session->expects($this->once()) + ->method('get') + ->with('two_factor_remember_login') + ->will($this->returnValue(false)); + $this->session->expects($this->at(1)) ->method('remove') ->with('two_factor_auth_uid'); + $this->session->expects($this->at(2)) + ->method('remove') + ->with('two_factor_remember_login'); $this->assertTrue($this->manager->verifyChallenge('email', $this->user, $challenge)); } @@ -304,11 +311,29 @@ class ManagerTest extends TestCase { ->method('getUID') ->will($this->returnValue('ferdinand')); - $this->session->expects($this->once()) + $this->session->expects($this->at(0)) + ->method('set') + ->with('two_factor_auth_uid', 'ferdinand'); + $this->session->expects($this->at(1)) + ->method('set') + ->with('two_factor_remember_login', true); + + $this->manager->prepareTwoFactorLogin($this->user, true); + } + + public function testPrepareTwoFactorLoginDontRemember() { + $this->user->expects($this->once()) + ->method('getUID') + ->will($this->returnValue('ferdinand')); + + $this->session->expects($this->at(0)) ->method('set') ->with('two_factor_auth_uid', 'ferdinand'); + $this->session->expects($this->at(1)) + ->method('set') + ->with('two_factor_remember_login', false); - $this->manager->prepareTwoFactorLogin($this->user); + $this->manager->prepareTwoFactorLogin($this->user, false); } } diff --git a/tests/lib/InstallerTest.php b/tests/lib/InstallerTest.php index e1c17b841a2..1212d3d7559 100644 --- a/tests/lib/InstallerTest.php +++ b/tests/lib/InstallerTest.php @@ -9,91 +9,572 @@ namespace Test; +use OC\App\AppStore\Fetcher\AppFetcher; +use OC\Archive\ZIP; use OC\Installer; +use OCP\Http\Client\IClient; +use OCP\Http\Client\IClientService; +use OCP\ILogger; +use OCP\ITempManager; class InstallerTest extends TestCase { private static $appid = 'testapp'; private $appstore; + /** @var AppFetcher|\PHPUnit_Framework_MockObject_MockObject */ + private $appFetcher; + /** @var IClientService|\PHPUnit_Framework_MockObject_MockObject */ + private $clientService; + /** @var ITempManager|\PHPUnit_Framework_MockObject_MockObject */ + private $tempManager; + /** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */ + private $logger; + + /** @var Installer */ + private $installer; protected function setUp() { parent::setUp(); + $this->appFetcher = $this->createMock(AppFetcher::class); + $this->clientService = $this->createMock(IClientService::class); + $this->tempManager = $this->createMock(ITempManager::class); + $this->logger = $this->createMock(ILogger::class); + $this->installer = new Installer( + $this->appFetcher, + $this->clientService, + $this->tempManager, + $this->logger + ); + $config = \OC::$server->getConfig(); $this->appstore = $config->setSystemValue('appstoreenabled', true); $config->setSystemValue('appstoreenabled', true); - Installer::removeApp(self::$appid); + $installer = new Installer( + \OC::$server->getAppFetcher(), + \OC::$server->getHTTPClientService(), + \OC::$server->getTempManager(), + \OC::$server->getLogger() + ); + $installer->removeApp(self::$appid); } protected function tearDown() { - Installer::removeApp(self::$appid); + $installer = new Installer( + \OC::$server->getAppFetcher(), + \OC::$server->getHTTPClientService(), + \OC::$server->getTempManager(), + \OC::$server->getLogger() + ); + $installer->removeApp(self::$appid); \OC::$server->getConfig()->setSystemValue('appstoreenabled', $this->appstore); parent::tearDown(); } public function testInstallApp() { - $pathOfTestApp = __DIR__; - $pathOfTestApp .= '/../data/'; - $pathOfTestApp .= 'testapp.zip'; - - $tmp = \OC::$server->getTempManager()->getTemporaryFile('.zip'); - \OC_Helper::copyr($pathOfTestApp, $tmp); - - $data = array( - 'path' => $tmp, - 'source' => 'path', - 'appdata' => [ - 'id' => 'Bar', - 'level' => 100, - ] - ); + // Extract app + $pathOfTestApp = __DIR__ . '/../data/testapp.zip'; + $tar = new ZIP($pathOfTestApp); + $tar->extract(\OC_App::getInstallPath()); - Installer::installApp($data); + // Install app + $installer = new Installer( + \OC::$server->getAppFetcher(), + \OC::$server->getHTTPClientService(), + \OC::$server->getTempManager(), + \OC::$server->getLogger() + ); + $installer->installApp(self::$appid); $isInstalled = Installer::isInstalled(self::$appid); - $this->assertTrue($isInstalled); + $installer->removeApp(self::$appid); } - public function testUpdateApp() { - $pathOfOldTestApp = __DIR__; - $pathOfOldTestApp .= '/../data/'; - $pathOfOldTestApp .= 'testapp.zip'; - - $oldTmp = \OC::$server->getTempManager()->getTemporaryFile('.zip'); - \OC_Helper::copyr($pathOfOldTestApp, $oldTmp); - - $oldData = array( - 'path' => $oldTmp, - 'source' => 'path', - 'appdata' => [ - 'id' => 'Bar', - 'level' => 100, - ] - ); + public function updateArrayProvider() { + return [ + // Update available + [ + [ + [ + 'id' => 'files', + 'releases' => [ + [ + 'version' => '1111.0' + ], + ], + ], + ], + '1111.0', + ], + // No update available + [ + [ + [ + 'id' => 'files', + 'releases' => [ + [ + 'version' => '1.0' + ], + ], + ], + ], + false, + ], + ]; + } - $pathOfNewTestApp = __DIR__; - $pathOfNewTestApp .= '/../data/'; - $pathOfNewTestApp .= 'testapp2.zip'; + /** + * @dataProvider updateArrayProvider + * @param array $appArray + * @param string|bool $updateAvailable + */ + public function testIsUpdateAvailable(array $appArray, $updateAvailable) { + $this->appFetcher + ->expects($this->once()) + ->method('get') + ->willReturn($appArray); - $newTmp = \OC::$server->getTempManager()->getTemporaryFile('.zip'); - \OC_Helper::copyr($pathOfNewTestApp, $newTmp); + $this->assertSame($updateAvailable, Installer::isUpdateAvailable('files', $this->appFetcher)); + } - $newData = array( - 'path' => $newTmp, - 'source' => 'path', - 'appdata' => [ - 'id' => 'Bar', - 'level' => 100, - ] - ); + /** + * @expectedException \Exception + * @expectedExceptionMessage Certificate "4112" has been revoked + */ + public function testDownloadAppWithRevokedCertificate() { + $appArray = [ + [ + 'id' => 'news', + 'certificate' => '-----BEGIN CERTIFICATE----- +MIIEAjCCAuoCAhAQMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD +VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI +MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB +dXRob3JpdHkwHhcNMTYxMDAzMTMyNDM3WhcNMjcwMTA5MTMyNDM3WjASMRAwDgYD +VQQDDAdwYXNzbWFuMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApEt+ +KZGs+WqdZkHZflzqk+ophYWB8qB47XCzy+xdTGPFM84/9wXltRPbcQQWJJl5aOx0 +FPbsyTGhIt/IYZ2Vl0XrDRJjsaxzPcrofrwpJ2tqforXjGohl6mZUBA0ESzFiPzT +SAZe8E14+Jk8rbF/ecrkqcWf2cTMV3Qfu9YvJo8WVs4lHc95r1F+Nalh/OLkHkzb +fYPno2Z5cco6U7BXunFQG2gqy3wWQwmlhDxh5fwrCoFzPWm7WhwSyK+eMoSDz+Vp +3kmtyijsqnda0zA9bfNzgW26czbJaObbnkdtDC2nfoAWXndlS/5YRI8yHd9miB5C +u1OC8LUWToDGNa9+FOxBSj7Nk6iyjbVfRXcTqThdkVZdOOPaBRMsL9R4UYywCbhA +yGNiQ0ahfXD8MZSb08rlQg8tAtcUZW1sYQcbtMGnu8OyC5J7N1efzv5mys4+9hBS +5ECeyCuQTuOkF4H/XS2BMSFZWF2xh7wzhMLca+5yauDW4i8baFEv74QTeY1DADgI +Lz29NJ6z9xYzEnPesjNrwIcJwIjV52EkdLTi+EIf83UjXLQdwDbLxu76qxqP7K0I +oMmwbl7UNA0wzq7nmgRhvqhow5RoCaSJjTz0EYQVSa1xelwiKeJiSKj2G9Mgt5Ms +Miuy3C3VAGvQJ2ocILPGOt54oVeNRFLpnCo1e3sCAwEAATANBgkqhkiG9w0BAQsF +AAOCAQEAkGYtg21rGpUVT/AokGUfI0PeyYAkcXKy2yuBAzfRk+uIXnRR0vK+OMpx +shBoYGR3JEGUHZcMTRh8wjAZ0wuyYlQONtJbFFF3bCfODXxCsw0Vm8/Ms+KCmE4Z +SyQafWEQf1sdqNw4VS4DYS2mlpDgAl+U9UY6HQKuT3+GFIxCsQSdS0GTaiYVKPVE +p/eKou739h+5dM4FEhIYZX+7PWlHmX6wPCFAjgNu3kiRGmF6LKmCNNXTySATEP86 +tczQMzLtVdTg5z8XMi//6TkAPxRPjYi8Vef/s2mLo7KystTmofxI/HZePSieJ9tj +gLgK8d8sKL60JMmKHN3boHrsThKBVA== +-----END CERTIFICATE-----', + ], + ]; + $this->appFetcher + ->expects($this->once()) + ->method('get') + ->willReturn($appArray); + + + $this->installer->downloadApp('news'); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage App with id news has a certificate not issued by a trusted Code Signing Authority + */ + public function testDownloadAppWithNotNextcloudCertificate() { + $appArray = [ + [ + 'id' => 'news', + 'certificate' => '-----BEGIN CERTIFICATE----- +MIID8TCCAdkCAhAAMA0GCSqGSIb3DQEBCwUAMG0xCzAJBgNVBAYTAlVTMQ8wDQYD +VQQIDAZCb3N0b24xFjAUBgNVBAoMDW93bkNsb3VkIEluYy4xNTAzBgNVBAMMLG93 +bkNsb3VkIENvZGUgU2lnbmluZyBJbnRlcm1lZGlhdGUgQXV0aG9yaXR5MB4XDTE2 +MDIwMzE3NTE0OVoXDTI2MDEzMTE3NTE0OVowDzENMAsGA1UEAwwEY29yZTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPHdSljnHI+ueQd27UyWPO9n4Lqt +bK0kdekiC3si7Mee7uXXJaGuqXJozHEZYB1LIFLdCU/itCxEk9hyLcyNzeT+nRT/ +zDuOYdbLgCj7/A5bX+u3jc29UlCYybSFchfMdvn7a0njCna4dE+73b4yEj16tS2h +S1EUygSzgicWlJqMD3Z9Qc+zLEpdhq9oDdDB8HURi2NW4KzIraVncSH+zF1QduOh +nERDnF8x48D3FLdTxGA0W/Kg4gYsq4NRvU6g3DJNdp4YfqRSFMmLFDCgzDuhan7D +wgRlI9NAeHbnyoUPtrDBUceI7shIbC/i87xk9ptqV0AyFonkJtK6lWwZjNkCAwEA +ATANBgkqhkiG9w0BAQsFAAOCAgEAAMgymqZE1YaHYlRGwvTE7gGDY3gmFOMaxQL4 +E5m0CnkBz4BdIPRsQFFdOv3l/MIWkw5ED3vUB925VpQZYFSiEuv5NbnlPaHZlIMI +n8AV/sTP5jue3LhtAN4EM63xNBhudAT6wVsvGwOuQOx9Xv+ptO8Po7sTuNYP0CMH +EOQN+/q8tYlSm2VW+dAlaJ+zVZwZldhVjL+lSH4E9ktWn3PmgNQeKfcnJISUbus6 +ZtsYDF/X96/Z2ZQvMXOKksgvU6XlvIxllcyebC9Bxe/h0D63GCO2tqN5CWQzIIqn +apUynPX8BlLaaExqYGERwlUi/yOGaUVPUjEPVehviOQYgAqxlrkJk1dWeCrwUori +CXpi+IUYkidfgiJ9F88M3ElpwqIaXp7G3/4oHBuE2u6M+L+1/vqPJeTCAWUxxpJE +yYmM+db6D4TySFpQPENNzPS8bpR6T8w2hRumkldC42HrnyJJbpjOieTXhXzjdPvZ +IEP9JGtkhB2du6nBF2MNAq2TqRXpcfQrQEbnQ13aV9bl+roTwwO+SOWK/wgvdOMI +STQ0Xk0sTGlmQjPYPkibVceaWMR3sX4cNt5c33YhJys5jxHoAh42km4nN9tfykR5 +crl5lBlKjXh2GP0+omSO3x1jX4+iQPCW2TWoyKkUdLu/hGHG2w8RrTeme+kATECH +YSu356M= +-----END CERTIFICATE-----', + ], + ]; + $this->appFetcher + ->expects($this->once()) + ->method('get') + ->willReturn($appArray); + + $this->installer->downloadApp('news'); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage App with id news has a cert issued to passman + */ + public function testDownloadAppWithDifferentCN() { + $appArray = [ + [ + 'id' => 'news', + 'certificate' => '-----BEGIN CERTIFICATE----- +MIIEAjCCAuoCAhAYMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD +VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI +MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB +dXRob3JpdHkwHhcNMTYxMDE5MTkzNTEyWhcNMjcwMTI1MTkzNTEyWjASMRAwDgYD +VQQDDAdwYXNzbWFuMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1Jw1 +8F0DefogaLaBudGbhK2zcFIBSzxhh7dRWguZKHGE+rG00BOvFLIAo37Bfmy9WKLc +3BFYvuFBowaVdaFOLxQJod0sOTmVMXhwoY5e3Xx+P+nsAw1/0gI10/LD1Vgl6i1u +gMocmnbEYhKwr0NbdiQiMI9UB9Ge/51wt4WtAxwK7yJFl3+5qzvJgfX75Wt+8L1e +Wk0LpVW23tUueJovjYZJXyAtohNaV3gwiST+QmKljCd4gwGX9abqfc76/lWtS+hI +rKptuICc55ffH30rqVhAgCMouF/Ml5Qru8tDen5dSNtmAXz89OlDNisP+9HL4WDZ +wvgps0mm/OYAUAQln24uXPDmAX/H2P5xIDHAa8avsqdgmHiqnLr4GYD8JYeb8GmB +zZ38hEMjCr2F1k1h9T1+SyfRiDPDqqv1mBtcvNVc1JmZvSikMxhtQbU0C4/o2SBG +RPCirknfPeKu8wBi6gvH4/SK0XTyuM8H58b9AKxzoo/wLbQ668+faLYyMSzCvsZD +eeZkiO85y87Ax57WRY93arccCMaUeks/cTriNw3JrvdDyb2SeQOX9JUp0orUlC64 +AzK2xhXCpmkprVBGizT5g3brrknX6VDX1gXFAmH/daCRJAIHPX0S/ol0z9w/hCEl +CpbiJPEphGtxqz4SfMv6IrIfneuDDKbF+w5MV/sCAwEAATANBgkqhkiG9w0BAQsF +AAOCAQEAUKj+/GpnMn+0/u9SPHTNmX3U3Y/ldmud0CsU5ELzMf/3YPbC/qWziRik +ewM2WyG8cwT9ayt9DxWGfu/zLv+ddyl8Wje1e/FIkRKXK0WW6OMz3e8Y45ONzpmu +8ME75IpnMuZEqE/WayRg27dQT5QNnEe/uNLd4m9BfsQcHIx3OfHCu5Of6/BclgsJ +VWp31zY8kcT0QN1GQxfB3eXnMyELneKCP3OH9DBhr4FUFb0vRHc8/1rdADFvSsdX +hNm8iRq+s2n0F6OGBofYT8ZyCnDUSQAoKMTIHcz+dDGyP4BfPY5w0ZGUfuaYATvm +cR92p/PYCFXkAKP3OO0RPlf6dXNKTw== +-----END CERTIFICATE-----', + ], + ]; + $this->appFetcher + ->expects($this->once()) + ->method('get') + ->willReturn($appArray); + + $this->installer->downloadApp('news'); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage App with id passman has invalid signature + */ + public function testDownloadAppWithInvalidSignature() { + $appArray = [ + [ + 'id' => 'passman', + 'certificate' => '-----BEGIN CERTIFICATE----- +MIIEAjCCAuoCAhAYMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD +VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI +MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB +dXRob3JpdHkwHhcNMTYxMDE5MTkzNTEyWhcNMjcwMTI1MTkzNTEyWjASMRAwDgYD +VQQDDAdwYXNzbWFuMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1Jw1 +8F0DefogaLaBudGbhK2zcFIBSzxhh7dRWguZKHGE+rG00BOvFLIAo37Bfmy9WKLc +3BFYvuFBowaVdaFOLxQJod0sOTmVMXhwoY5e3Xx+P+nsAw1/0gI10/LD1Vgl6i1u +gMocmnbEYhKwr0NbdiQiMI9UB9Ge/51wt4WtAxwK7yJFl3+5qzvJgfX75Wt+8L1e +Wk0LpVW23tUueJovjYZJXyAtohNaV3gwiST+QmKljCd4gwGX9abqfc76/lWtS+hI +rKptuICc55ffH30rqVhAgCMouF/Ml5Qru8tDen5dSNtmAXz89OlDNisP+9HL4WDZ +wvgps0mm/OYAUAQln24uXPDmAX/H2P5xIDHAa8avsqdgmHiqnLr4GYD8JYeb8GmB +zZ38hEMjCr2F1k1h9T1+SyfRiDPDqqv1mBtcvNVc1JmZvSikMxhtQbU0C4/o2SBG +RPCirknfPeKu8wBi6gvH4/SK0XTyuM8H58b9AKxzoo/wLbQ668+faLYyMSzCvsZD +eeZkiO85y87Ax57WRY93arccCMaUeks/cTriNw3JrvdDyb2SeQOX9JUp0orUlC64 +AzK2xhXCpmkprVBGizT5g3brrknX6VDX1gXFAmH/daCRJAIHPX0S/ol0z9w/hCEl +CpbiJPEphGtxqz4SfMv6IrIfneuDDKbF+w5MV/sCAwEAATANBgkqhkiG9w0BAQsF +AAOCAQEAUKj+/GpnMn+0/u9SPHTNmX3U3Y/ldmud0CsU5ELzMf/3YPbC/qWziRik +ewM2WyG8cwT9ayt9DxWGfu/zLv+ddyl8Wje1e/FIkRKXK0WW6OMz3e8Y45ONzpmu +8ME75IpnMuZEqE/WayRg27dQT5QNnEe/uNLd4m9BfsQcHIx3OfHCu5Of6/BclgsJ +VWp31zY8kcT0QN1GQxfB3eXnMyELneKCP3OH9DBhr4FUFb0vRHc8/1rdADFvSsdX +hNm8iRq+s2n0F6OGBofYT8ZyCnDUSQAoKMTIHcz+dDGyP4BfPY5w0ZGUfuaYATvm +cR92p/PYCFXkAKP3OO0RPlf6dXNKTw== +-----END CERTIFICATE-----', + 'releases' => [ + [ + 'download' => 'https://example.com', + 'signature' => 'MySignature', + ], + [ + 'download' => 'https://nextcloud.com', + ], + ], + ], + ]; + $this->appFetcher + ->expects($this->once()) + ->method('get') + ->willReturn($appArray); + $realTmpFile = \OC::$server->getTempManager()->getTemporaryFile('.tar.gz'); + copy(__DIR__ . '/../data/testapp.tar.gz', $realTmpFile); + $this->tempManager + ->expects($this->at(0)) + ->method('getTemporaryFile') + ->with('.tar.gz') + ->willReturn($realTmpFile); + $client = $this->createMock(IClient::class); + $client + ->expects($this->once()) + ->method('get') + ->with('https://example.com', ['save_to' => $realTmpFile]); + $this->clientService + ->expects($this->once()) + ->method('newClient') + ->willReturn($client); + + $this->installer->downloadApp('passman'); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage Extracted app testapp has more than 1 folder + */ + public function testDownloadAppWithMoreThanOneFolderDownloaded() { + $appArray = [ + [ + 'id' => 'testapp', + 'certificate' => '-----BEGIN CERTIFICATE----- +MIIEAjCCAuoCAhAbMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD +VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI +MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB +dXRob3JpdHkwHhcNMTYxMDMxMTgxNTI2WhcNMjcwMjA2MTgxNTI2WjASMRAwDgYD +VQQDEwd0ZXN0YXBwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqa0x +FcVa0YcO/ABqSNdbf7Bzp2PBBJzVM9gI4/HzzBKU/NY9/RibBBpNjAIWEFAbTI4j +ilFSoxHDQ8HrboFOeKCrOIdp9ATQ8SnYVNIQ12Ym3LA/XxcG0gG0H7DeS9C0uACe +svN8fwD1wnKnLLU9GBzO77jwYkneed85wwKG4waHd3965gxQWq0N5gnYS0TTn7Yr +l1veRiw+ryefXvfWI0cN1WBZJ/4XAkwVlpG1HP60AunIpcwn9bfG4XCka+7x26E4 +6Hw0Ot7D7j0yzVzimJDPB2h2buEtPVd6m+oNPueVvKGta+p6cEEaHlFVh2Pa9DI+ +me3nb6aXE2kABWXav3BmK18A5Rg4ZY4VFYvmHmxkOhT/ulGZRqy6TccL/optqs52 +KQ6P0e5dfmhLeoCvJObD+ZYKv+kJCRFtX1Hve/R4IHG6XSFKUfrRjyor9b6TX2L/ +l2vV0mFjmy4g3l05vWHg1Edtq7M29S/xNA3/hF29NjBq6NoMbLGcBtFced1iK07Z +yHLjXRZRfURP671Svqqg8pjxuDqkJ2vIj/Vpod4kF2jeiZYXcfmNKhEhxpkccSe0 +dI6p76Ne7XSUpf8yCPiSnWZLadqKZdEulcB4SlrZO2+/pycgqrqihofDrvDeWeeg +gQyvbZZKl4ylRNj6IRKnosKLVXNqMHQxLmxLHeUCAwEAATANBgkqhkiG9w0BAQsF +AAOCAQEALkKQwa40HfuP4Q6ShwBFJbXLyodIAXCT014kBVjReDKNl5oHtMXRjPxj +nj9doKu+3bLNuLCv9uU3H5+t/GFogReV3Av3z/fCqJ6wHv/KX+lacj31dWXZGD8G +z+RYibrxKkPN0V6q1mSvkg3hJOOE+/4FPIdc8PNlgratv3WS4dT8QwGSUavHW2Kx +89nIdnwtLEFpgML/bTG0dm8BH57xER8LCYixW1VmpV6A4IsoKVsnB7KUCRTK3iUJ +Zh8Xg8UMNrOtXc1Wx1Wmjaa4ZE9dY6/KkU2ny2UWyDHKU/9VE8QQ4HN93gxU4+H7 +cUg0V1uAxqUvKytKkMfcyPWsz/AINA== +-----END CERTIFICATE-----', + 'releases' => [ + [ + 'download' => 'https://example.com', + 'signature' => 'h8H3tUy2dDlwrV/hY/ZxqYqe8Vue+IINluLtAt1HxX2cjz3vdoVHJRINRkMYYcdz +VlndvHyKdqJHDAACphR8tVV6EFrPermn7gEgWk7a51LbUM7sAN7RV7ijEooUo+TQ +jNW9Ch48Wg3jvebMwWNr5t5U4MEXTP5f0YX/kxvkJoUrG3a3spt7ziEuHaq8IPvt +Jj/JSDFhvRNpom7yNNcI1Ijoq8yC11sg7RJBNfrHdGPHPZVz2SyBiY9OcvgGSpUU +bfvzhIZDCl/RRi5fs39jLLupAP69Ez6+jylNXEMsNwM0YL5+egSXFtkCvgOw8UBg +ZqNZZojcS22acuvHRnoa6PDDhwHdCH+zpifXSOhSQvue5n6q+FVX6aeD1LnCQkYB +D2wvNyZWwdADJtvDj03DKhm21g+TPy63XC94q4IqvjQ94pV8U+qrBBfkQ62NGjaC +oOU6y5sEmQeAdVRpWVo0Hewmjp4Adoj5JRwuqCVEynTC6DXHs3HvHxYlmib1F05a +GqEhdDmOHsxNaeJ08Hlptq5yLv3+0wEdtriVjgAZNVduHG1F1FkhPIrDHaB6pd67 +0AFvO/pZgMSHDRHD+safBgaLb5dBZ895Qvudbq3RQevVnO+YZQYZkpmjoF/+TQ7/ +YwDVP+QmNRzx72jtqAN/Kc3CvQ9nkgYhU65B95aX0xA=', + ], + [ + 'download' => 'https://nextcloud.com', + ], + ], + ], + ]; + $this->appFetcher + ->expects($this->once()) + ->method('get') + ->willReturn($appArray); + $realTmpFile = \OC::$server->getTempManager()->getTemporaryFile('.tar.gz'); + copy(__DIR__ . '/../data/testapp1.tar.gz', $realTmpFile); + $this->tempManager + ->expects($this->at(0)) + ->method('getTemporaryFile') + ->with('.tar.gz') + ->willReturn($realTmpFile); + $realTmpFolder = \OC::$server->getTempManager()->getTemporaryFolder(); + mkdir($realTmpFolder . '/testfolder'); + $this->tempManager + ->expects($this->at(1)) + ->method('getTemporaryFolder') + ->willReturn($realTmpFolder); + $client = $this->createMock(IClient::class); + $client + ->expects($this->once()) + ->method('get') + ->with('https://example.com', ['save_to' => $realTmpFile]); + $this->clientService + ->expects($this->once()) + ->method('newClient') + ->willReturn($client); + + $this->installer->downloadApp('testapp'); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage App for id testapp has a wrong app ID in info.xml: testapp1 + */ + public function testDownloadAppWithMismatchingIdentifier() { + $appArray = [ + [ + 'id' => 'testapp', + 'certificate' => '-----BEGIN CERTIFICATE----- +MIIEAjCCAuoCAhAbMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD +VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI +MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB +dXRob3JpdHkwHhcNMTYxMDMxMTgxNTI2WhcNMjcwMjA2MTgxNTI2WjASMRAwDgYD +VQQDEwd0ZXN0YXBwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqa0x +FcVa0YcO/ABqSNdbf7Bzp2PBBJzVM9gI4/HzzBKU/NY9/RibBBpNjAIWEFAbTI4j +ilFSoxHDQ8HrboFOeKCrOIdp9ATQ8SnYVNIQ12Ym3LA/XxcG0gG0H7DeS9C0uACe +svN8fwD1wnKnLLU9GBzO77jwYkneed85wwKG4waHd3965gxQWq0N5gnYS0TTn7Yr +l1veRiw+ryefXvfWI0cN1WBZJ/4XAkwVlpG1HP60AunIpcwn9bfG4XCka+7x26E4 +6Hw0Ot7D7j0yzVzimJDPB2h2buEtPVd6m+oNPueVvKGta+p6cEEaHlFVh2Pa9DI+ +me3nb6aXE2kABWXav3BmK18A5Rg4ZY4VFYvmHmxkOhT/ulGZRqy6TccL/optqs52 +KQ6P0e5dfmhLeoCvJObD+ZYKv+kJCRFtX1Hve/R4IHG6XSFKUfrRjyor9b6TX2L/ +l2vV0mFjmy4g3l05vWHg1Edtq7M29S/xNA3/hF29NjBq6NoMbLGcBtFced1iK07Z +yHLjXRZRfURP671Svqqg8pjxuDqkJ2vIj/Vpod4kF2jeiZYXcfmNKhEhxpkccSe0 +dI6p76Ne7XSUpf8yCPiSnWZLadqKZdEulcB4SlrZO2+/pycgqrqihofDrvDeWeeg +gQyvbZZKl4ylRNj6IRKnosKLVXNqMHQxLmxLHeUCAwEAATANBgkqhkiG9w0BAQsF +AAOCAQEALkKQwa40HfuP4Q6ShwBFJbXLyodIAXCT014kBVjReDKNl5oHtMXRjPxj +nj9doKu+3bLNuLCv9uU3H5+t/GFogReV3Av3z/fCqJ6wHv/KX+lacj31dWXZGD8G +z+RYibrxKkPN0V6q1mSvkg3hJOOE+/4FPIdc8PNlgratv3WS4dT8QwGSUavHW2Kx +89nIdnwtLEFpgML/bTG0dm8BH57xER8LCYixW1VmpV6A4IsoKVsnB7KUCRTK3iUJ +Zh8Xg8UMNrOtXc1Wx1Wmjaa4ZE9dY6/KkU2ny2UWyDHKU/9VE8QQ4HN93gxU4+H7 +cUg0V1uAxqUvKytKkMfcyPWsz/AINA== +-----END CERTIFICATE-----', + 'releases' => [ + [ + 'download' => 'https://example.com', + 'signature' => 'h8H3tUy2dDlwrV/hY/ZxqYqe8Vue+IINluLtAt1HxX2cjz3vdoVHJRINRkMYYcdz +VlndvHyKdqJHDAACphR8tVV6EFrPermn7gEgWk7a51LbUM7sAN7RV7ijEooUo+TQ +jNW9Ch48Wg3jvebMwWNr5t5U4MEXTP5f0YX/kxvkJoUrG3a3spt7ziEuHaq8IPvt +Jj/JSDFhvRNpom7yNNcI1Ijoq8yC11sg7RJBNfrHdGPHPZVz2SyBiY9OcvgGSpUU +bfvzhIZDCl/RRi5fs39jLLupAP69Ez6+jylNXEMsNwM0YL5+egSXFtkCvgOw8UBg +ZqNZZojcS22acuvHRnoa6PDDhwHdCH+zpifXSOhSQvue5n6q+FVX6aeD1LnCQkYB +D2wvNyZWwdADJtvDj03DKhm21g+TPy63XC94q4IqvjQ94pV8U+qrBBfkQ62NGjaC +oOU6y5sEmQeAdVRpWVo0Hewmjp4Adoj5JRwuqCVEynTC6DXHs3HvHxYlmib1F05a +GqEhdDmOHsxNaeJ08Hlptq5yLv3+0wEdtriVjgAZNVduHG1F1FkhPIrDHaB6pd67 +0AFvO/pZgMSHDRHD+safBgaLb5dBZ895Qvudbq3RQevVnO+YZQYZkpmjoF/+TQ7/ +YwDVP+QmNRzx72jtqAN/Kc3CvQ9nkgYhU65B95aX0xA=', + ], + [ + 'download' => 'https://nextcloud.com', + ], + ], + ], + ]; + $this->appFetcher + ->expects($this->once()) + ->method('get') + ->willReturn($appArray); + $realTmpFile = \OC::$server->getTempManager()->getTemporaryFile('.tar.gz'); + copy(__DIR__ . '/../data/testapp1.tar.gz', $realTmpFile); + $this->tempManager + ->expects($this->at(0)) + ->method('getTemporaryFile') + ->with('.tar.gz') + ->willReturn($realTmpFile); + $realTmpFolder = \OC::$server->getTempManager()->getTemporaryFolder(); + $this->tempManager + ->expects($this->at(1)) + ->method('getTemporaryFolder') + ->willReturn($realTmpFolder); + $client = $this->createMock(IClient::class); + $client + ->expects($this->once()) + ->method('get') + ->with('https://example.com', ['save_to' => $realTmpFile]); + $this->clientService + ->expects($this->once()) + ->method('newClient') + ->willReturn($client); + + $this->installer->downloadApp('testapp'); + } - Installer::installApp($oldData); - $oldVersionNumber = \OC_App::getAppVersion(self::$appid); + public function testDownloadAppSuccessful() { + $appArray = [ + [ + 'id' => 'testapp', + 'certificate' => '-----BEGIN CERTIFICATE----- +MIIEAjCCAuoCAhAbMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD +VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI +MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB +dXRob3JpdHkwHhcNMTYxMDMxMTgxNTI2WhcNMjcwMjA2MTgxNTI2WjASMRAwDgYD +VQQDEwd0ZXN0YXBwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqa0x +FcVa0YcO/ABqSNdbf7Bzp2PBBJzVM9gI4/HzzBKU/NY9/RibBBpNjAIWEFAbTI4j +ilFSoxHDQ8HrboFOeKCrOIdp9ATQ8SnYVNIQ12Ym3LA/XxcG0gG0H7DeS9C0uACe +svN8fwD1wnKnLLU9GBzO77jwYkneed85wwKG4waHd3965gxQWq0N5gnYS0TTn7Yr +l1veRiw+ryefXvfWI0cN1WBZJ/4XAkwVlpG1HP60AunIpcwn9bfG4XCka+7x26E4 +6Hw0Ot7D7j0yzVzimJDPB2h2buEtPVd6m+oNPueVvKGta+p6cEEaHlFVh2Pa9DI+ +me3nb6aXE2kABWXav3BmK18A5Rg4ZY4VFYvmHmxkOhT/ulGZRqy6TccL/optqs52 +KQ6P0e5dfmhLeoCvJObD+ZYKv+kJCRFtX1Hve/R4IHG6XSFKUfrRjyor9b6TX2L/ +l2vV0mFjmy4g3l05vWHg1Edtq7M29S/xNA3/hF29NjBq6NoMbLGcBtFced1iK07Z +yHLjXRZRfURP671Svqqg8pjxuDqkJ2vIj/Vpod4kF2jeiZYXcfmNKhEhxpkccSe0 +dI6p76Ne7XSUpf8yCPiSnWZLadqKZdEulcB4SlrZO2+/pycgqrqihofDrvDeWeeg +gQyvbZZKl4ylRNj6IRKnosKLVXNqMHQxLmxLHeUCAwEAATANBgkqhkiG9w0BAQsF +AAOCAQEALkKQwa40HfuP4Q6ShwBFJbXLyodIAXCT014kBVjReDKNl5oHtMXRjPxj +nj9doKu+3bLNuLCv9uU3H5+t/GFogReV3Av3z/fCqJ6wHv/KX+lacj31dWXZGD8G +z+RYibrxKkPN0V6q1mSvkg3hJOOE+/4FPIdc8PNlgratv3WS4dT8QwGSUavHW2Kx +89nIdnwtLEFpgML/bTG0dm8BH57xER8LCYixW1VmpV6A4IsoKVsnB7KUCRTK3iUJ +Zh8Xg8UMNrOtXc1Wx1Wmjaa4ZE9dY6/KkU2ny2UWyDHKU/9VE8QQ4HN93gxU4+H7 +cUg0V1uAxqUvKytKkMfcyPWsz/AINA== +-----END CERTIFICATE-----', + 'releases' => [ + [ + 'download' => 'https://example.com', + 'signature' => 'O5UWFRnSx4mSdEX83Uh9u7KW+Gl1OWU4uaFg6aYY19zc+lWP4rKCbAUH7Jo1Bohf +qxQbhXs4cMqGmoL8dW4zeFUqSJCRk52LA+ciLezjPFv275q+BxEgyWOylLnbhBaz ++v6lXLaeG0J/ry8wEdg+rwP8FCYPsvKlXSVbFjgubvCR/owKJJf5iL0B93noBwBN +jfbcxi7Kh16HAKy6f/gVZ6hf/4Uo7iEFMCPEHjidope+ejUpqbd8XhQg5/yh7TQ7 +VKR7pkdDG2eFr5c3CpaECdNg5ZIGRbQNJHBXHT/wliorWpYJtwtNAQJ4xC635gLP +4klkKN4XtSj8bJUaJC6aaksLFgRSeKXaYAHai/XP6BkeyNzlSbsmyZk8cZbySx8F +gVOzPok1c94UGT57FjeW5eqRjtmzbYivQdP89Ouz6et7PY69yOCqiRFQanrqzwoX +MPLX6f5V9tCJtlH6ztmEcDROfvuVc0U3rEhqx2hphoyo+MZrPFpdcJL8KkIdMKbY +7yQWrsV7QvAzygAOFsC0TlSNJbmMCljouUk9di4CUZ+xsQ6n6TZtE7gsdljlKjPS +3Ys+e3V1HUaVzv8SaSmKwjRoQxQxHWLtXpJS2Yq+i+gq7LuC+aStzxAzV/h2plDW +358picx/PobNDi71Q97+/CAOq+4wDOwhKwls7lwudIs=', + ], + [ + 'download' => 'https://nextcloud.com', + ], + ], + ], + ]; + $this->appFetcher + ->expects($this->once()) + ->method('get') + ->willReturn($appArray); + $realTmpFile = \OC::$server->getTempManager()->getTemporaryFile('.tar.gz'); + copy(__DIR__ . '/../data/testapp.tar.gz', $realTmpFile); + $this->tempManager + ->expects($this->at(0)) + ->method('getTemporaryFile') + ->with('.tar.gz') + ->willReturn($realTmpFile); + $realTmpFolder = \OC::$server->getTempManager()->getTemporaryFolder(); + $this->tempManager + ->expects($this->at(1)) + ->method('getTemporaryFolder') + ->willReturn($realTmpFolder); + $client = $this->createMock(IClient::class); + $client + ->expects($this->once()) + ->method('get') + ->with('https://example.com', ['save_to' => $realTmpFile]); + $this->clientService + ->expects($this->once()) + ->method('newClient') + ->willReturn($client); - Installer::updateApp($newData); - $newVersionNumber = \OC_App::getAppVersion(self::$appid); + $this->installer->downloadApp('testapp'); - $this->assertNotEquals($oldVersionNumber, $newVersionNumber); + $this->assertTrue(file_exists(__DIR__ . '/../../apps/testapp/appinfo/info.xml')); + $this->assertEquals('0.9', \OC_App::getAppVersionByPath(__DIR__ . '/../../apps/testapp/')); } } diff --git a/tests/lib/OCSClientTest.php b/tests/lib/OCSClientTest.php deleted file mode 100644 index d4bfd77e871..00000000000 --- a/tests/lib/OCSClientTest.php +++ /dev/null @@ -1,1132 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * - * @copyright Copyright (c) 2015, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace Test; - -use OC\OCSClient; -use OCP\Http\Client\IClient; -use OCP\Http\Client\IClientService; -use OCP\Http\Client\IResponse; -use OCP\IConfig; -use OCP\ILogger; - -/** - * Class OCSClientTest - */ -class OCSClientTest extends \Test\TestCase { - /** @var OCSClient */ - private $ocsClient; - /** @var IConfig */ - private $config; - /** @var IClientService */ - private $clientService; - /** @var ILogger */ - private $logger; - - public function setUp() { - parent::setUp(); - - $this->config = $this->getMockBuilder('\OCP\IConfig') - ->disableOriginalConstructor()->getMock(); - $this->clientService = $this->createMock(IClientService::class); - $this->logger = $this->createMock(ILogger::class); - - $this->ocsClient = new OCSClient( - $this->clientService, - $this->config, - $this->logger - ); - } - - public function testIsAppStoreEnabledSuccess() { - $this->config - ->expects($this->once()) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(true)); - $this->assertTrue($this->ocsClient->isAppStoreEnabled()); - } - - public function testIsAppStoreEnabledFail() { - $this->config - ->expects($this->once()) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(false)); - $this->assertFalse($this->ocsClient->isAppStoreEnabled()); - } - - public function testGetAppStoreUrl() { - $this->config - ->expects($this->once()) - ->method('getSystemValue') - ->with('appstoreurl', 'https://api.owncloud.com/v1') - ->will($this->returnValue('https://api.owncloud.com/v1')); - $this->assertSame('https://api.owncloud.com/v1', self::invokePrivate($this->ocsClient, 'getAppStoreUrl')); - } - - public function testGetCategoriesDisabledAppStore() { - $this->config - ->expects($this->once()) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(false)); - $this->assertNull($this->ocsClient->getCategories([8, 1, 0, 7])); - } - - public function testGetCategoriesExceptionClient() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(true)); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreurl', 'https://api.owncloud.com/v1') - ->will($this->returnValue('https://api.owncloud.com/v1')); - - $client = $this->createMock(IClient::class); - $client - ->expects($this->once()) - ->method('get') - ->with( - 'https://api.owncloud.com/v1/content/categories', - [ - 'timeout' => 20, - 'query' => ['version' => '8x1x0x7'], - ] - ) - ->will($this->throwException(new \Exception('TheErrorMessage'))); - - $this->clientService - ->expects($this->once()) - ->method('newClient') - ->will($this->returnValue($client)); - - $this->logger - ->expects($this->once()) - ->method('error') - ->with( - 'Could not get categories: TheErrorMessage', - [ - 'app' => 'core', - ] - ); - - $this->assertNull($this->ocsClient->getCategories([8, 1, 0, 7])); - } - - public function testGetCategoriesParseError() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(true)); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreurl', 'https://api.owncloud.com/v1') - ->will($this->returnValue('https://api.owncloud.com/v1')); - - $response = $this->createMock(IResponse::class); - $response - ->expects($this->once()) - ->method('getBody') - ->will($this->returnValue('MyInvalidXml')); - - $client = $this->createMock(IClient::class); - $client - ->expects($this->once()) - ->method('get') - ->with( - 'https://api.owncloud.com/v1/content/categories', - [ - 'timeout' => 20, - 'query' => ['version' => '8x1x0x7'], - ] - ) - ->will($this->returnValue($response)); - - $this->clientService - ->expects($this->once()) - ->method('newClient') - ->will($this->returnValue($client)); - - $this->logger - ->expects($this->once()) - ->method('error') - ->with( - 'Could not get categories, content was no valid XML', - [ - 'app' => 'core', - ] - ); - - $this->assertNull($this->ocsClient->getCategories([8, 1, 0, 7])); - } - - public function testGetCategoriesSuccessful() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(true)); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreurl', 'https://api.owncloud.com/v1') - ->will($this->returnValue('https://api.owncloud.com/v1')); - - $response = $this->createMock(IResponse::class); - $response - ->expects($this->once()) - ->method('getBody') - ->will($this->returnValue('<?xml version="1.0"?> - <ocs> - <meta> - <status>ok</status> - <statuscode>100</statuscode> - <message></message> - <totalitems>6</totalitems> - </meta> - <data> - <category> - <id>920</id> - <name>ownCloud Multimedia</name> - </category> - <category> - <id>921</id> - <name>ownCloud PIM</name> - </category> - <category> - <id>922</id> - <name>ownCloud Productivity</name> - </category> - <category> - <id>923</id> - <name>ownCloud Game</name> - </category> - <category> - <id>924</id> - <name>ownCloud Tool</name> - </category> - <category> - <id>925</id> - <name>ownCloud other</name> - </category> - </data> - </ocs> - ')); - - $client = $this->createMock(IClient::class); - $client - ->expects($this->once()) - ->method('get') - ->with( - 'https://api.owncloud.com/v1/content/categories', - [ - 'timeout' => 20, - 'query' => ['version' => '8x1x0x7'], - ] - ) - ->will($this->returnValue($response)); - - $this->clientService - ->expects($this->once()) - ->method('newClient') - ->will($this->returnValue($client)); - - $expected = [ - 920 => 'ownCloud Multimedia', - 921 => 'ownCloud PIM', - 922 => 'ownCloud Productivity', - 923 => 'ownCloud Game', - 924 => 'ownCloud Tool', - 925 => 'ownCloud other', - ]; - $this->assertSame($expected, $this->ocsClient->getCategories([8, 1, 0, 7])); - } - - public function testGetApplicationsDisabledAppStore() { - $this->config - ->expects($this->once()) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(false)); - $this->assertSame([], $this->ocsClient->getApplications([], 1, 'approved', [8, 1, 0, 7])); - } - - public function testGetApplicationsExceptionClient() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(true)); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreurl', 'https://api.owncloud.com/v1') - ->will($this->returnValue('https://api.owncloud.com/v1')); - - $client = $this->createMock(IClient::class); - $client - ->expects($this->once()) - ->method('get') - ->with( - 'https://api.owncloud.com/v1/content/data', - [ - 'timeout' => 20, - 'query' => [ - 'version' => implode('x', [8, 1, 0, 7]), - 'filter' => 'approved', - 'categories' => '815x1337', - 'sortmode' => 'new', - 'page' => 1, - 'pagesize' => 100, - 'approved' => 'approved', - ], - ] - ) - ->will($this->throwException(new \Exception('TheErrorMessage'))); - - $this->clientService - ->expects($this->once()) - ->method('newClient') - ->will($this->returnValue($client)); - - $this->logger - ->expects($this->once()) - ->method('error') - ->with( - 'Could not get applications: TheErrorMessage', - [ - 'app' => 'core', - ] - ); - - $this->assertSame([], $this->ocsClient->getApplications([815, 1337], 1, 'approved', [8, 1, 0, 7])); - } - - public function testGetApplicationsParseError() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(true)); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreurl', 'https://api.owncloud.com/v1') - ->will($this->returnValue('https://api.owncloud.com/v1')); - - $response = $this->createMock(IResponse::class); - $response - ->expects($this->once()) - ->method('getBody') - ->will($this->returnValue('MyInvalidXml')); - - $client = $this->createMock(IClient::class); - $client - ->expects($this->once()) - ->method('get') - ->with( - 'https://api.owncloud.com/v1/content/data', - [ - 'timeout' => 20, - 'query' => [ - 'version' => implode('x', [8, 1, 0, 7]), - 'filter' => 'approved', - 'categories' => '815x1337', - 'sortmode' => 'new', - 'page' => 1, - 'pagesize' => 100, - 'approved' => 'approved', - ], - ] - ) - ->will($this->returnValue($response)); - - $this->clientService - ->expects($this->once()) - ->method('newClient') - ->will($this->returnValue($client)); - - $this->logger - ->expects($this->once()) - ->method('error') - ->with( - 'Could not get applications, content was no valid XML', - [ - 'app' => 'core', - ] - ); - - $this->assertSame([], $this->ocsClient->getApplications([815, 1337], 1, 'approved', [8, 1, 0, 7])); - } - - public function testGetApplicationsSuccessful() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(true)); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreurl', 'https://api.owncloud.com/v1') - ->will($this->returnValue('https://api.owncloud.com/v1')); - - $response = $this->createMock(IResponse::class); - $response - ->expects($this->once()) - ->method('getBody') - ->will($this->returnValue('<?xml version="1.0"?> - <ocs> - <meta> - <status>ok</status> - <statuscode>100</statuscode> - <message></message> - <totalitems>2</totalitems> - <itemsperpage>100</itemsperpage> - </meta> - <data> - <content details="summary"> - <id>168707</id> - <name>Calendar 8.0</name> - <version>0.6.4</version> - <label>recommended</label> - <changed>2015-02-09T15:23:56+01:00</changed> - <created>2015-01-26T04:35:19+01:00</created> - <typeid>921</typeid> - <typename>ownCloud PIM</typename> - <language></language> - <personid>owncloud</personid> - <profilepage>http://opendesktop.org/usermanager/search.php?username=owncloud</profilepage> - <downloads>5393</downloads> - <score>60</score> - <description>Calendar App for ownCloud</description> - <comments>7</comments> - <fans>10</fans> - <licensetype>16</licensetype> - <approved>0</approved> - <category>1</category> - <license>AGPL</license> - <preview1></preview1> - <detailpage>https://apps.owncloud.com/content/show.php?content=168707</detailpage> - <downloadtype1></downloadtype1> - <downloadway1>0</downloadway1> - <downloadprice1>0</downloadprice1> - <downloadlink1>http://apps.owncloud.com/content/download.php?content=168707&id=1</downloadlink1> - <downloadgpgsignature1></downloadgpgsignature1> - <downloadgpgfingerprint1></downloadgpgfingerprint1> - <downloadpackagename1></downloadpackagename1> - <downloadrepository1></downloadrepository1> - <downloadname1></downloadname1> - <downloadsize1>885</downloadsize1> - </content> - <content details="summary"> - <id>168708</id> - <name>Contacts 8.0</name> - <version>0.3.0.18</version> - <label>recommended</label> - <changed>2015-02-09T15:18:58+01:00</changed> - <created>2015-01-26T04:45:17+01:00</created> - <typeid>921</typeid> - <typename>ownCloud PIM</typename> - <language></language> - <personid>owncloud</personid> - <profilepage>http://opendesktop.org/usermanager/search.php?username=owncloud</profilepage> - <downloads>4237</downloads> - <score>58</score> - <description></description> - <comments>3</comments> - <fans>6</fans> - <licensetype>16</licensetype> - <approved>200</approved> - <category>1</category> - <license>AGPL</license> - <preview1></preview1> - <detailpage>https://apps.owncloud.com/content/show.php?content=168708</detailpage> - <downloadtype1></downloadtype1> - <downloadway1>0</downloadway1> - <downloadprice1>0</downloadprice1> - <downloadlink1>http://apps.owncloud.com/content/download.php?content=168708&id=1</downloadlink1> - <downloadgpgsignature1></downloadgpgsignature1> - <downloadgpgfingerprint1></downloadgpgfingerprint1> - <downloadpackagename1></downloadpackagename1> - <downloadrepository1></downloadrepository1> - <downloadname1></downloadname1> - <downloadsize1>1409</downloadsize1> - </content> - </data> - </ocs> ')); - - $client = $this->createMock(IClient::class); - $client - ->expects($this->once()) - ->method('get') - ->with( - 'https://api.owncloud.com/v1/content/data', - [ - 'timeout' => 20, - 'query' => [ - 'version' => implode('x', [8, 1, 0, 7]), - 'filter' => 'approved', - 'categories' => '815x1337', - 'sortmode' => 'new', - 'page' => 1, - 'pagesize' => 100, - 'approved' => 'approved', - ], - ] - ) - ->will($this->returnValue($response)); - - $this->clientService - ->expects($this->once()) - ->method('newClient') - ->will($this->returnValue($client)); - - $expected = [ - [ - 'id' => '168707', - 'name' => 'Calendar 8.0', - 'label' => 'recommended', - 'version' => '0.6.4', - 'type' => '921', - 'typename' => 'ownCloud PIM', - 'personid' => 'owncloud', - 'license' => 'AGPL', - 'detailpage' => 'https://apps.owncloud.com/content/show.php?content=168707', - 'preview' => '', - 'preview-full' => '', - 'changed' => 1423491836, - 'description' => 'Calendar App for ownCloud', - 'score' => '60', - 'downloads' => 5393, - 'level' => 0, - 'profilepage' => 'http://opendesktop.org/usermanager/search.php?username=owncloud', - ], - [ - 'id' => '168708', - 'name' => 'Contacts 8.0', - 'label' => 'recommended', - 'version' => '0.3.0.18', - 'type' => '921', - 'typename' => 'ownCloud PIM', - 'personid' => 'owncloud', - 'license' => 'AGPL', - 'detailpage' => 'https://apps.owncloud.com/content/show.php?content=168708', - 'preview' => '', - 'preview-full' => '', - 'changed' => 1423491538, - 'description' => '', - 'score' => '58', - 'downloads' => 4237, - 'level' => 200, - 'profilepage' => 'http://opendesktop.org/usermanager/search.php?username=owncloud', - ], - ]; - $this->assertEquals($expected, $this->ocsClient->getApplications([815, 1337], 1, 'approved', [8, 1, 0, 7])); - } - - public function tesGetApplicationDisabledAppStore() { - $this->config - ->expects($this->once()) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(false)); - $this->assertNull($this->ocsClient->getApplication('MyId', [8, 1, 0, 7])); - } - - public function testGetApplicationExceptionClient() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(true)); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreurl', 'https://api.owncloud.com/v1') - ->will($this->returnValue('https://api.owncloud.com/v1')); - - $client = $this->createMock(IClient::class); - $client - ->expects($this->once()) - ->method('get') - ->with( - 'https://api.owncloud.com/v1/content/data/MyId', - [ - 'timeout' => 20, - 'query' => ['version' => '8x1x0x7'], - ] - ) - ->will($this->throwException(new \Exception('TheErrorMessage'))); - - $this->clientService - ->expects($this->once()) - ->method('newClient') - ->will($this->returnValue($client)); - - $this->logger - ->expects($this->once()) - ->method('error') - ->with( - 'Could not get application: TheErrorMessage', - [ - 'app' => 'core', - ] - ); - - $this->assertNull($this->ocsClient->getApplication('MyId', [8, 1, 0, 7])); - } - - public function testGetApplicationParseError() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(true)); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreurl', 'https://api.owncloud.com/v1') - ->will($this->returnValue('https://api.owncloud.com/v1')); - - $response = $this->createMock(IResponse::class); - $response - ->expects($this->once()) - ->method('getBody') - ->will($this->returnValue('MyInvalidXml')); - - $client = $this->createMock(IClient::class); - $client - ->expects($this->once()) - ->method('get') - ->with( - 'https://api.owncloud.com/v1/content/data/MyId', - [ - 'timeout' => 20, - 'query' => ['version' => '8x1x0x7'], - ] - ) - ->will($this->returnValue($response)); - - $this->clientService - ->expects($this->once()) - ->method('newClient') - ->will($this->returnValue($client)); - - $this->logger - ->expects($this->once()) - ->method('error') - ->with( - 'Could not get application, content was no valid XML', - [ - 'app' => 'core', - ] - ); - - $this->assertNull($this->ocsClient->getApplication('MyId', [8, 1, 0, 7])); - } - - public function testGetApplicationSuccessful() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(true)); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreurl', 'https://api.owncloud.com/v1') - ->will($this->returnValue('https://api.owncloud.com/v1')); - - $response = $this->createMock(IResponse::class); - $response - ->expects($this->once()) - ->method('getBody') - ->will($this->returnValue('<?xml version="1.0"?> - <ocs> - <meta> - <status>ok</status> - <statuscode>100</statuscode> - <message></message> - </meta> - <data> - <content details="full"> - <id>166053</id> - <name>Versioning</name> - <version>0.0.1</version> - <label>recommended</label> - <typeid>925</typeid> - <typename>ownCloud other</typename> - <language></language> - <personid>owncloud</personid> - <profilepage>http://opendesktop.org/usermanager/search.php?username=owncloud</profilepage> - <created>2014-07-07T16:34:40+02:00</created> - <changed>2014-07-07T16:34:40+02:00</changed> - <downloads>140</downloads> - <score>50</score> - <description>Placeholder for future updates</description> - <summary></summary> - <feedbackurl></feedbackurl> - <changelog></changelog> - <homepage></homepage> - <homepagetype></homepagetype> - <homepage2></homepage2> - <homepagetype2></homepagetype2> - <homepage3></homepage3> - <homepagetype3></homepagetype3> - <homepage4></homepage4> - <homepagetype4></homepagetype4> - <homepage5></homepage5> - <homepagetype5></homepagetype5> - <homepage6></homepage6> - <homepagetype6></homepagetype6> - <homepage7></homepage7> - <homepagetype7></homepagetype7> - <homepage8></homepage8> - <homepagetype8></homepagetype8> - <homepage9></homepage9> - <homepagetype9></homepagetype9> - <homepage10></homepage10> - <homepagetype10></homepagetype10> - <licensetype>16</licensetype> - <license>AGPL</license> - <donationpage></donationpage> - <comments>0</comments> - <commentspage>http://apps.owncloud.com/content/show.php?content=166053</commentspage> - <fans>0</fans> - <fanspage>http://apps.owncloud.com/content/show.php?action=fan&content=166053</fanspage> - <knowledgebaseentries>0</knowledgebaseentries> - <knowledgebasepage>http://apps.owncloud.com/content/show.php?action=knowledgebase&content=166053</knowledgebasepage> - <depend>ownCloud 7</depend> - <preview1></preview1> - <preview2></preview2> - <preview3></preview3> - <previewpic1></previewpic1> - <previewpic2></previewpic2> - <previewpic3></previewpic3> - <picsmall1></picsmall1> - <picsmall2></picsmall2> - <picsmall3></picsmall3> - <detailpage>https://apps.owncloud.com/content/show.php?content=166053</detailpage> - <downloadtype1></downloadtype1> - <downloadprice1>0</downloadprice1> - <downloadlink1>http://apps.owncloud.com/content/download.php?content=166053&id=1</downloadlink1> - <downloadname1></downloadname1> - <downloadgpgfingerprint1></downloadgpgfingerprint1> - <downloadgpgsignature1></downloadgpgsignature1> - <downloadpackagename1></downloadpackagename1> - <downloadrepository1></downloadrepository1> - <downloadsize1>1</downloadsize1> - <approved>200</approved> - </content> - </data> - </ocs> - ')); - - $client = $this->createMock(IClient::class); - $client - ->expects($this->once()) - ->method('get') - ->with( - 'https://api.owncloud.com/v1/content/data/166053', - [ - 'timeout' => 20, - 'query' => ['version' => '8x1x0x7'], - ] - ) - ->will($this->returnValue($response)); - - $this->clientService - ->expects($this->once()) - ->method('newClient') - ->will($this->returnValue($client)); - - $expected = [ - 'id' => 166053, - 'name' => 'Versioning', - 'version' => '0.0.1', - 'type' => '925', - 'label' => 'recommended', - 'typename' => 'ownCloud other', - 'personid' => 'owncloud', - 'profilepage' => 'http://opendesktop.org/usermanager/search.php?username=owncloud', - 'detailpage' => 'https://apps.owncloud.com/content/show.php?content=166053', - 'preview1' => '', - 'preview2' => '', - 'preview3' => '', - 'changed' => 1404743680, - 'description' => 'Placeholder for future updates', - 'score' => 50, - 'level' => 200, - ]; - $this->assertSame($expected, $this->ocsClient->getApplication(166053, [8, 1, 0, 7])); - } - - public function testGetApplicationSuccessfulWithOldId() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(true)); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreurl', 'https://api.owncloud.com/v1') - ->will($this->returnValue('https://api.owncloud.com/v1')); - - $response = $this->createMock(IResponse::class); - $response - ->expects($this->once()) - ->method('getBody') - ->will($this->returnValue('<?xml version="1.0"?> - <ocs> - <meta> - <status>ok</status> - <statuscode>100</statuscode> - <message></message> - </meta> - <data> - <content details="full"> - <id>1337</id> - <name>Versioning</name> - <version>0.0.1</version> - <label>recommended</label> - <typeid>925</typeid> - <typename>ownCloud other</typename> - <language></language> - <personid>owncloud</personid> - <profilepage>http://opendesktop.org/usermanager/search.php?username=owncloud</profilepage> - <created>2014-07-07T16:34:40+02:00</created> - <changed>2014-07-07T16:34:40+02:00</changed> - <downloads>140</downloads> - <score>50</score> - <description>Placeholder for future updates</description> - <summary></summary> - <feedbackurl></feedbackurl> - <changelog></changelog> - <homepage></homepage> - <homepagetype></homepagetype> - <homepage2></homepage2> - <homepagetype2></homepagetype2> - <homepage3></homepage3> - <homepagetype3></homepagetype3> - <homepage4></homepage4> - <homepagetype4></homepagetype4> - <homepage5></homepage5> - <homepagetype5></homepagetype5> - <homepage6></homepage6> - <homepagetype6></homepagetype6> - <homepage7></homepage7> - <homepagetype7></homepagetype7> - <homepage8></homepage8> - <homepagetype8></homepagetype8> - <homepage9></homepage9> - <homepagetype9></homepagetype9> - <homepage10></homepage10> - <homepagetype10></homepagetype10> - <licensetype>16</licensetype> - <license>AGPL</license> - <donationpage></donationpage> - <comments>0</comments> - <commentspage>http://apps.owncloud.com/content/show.php?content=166053</commentspage> - <fans>0</fans> - <fanspage>http://apps.owncloud.com/content/show.php?action=fan&content=166053</fanspage> - <knowledgebaseentries>0</knowledgebaseentries> - <knowledgebasepage>http://apps.owncloud.com/content/show.php?action=knowledgebase&content=166053</knowledgebasepage> - <depend>ownCloud 7</depend> - <preview1></preview1> - <preview2></preview2> - <preview3></preview3> - <previewpic1></previewpic1> - <previewpic2></previewpic2> - <previewpic3></previewpic3> - <picsmall1></picsmall1> - <picsmall2></picsmall2> - <picsmall3></picsmall3> - <detailpage>https://apps.owncloud.com/content/show.php?content=166053</detailpage> - <downloadtype1></downloadtype1> - <downloadprice1>0</downloadprice1> - <downloadlink1>http://apps.owncloud.com/content/download.php?content=166053&id=1</downloadlink1> - <downloadname1></downloadname1> - <downloadgpgfingerprint1></downloadgpgfingerprint1> - <downloadgpgsignature1></downloadgpgsignature1> - <downloadpackagename1></downloadpackagename1> - <downloadrepository1></downloadrepository1> - <downloadsize1>1</downloadsize1> - <approved>200</approved> - </content> - </data> - </ocs> - ')); - - $client = $this->createMock(IClient::class); - $client - ->expects($this->once()) - ->method('get') - ->with( - 'https://api.owncloud.com/v1/content/data/166053', - [ - 'timeout' => 20, - 'query' => ['version' => '8x1x0x7'], - ] - ) - ->will($this->returnValue($response)); - - $this->clientService - ->expects($this->once()) - ->method('newClient') - ->will($this->returnValue($client)); - - $expected = [ - 'id' => 166053, - 'name' => 'Versioning', - 'version' => '0.0.1', - 'type' => '925', - 'label' => 'recommended', - 'typename' => 'ownCloud other', - 'personid' => 'owncloud', - 'profilepage' => 'http://opendesktop.org/usermanager/search.php?username=owncloud', - 'detailpage' => 'https://apps.owncloud.com/content/show.php?content=166053', - 'preview1' => '', - 'preview2' => '', - 'preview3' => '', - 'changed' => 1404743680, - 'description' => 'Placeholder for future updates', - 'score' => 50, - 'level' => 200, - ]; - $this->assertSame($expected, $this->ocsClient->getApplication(166053, [8, 1, 0, 7])); - } - - public function testGetApplicationEmptyXml() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(true)); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreurl', 'https://api.owncloud.com/v1') - ->will($this->returnValue('https://api.owncloud.com/v1')); - - $response = $this->createMock(IResponse::class); - $response - ->expects($this->once()) - ->method('getBody') - ->will($this->returnValue('<?xml version="1.0"?> - <ocs> - <meta> - <status>ok</status> - <statuscode>100</statuscode> - <message></message> - </meta> - </ocs> - ')); - - $client = $this->createMock(IClient::class); - $client - ->expects($this->once()) - ->method('get') - ->with( - 'https://api.owncloud.com/v1/content/data/MyId', - [ - 'timeout' => 20, - 'query' => ['version' => '8x1x0x7'], - ] - ) - ->will($this->returnValue($response)); - - $this->clientService - ->expects($this->once()) - ->method('newClient') - ->will($this->returnValue($client)); - - $this->assertSame(null, $this->ocsClient->getApplication('MyId', [8, 1, 0, 7])); - } - - public function testGetApplicationDownloadDisabledAppStore() { - $this->config - ->expects($this->once()) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(false)); - $this->assertNull($this->ocsClient->getApplicationDownload('MyId', [8, 1, 0, 7])); - } - - public function testGetApplicationDownloadExceptionClient() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(true)); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreurl', 'https://api.owncloud.com/v1') - ->will($this->returnValue('https://api.owncloud.com/v1')); - - $client = $this->createMock(IClient::class); - $client - ->expects($this->once()) - ->method('get') - ->with( - 'https://api.owncloud.com/v1/content/download/MyId/1', - [ - 'timeout' => 20, - 'query' => ['version' => '8x1x0x7'], - ] - ) - ->will($this->throwException(new \Exception('TheErrorMessage'))); - - $this->clientService - ->expects($this->once()) - ->method('newClient') - ->will($this->returnValue($client)); - - $this->logger - ->expects($this->once()) - ->method('error') - ->with( - 'Could not get application download URL: TheErrorMessage', - [ - 'app' => 'core', - ] - ); - - $this->assertNull($this->ocsClient->getApplicationDownload('MyId', [8, 1, 0, 7])); - } - - public function testGetApplicationDownloadParseError() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(true)); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreurl', 'https://api.owncloud.com/v1') - ->will($this->returnValue('https://api.owncloud.com/v1')); - - $response = $this->createMock(IResponse::class); - $response - ->expects($this->once()) - ->method('getBody') - ->will($this->returnValue('MyInvalidXml')); - - $client = $this->createMock(IClient::class); - $client - ->expects($this->once()) - ->method('get') - ->with( - 'https://api.owncloud.com/v1/content/download/MyId/1', - [ - 'timeout' => 20, - 'query' => ['version' => '8x1x0x7'], - ] - ) - ->will($this->returnValue($response)); - - $this->clientService - ->expects($this->once()) - ->method('newClient') - ->will($this->returnValue($client)); - - $this->logger - ->expects($this->once()) - ->method('error') - ->with( - 'Could not get application download URL, content was no valid XML', - [ - 'app' => 'core', - ] - ); - - $this->assertNull($this->ocsClient->getApplicationDownload('MyId', [8, 1, 0, 7])); - } - - public function testGetApplicationDownloadUrlSuccessful() { - $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('appstoreenabled', true) - ->will($this->returnValue(true)); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('appstoreurl', 'https://api.owncloud.com/v1') - ->will($this->returnValue('https://api.owncloud.com/v1')); - - $response = $this->createMock(IResponse::class); - $response - ->expects($this->once()) - ->method('getBody') - ->will($this->returnValue('<?xml version="1.0"?> - <ocs> - <meta> - <status>ok</status> - <statuscode>100</statuscode> - <message></message> - </meta> - <data> - <content details="download"> - <downloadlink>https://apps.owncloud.com/CONTENT/content-files/166052-files_trashbin.zip</downloadlink> - <mimetype>application/zip</mimetype> - <gpgfingerprint></gpgfingerprint> - <gpgsignature></gpgsignature> - <packagename></packagename> - <repository></repository> - </content> - </data> - </ocs> - ')); - - $client = $this->createMock(IClient::class); - $client - ->expects($this->once()) - ->method('get') - ->with( - 'https://api.owncloud.com/v1/content/download/MyId/1', - [ - 'timeout' => 20, - 'query' => ['version' => '8x1x0x7'], - ] - ) - ->will($this->returnValue($response)); - - $this->clientService - ->expects($this->once()) - ->method('newClient') - ->will($this->returnValue($client)); - - $expected = [ - 'downloadlink' => 'https://apps.owncloud.com/CONTENT/content-files/166052-files_trashbin.zip', - ]; - $this->assertSame($expected, $this->ocsClient->getApplicationDownload('MyId', [8, 1, 0, 7])); - } -} diff --git a/tests/lib/Security/CSRF/CsrfTokenManagerTest.php b/tests/lib/Security/CSRF/CsrfTokenManagerTest.php index 6f7842fdfd9..f9dd8127e5a 100644 --- a/tests/lib/Security/CSRF/CsrfTokenManagerTest.php +++ b/tests/lib/Security/CSRF/CsrfTokenManagerTest.php @@ -137,15 +137,19 @@ class CsrfTokenManagerTest extends \Test\TestCase { } public function testIsTokenValidWithValidToken() { + $a = 'abc'; + $b = 'def'; + $xorB64 = 'BQcF'; + $tokenVal = sprintf('%s:%s', $xorB64, base64_encode($a)); $this->storageInterface ->expects($this->once()) ->method('hasToken') ->willReturn(true); - $token = new \OC\Security\CSRF\CsrfToken('XlQhHjgWCgBXAEI0Khl+IQEiCXN2LUcDHAQTQAc1HQs=:qgkUlg8l3m8WnkOG4XM9Az33pAt1vSVMx4hcJFsxdqc='); + $token = new \OC\Security\CSRF\CsrfToken($tokenVal); $this->storageInterface ->expects($this->once()) ->method('getToken') - ->willReturn('/3JKTq2ldmzcDr1f5zDJ7Wt0lEgqqfKF'); + ->willReturn($b); $this->assertSame(true, $this->csrfTokenManager->isTokenValid($token)); } diff --git a/tests/lib/Security/CSRF/CsrfTokenTest.php b/tests/lib/Security/CSRF/CsrfTokenTest.php index d19d1de916c..fbb92cd315a 100644 --- a/tests/lib/Security/CSRF/CsrfTokenTest.php +++ b/tests/lib/Security/CSRF/CsrfTokenTest.php @@ -36,7 +36,11 @@ class CsrfTokenTest extends \Test\TestCase { } public function testGetDecryptedValue() { - $csrfToken = new \OC\Security\CSRF\CsrfToken('XlQhHjgWCgBXAEI0Khl+IQEiCXN2LUcDHAQTQAc1HQs=:qgkUlg8l3m8WnkOG4XM9Az33pAt1vSVMx4hcJFsxdqc='); - $this->assertSame('/3JKTq2ldmzcDr1f5zDJ7Wt0lEgqqfKF', $csrfToken->getDecryptedValue()); + $a = 'abc'; + $b = 'def'; + $xorB64 = 'BQcF'; + $tokenVal = sprintf('%s:%s', $xorB64, base64_encode($a)); + $csrfToken = new \OC\Security\CSRF\CsrfToken($tokenVal); + $this->assertSame($b, $csrfToken->getDecryptedValue()); } } diff --git a/tests/lib/ServerTest.php b/tests/lib/ServerTest.php index 2e5900c4ce5..02fccee628e 100644 --- a/tests/lib/ServerTest.php +++ b/tests/lib/ServerTest.php @@ -23,6 +23,8 @@ */ namespace Test; +use OC\App\AppStore\Fetcher\AppFetcher; +use OC\App\AppStore\Fetcher\CategoryFetcher; /** * Class Server @@ -50,6 +52,7 @@ class ServerTest extends \Test\TestCase { ['AllConfig', '\OCP\IConfig'], ['AppConfig', '\OC\AppConfig'], ['AppConfig', '\OCP\IAppConfig'], + ['AppFetcher', AppFetcher::class], ['AppHelper', '\OC\AppHelper'], ['AppHelper', '\OCP\IHelper'], ['AppManager', '\OC\App\AppManager'], @@ -59,6 +62,7 @@ class ServerTest extends \Test\TestCase { ['AvatarManager', '\OC\AvatarManager'], ['AvatarManager', '\OCP\IAvatarManager'], + ['CategoryFetcher', CategoryFetcher::class], ['CapabilitiesManager', '\OC\CapabilitiesManager'], ['ContactsManager', '\OC\ContactsManager'], ['ContactsManager', '\OCP\Contacts\IManager'], @@ -122,8 +126,6 @@ class ServerTest extends \Test\TestCase { ['UserCache', '\OC\Cache\File'], ['UserCache', '\OCP\ICache'], - ['OcsClient', '\OC\OCSClient'], - ['PreviewManager', '\OC\PreviewManager'], ['PreviewManager', '\OCP\IPreview'], diff --git a/tests/lib/Share20/ManagerTest.php b/tests/lib/Share20/ManagerTest.php index c0c7b48b35d..bd85e3c73aa 100644 --- a/tests/lib/Share20/ManagerTest.php +++ b/tests/lib/Share20/ManagerTest.php @@ -2530,6 +2530,46 @@ class ManagerTest extends \Test\TestCase { $this->manager->moveShare($share, 'recipient'); } + + /** + * @dataProvider dataTestShareProviderExists + */ + public function testShareProviderExists($shareType, $expected) { + + $factory = $this->getMockBuilder('OCP\Share\IProviderFactory')->getMock(); + $factory->expects($this->any())->method('getProviderForType') + ->willReturnCallback(function ($id) { + if ($id === \OCP\Share::SHARE_TYPE_USER) { + return true; + } + throw new Exception\ProviderException(); + }); + + $manager = new Manager( + $this->logger, + $this->config, + $this->secureRandom, + $this->hasher, + $this->mountManager, + $this->groupManager, + $this->l, + $factory, + $this->userManager, + $this->rootFolder, + $this->eventDispatcher + ); + $this->assertSame($expected, + $manager->shareProviderExists($shareType) + ); + } + + public function dataTestShareProviderExists() { + return [ + [\OCP\Share::SHARE_TYPE_USER, true], + [42, false], + ]; + } + public function testGetSharesInFolder() { $factory = new DummyFactory2($this->createMock(IServerContainer::class)); diff --git a/tests/lib/StreamWrappersTest.php b/tests/lib/StreamWrappersTest.php index c0ecb5e738b..eb35fd54454 100644 --- a/tests/lib/StreamWrappersTest.php +++ b/tests/lib/StreamWrappersTest.php @@ -38,7 +38,7 @@ class StreamWrappersTest extends \Test\TestCase { public static function tearDownAfterClass() { if (self::$trashBinStatus) { - \OC_App::enable('files_trashbin'); + (new \OC_App())->enable('files_trashbin'); } } diff --git a/tests/lib/User/SessionTest.php b/tests/lib/User/SessionTest.php index 268d8e10e5a..ee9ed737cf5 100644 --- a/tests/lib/User/SessionTest.php +++ b/tests/lib/User/SessionTest.php @@ -1,5 +1,4 @@ <?php - /** * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com> * This file is licensed under the Affero General Public License version 3 or @@ -39,8 +38,16 @@ class SessionTest extends \Test\TestCase { protected $tokenProvider; /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ private $config; - /** @var Throttler */ + /** @var Throttler|\PHPUnit_Framework_MockObject_MockObject */ private $throttler; + /** @var ISecureRandom|\PHPUnit_Framework_MockObject_MockObject */ + private $random; + /** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */ + private $manager; + /** @var ISession|\PHPUnit_Framework_MockObject_MockObject */ + private $session; + /** @var Session|\PHPUnit_Framework_MockObject_MockObject */ + private $userSession; protected function setUp() { parent::setUp(); @@ -52,6 +59,24 @@ class SessionTest extends \Test\TestCase { $this->tokenProvider = $this->createMock(IProvider::class); $this->config = $this->createMock(IConfig::class); $this->throttler = $this->createMock(Throttler::class); + $this->random = $this->createMock(ISecureRandom::class); + $this->manager = $this->createMock(IUserManager::class); + $this->session = $this->createMock(ISession::class); + $this->userSession = $this->getMockBuilder(Session::class) + ->setConstructorArgs([ + $this->manager, + $this->session, + $this->timeFactory, + $this->tokenProvider, + $this->config, + $this->random, + ]) + ->setMethods([ + 'setMagicInCookie', + ]) + ->getMock(); + + \OC_User::setIncognitoMode(false); } public function testGetUser() { @@ -100,12 +125,12 @@ class SessionTest extends \Test\TestCase { ->method('updateTokenActivity') ->with($token); - $manager->expects($this->any()) + $manager->expects($this->once()) ->method('get') ->with($expectedUser->getUID()) ->will($this->returnValue($expectedUser)); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random); $user = $userSession->getUser(); $this->assertSame($expectedUser, $user); $this->assertSame(10000, $token->getLastCheck()); @@ -127,7 +152,7 @@ class SessionTest extends \Test\TestCase { $manager = $this->createMock(Manager::class); $userSession = $this->getMockBuilder(Session::class) - ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) ->setMethods([ 'getUser' ]) @@ -154,7 +179,7 @@ class SessionTest extends \Test\TestCase { ->method('getUID') ->will($this->returnValue('foo')); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random); $userSession->setUser($user); } @@ -181,17 +206,10 @@ class SessionTest extends \Test\TestCase { }, 'foo')); $managerMethods = get_class_methods(Manager::class); - //keep following methods intact in order to ensure hooks are - //working - $doNotMock = array('__construct', 'emit', 'listen'); - foreach ($doNotMock as $methodName) { - $i = array_search($methodName, $managerMethods, true); - if ($i !== false) { - unset($managerMethods[$i]); - } - } + //keep following methods intact in order to ensure hooks are working + $mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']); $manager = $this->getMockBuilder(Manager::class) - ->setMethods($managerMethods) + ->setMethods($mockedManagerMethods) ->setConstructorArgs([$this->config]) ->getMock(); @@ -213,7 +231,7 @@ class SessionTest extends \Test\TestCase { ->will($this->returnValue($user)); $userSession = $this->getMockBuilder(Session::class) - ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) ->setMethods([ 'prepareUserLogin' ]) @@ -238,18 +256,11 @@ class SessionTest extends \Test\TestCase { ->with('bar') ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException())); - $managerMethods = get_class_methods('\OC\User\Manager'); - //keep following methods intact in order to ensure hooks are - //working - $doNotMock = array('__construct', 'emit', 'listen'); - foreach ($doNotMock as $methodName) { - $i = array_search($methodName, $managerMethods, true); - if ($i !== false) { - unset($managerMethods[$i]); - } - } + $managerMethods = get_class_methods(\OC\User\Manager::class); + //keep following methods intact in order to ensure hooks are working + $mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']); $manager = $this->getMockBuilder(Manager::class) - ->setMethods($managerMethods) + ->setMethods($mockedManagerMethods) ->setConstructorArgs([$this->config]) ->getMock(); @@ -267,28 +278,21 @@ class SessionTest extends \Test\TestCase { ->with('foo', 'bar') ->will($this->returnValue($user)); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random); $userSession->login('foo', 'bar'); } public function testLoginInvalidPassword() { $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock(); - $managerMethods = get_class_methods('\OC\User\Manager'); - //keep following methods intact in order to ensure hooks are - //working - $doNotMock = array('__construct', 'emit', 'listen'); - foreach ($doNotMock as $methodName) { - $i = array_search($methodName, $managerMethods, true); - if ($i !== false) { - unset($managerMethods[$i]); - } - } + $managerMethods = get_class_methods(\OC\User\Manager::class); + //keep following methods intact in order to ensure hooks are working + $mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']); $manager = $this->getMockBuilder(Manager::class) - ->setMethods($managerMethods) + ->setMethods($mockedManagerMethods) ->setConstructorArgs([$this->config]) ->getMock(); $backend = $this->createMock(\Test\Util\User\Dummy::class); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random); $user = $this->getMockBuilder(User::class)->setConstructorArgs(['foo', $backend])->getMock(); @@ -317,7 +321,7 @@ class SessionTest extends \Test\TestCase { public function testLoginNonExisting() { $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock(); $manager = $this->createMock(Manager::class); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random); $session->expects($this->never()) ->method('set'); @@ -343,7 +347,7 @@ class SessionTest extends \Test\TestCase { public function testLoginWithDifferentTokenLoginName() { $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock(); $manager = $this->createMock(Manager::class); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random); $username = 'user123'; $token = new \OC\Authentication\Token\DefaultToken(); $token->setLoginName($username); @@ -375,7 +379,7 @@ class SessionTest extends \Test\TestCase { /** @var \OC\User\Session $userSession */ $userSession = $this->getMockBuilder(Session::class) - ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) ->setMethods(['login', 'supportsCookies', 'createSessionToken', 'getUser']) ->getMock(); @@ -411,7 +415,7 @@ class SessionTest extends \Test\TestCase { /** @var Session $userSession */ $userSession = $this->getMockBuilder(Session::class) - ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) ->setMethods(['login', 'supportsCookies', 'createSessionToken', 'getUser']) ->getMock(); @@ -434,7 +438,7 @@ class SessionTest extends \Test\TestCase { /** @var \OC\User\Session $userSession */ $userSession = $this->getMockBuilder(Session::class) - ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) ->setMethods(['isTokenPassword', 'login', 'supportsCookies', 'createSessionToken', 'getUser']) ->getMock(); @@ -476,7 +480,7 @@ class SessionTest extends \Test\TestCase { /** @var \OC\User\Session $userSession */ $userSession = $this->getMockBuilder(Session::class) - ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) ->setMethods(['login', 'isTwoFactorEnforced']) ->getMock(); @@ -513,156 +517,216 @@ class SessionTest extends \Test\TestCase { public function testRememberLoginValidToken() { $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock(); - $session->expects($this->exactly(1)) - ->method('set') - ->with($this->callback(function ($key) { - switch ($key) { - case 'user_id': - return true; - default: - return false; - } - }, 'foo')); - $session->expects($this->once()) - ->method('regenerateId'); - - $managerMethods = get_class_methods(Manager::class); - //keep following methods intact in order to ensure hooks are - //working - $doNotMock = array('__construct', 'emit', 'listen'); - foreach ($doNotMock as $methodName) { - $i = array_search($methodName, $managerMethods, true); - if ($i !== false) { - unset($managerMethods[$i]); - } - } + $managerMethods = get_class_methods(\OC\User\Manager::class); + //keep following methods intact in order to ensure hooks are working + $mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']); $manager = $this->getMockBuilder(Manager::class) - ->setMethods($managerMethods) + ->setMethods($mockedManagerMethods) ->setConstructorArgs([$this->config]) ->getMock(); + $userSession = $this->getMockBuilder(Session::class) + //override, otherwise tests will fail because of setcookie() + ->setMethods(['setMagicInCookie']) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) + ->getMock(); - $backend = $this->createMock(\Test\Util\User\Dummy::class); + $user = $this->createMock(IUser::class); + $token = 'goodToken'; + $oldSessionId = 'sess321'; + $sessionId = 'sess123'; - $user = $this->getMockBuilder(User::class)->setConstructorArgs(['foo', $backend])->getMock(); + $session->expects($this->once()) + ->method('regenerateId'); + $manager->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue($user)); + $this->config->expects($this->once()) + ->method('getUserKeys') + ->with('foo', 'login_token') + ->will($this->returnValue([$token])); + $this->config->expects($this->once()) + ->method('deleteUserValue') + ->with('foo', 'login_token', $token); + $this->random->expects($this->once()) + ->method('generate') + ->with(32) + ->will($this->returnValue('abcdefg123456')); + $this->config->expects($this->once()) + ->method('setUserValue') + ->with('foo', 'login_token', 'abcdefg123456', 10000); + + $session->expects($this->once()) + ->method('getId') + ->will($this->returnValue($sessionId)); + $this->tokenProvider->expects($this->once()) + ->method('renewSessionToken') + ->with($oldSessionId, $sessionId) + ->will($this->returnValue(true)); $user->expects($this->any()) ->method('getUID') ->will($this->returnValue('foo')); + $userSession->expects($this->once()) + ->method('setMagicInCookie'); $user->expects($this->once()) ->method('updateLastLoginTimestamp'); + $session->expects($this->once()) + ->method('set') + ->with('user_id', 'foo'); - $manager->expects($this->once()) - ->method('get') - ->with('foo') - ->will($this->returnValue($user)); + $granted = $userSession->loginWithCookie('foo', $token, $oldSessionId); - //prepare login token - $token = 'goodToken'; - \OC::$server->getConfig()->setUserValue('foo', 'login_token', $token, time()); + $this->assertTrue($granted); + } + public function testRememberLoginInvalidSessionToken() { + $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock(); + $managerMethods = get_class_methods(\OC\User\Manager::class); + //keep following methods intact in order to ensure hooks are working + $mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']); + $manager = $this->getMockBuilder(Manager::class) + ->setMethods($mockedManagerMethods) + ->setConstructorArgs([$this->config]) + ->getMock(); $userSession = $this->getMockBuilder(Session::class) //override, otherwise tests will fail because of setcookie() ->setMethods(['setMagicInCookie']) - //there are passed as parameters to the constructor - ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) ->getMock(); - $granted = $userSession->loginWithCookie('foo', $token); - - $this->assertSame($granted, true); - } + $user = $this->createMock(IUser::class); + $token = 'goodToken'; + $oldSessionId = 'sess321'; + $sessionId = 'sess123'; - public function testRememberLoginInvalidToken() { - $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock(); - $session->expects($this->never()) - ->method('set'); $session->expects($this->once()) ->method('regenerateId'); + $manager->expects($this->once()) + ->method('get') + ->with('foo') + ->will($this->returnValue($user)); + $this->config->expects($this->once()) + ->method('getUserKeys') + ->with('foo', 'login_token') + ->will($this->returnValue([$token])); + $this->config->expects($this->once()) + ->method('deleteUserValue') + ->with('foo', 'login_token', $token); + $this->config->expects($this->once()) + ->method('setUserValue'); // TODO: mock new random value - $managerMethods = get_class_methods('\OC\User\Manager'); - //keep following methods intact in order to ensure hooks are - //working - $doNotMock = array('__construct', 'emit', 'listen'); - foreach ($doNotMock as $methodName) { - $i = array_search($methodName, $managerMethods, true); - if ($i !== false) { - unset($managerMethods[$i]); - } - } - $manager = $this->getMockBuilder(Manager::class) - ->setMethods($managerMethods) - ->setConstructorArgs([$this->config]) - ->getMock(); - - $backend = $this->createMock(\Test\Util\User\Dummy::class); - - $user = $this->getMockBuilder(User::class)->setConstructorArgs(['foo', $backend])->getMock(); + $session->expects($this->once()) + ->method('getId') + ->will($this->returnValue($sessionId)); + $this->tokenProvider->expects($this->once()) + ->method('renewSessionToken') + ->with($oldSessionId, $sessionId) + ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException())); - $user->expects($this->any()) + $user->expects($this->never()) ->method('getUID') ->will($this->returnValue('foo')); + $userSession->expects($this->never()) + ->method('setMagicInCookie'); $user->expects($this->never()) ->method('updateLastLoginTimestamp'); + $session->expects($this->never()) + ->method('set') + ->with('user_id', 'foo'); + $granted = $userSession->loginWithCookie('foo', $token, $oldSessionId); + + $this->assertFalse($granted); + } + + public function testRememberLoginInvalidToken() { + $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock(); + $managerMethods = get_class_methods(\OC\User\Manager::class); + //keep following methods intact in order to ensure hooks are working + $mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']); + $manager = $this->getMockBuilder(Manager::class) + ->setMethods($mockedManagerMethods) + ->setConstructorArgs([$this->config]) + ->getMock(); + $userSession = $this->getMockBuilder(Session::class) + //override, otherwise tests will fail because of setcookie() + ->setMethods(['setMagicInCookie']) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) + ->getMock(); + + $user = $this->createMock(IUser::class); + $token = 'goodToken'; + $oldSessionId = 'sess321'; + + $session->expects($this->once()) + ->method('regenerateId'); $manager->expects($this->once()) ->method('get') ->with('foo') ->will($this->returnValue($user)); + $this->config->expects($this->once()) + ->method('getUserKeys') + ->with('foo', 'login_token') + ->will($this->returnValue(['anothertoken'])); + $this->config->expects($this->never()) + ->method('deleteUserValue') + ->with('foo', 'login_token', $token); + + $this->tokenProvider->expects($this->never()) + ->method('renewSessionToken'); + $userSession->expects($this->never()) + ->method('setMagicInCookie'); + $user->expects($this->never()) + ->method('updateLastLoginTimestamp'); + $session->expects($this->never()) + ->method('set') + ->with('user_id', 'foo'); - //prepare login token - $token = 'goodToken'; - \OC::$server->getConfig()->setUserValue('foo', 'login_token', $token, time()); - - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); - $granted = $userSession->loginWithCookie('foo', 'badToken'); + $granted = $userSession->loginWithCookie('foo', $token, $oldSessionId); - $this->assertSame($granted, false); + $this->assertFalse($granted); } public function testRememberLoginInvalidUser() { $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock(); - $session->expects($this->never()) - ->method('set'); - $session->expects($this->once()) - ->method('regenerateId'); - - $managerMethods = get_class_methods('\OC\User\Manager'); - //keep following methods intact in order to ensure hooks are - //working - $doNotMock = array('__construct', 'emit', 'listen'); - foreach ($doNotMock as $methodName) { - $i = array_search($methodName, $managerMethods, true); - if ($i !== false) { - unset($managerMethods[$i]); - } - } + $managerMethods = get_class_methods(\OC\User\Manager::class); + //keep following methods intact in order to ensure hooks are working + $mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']); $manager = $this->getMockBuilder(Manager::class) - ->setMethods($managerMethods) + ->setMethods($mockedManagerMethods) ->setConstructorArgs([$this->config]) ->getMock(); + $userSession = $this->getMockBuilder(Session::class) + //override, otherwise tests will fail because of setcookie() + ->setMethods(['setMagicInCookie']) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) + ->getMock(); + $token = 'goodToken'; + $oldSessionId = 'sess321'; - $backend = $this->createMock(\Test\Util\User\Dummy::class); - - $user = $this->getMockBuilder(User::class)->setConstructorArgs(['foo', $backend])->getMock(); - - $user->expects($this->never()) - ->method('getUID'); - $user->expects($this->never()) - ->method('updateLastLoginTimestamp'); - + $session->expects($this->once()) + ->method('regenerateId'); $manager->expects($this->once()) ->method('get') ->with('foo') ->will($this->returnValue(null)); + $this->config->expects($this->never()) + ->method('getUserKeys') + ->with('foo', 'login_token') + ->will($this->returnValue(['anothertoken'])); + + $this->tokenProvider->expects($this->never()) + ->method('renewSessionToken'); + $userSession->expects($this->never()) + ->method('setMagicInCookie'); + $session->expects($this->never()) + ->method('set') + ->with('user_id', 'foo'); - //prepare login token - $token = 'goodToken'; - \OC::$server->getConfig()->setUserValue('foo', 'login_token', $token, time()); - - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); - $granted = $userSession->loginWithCookie('foo', $token); + $granted = $userSession->loginWithCookie('foo', $token, $oldSessionId); - $this->assertSame($granted, false); + $this->assertFalse($granted); } public function testActiveUserAfterSetSession() { @@ -684,7 +748,7 @@ class SessionTest extends \Test\TestCase { $session = new Memory(''); $session->set('user_id', 'foo'); $userSession = $this->getMockBuilder('\OC\User\Session') - ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) ->setMethods([ 'validateSession' ]) @@ -705,7 +769,7 @@ class SessionTest extends \Test\TestCase { $session = $this->createMock(ISession::class); $token = $this->createMock(IToken::class); $user = $this->createMock(IUser::class); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random); $random = $this->createMock(ISecureRandom::class); $config = $this->createMock(IConfig::class); @@ -749,7 +813,7 @@ class SessionTest extends \Test\TestCase { $session = $this->createMock(ISession::class); $token = $this->createMock(IToken::class); $user = $this->createMock(IUser::class); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random); $random = $this->createMock(ISecureRandom::class); $config = $this->createMock(IConfig::class); @@ -796,7 +860,7 @@ class SessionTest extends \Test\TestCase { ->disableOriginalConstructor() ->getMock(); $session = $this->createMock(ISession::class); - $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config); + $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random); $request = $this->createMock(IRequest::class); $uid = 'user123'; @@ -826,7 +890,7 @@ class SessionTest extends \Test\TestCase { $user = $this->createMock(IUser::class); $userSession = $this->getMockBuilder('\OC\User\Session') ->setMethods(['logout']) - ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config]) + ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random]) ->getMock(); $request = $this->createMock(IRequest::class); @@ -855,7 +919,7 @@ class SessionTest extends \Test\TestCase { $timeFactory = $this->createMock(ITimeFactory::class); $tokenProvider = $this->createMock(IProvider::class); $userSession = $this->getMockBuilder('\OC\User\Session') - ->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config]) + ->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random]) ->setMethods(['logout']) ->getMock(); @@ -902,7 +966,7 @@ class SessionTest extends \Test\TestCase { $timeFactory = $this->createMock(ITimeFactory::class); $tokenProvider = $this->createMock(IProvider::class); $userSession = $this->getMockBuilder('\OC\User\Session') - ->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config]) + ->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random]) ->setMethods(['logout']) ->getMock(); @@ -936,7 +1000,7 @@ class SessionTest extends \Test\TestCase { $session = $this->createMock(ISession::class); $timeFactory = $this->createMock(ITimeFactory::class); $tokenProvider = $this->createMock(IProvider::class); - $userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config); + $userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random); $password = '123456'; $sessionId = 'session1234'; @@ -961,7 +1025,7 @@ class SessionTest extends \Test\TestCase { $session = $this->createMock(ISession::class); $timeFactory = $this->createMock(ITimeFactory::class); $tokenProvider = $this->createMock(IProvider::class); - $userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config); + $userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random); $session->expects($this->once()) ->method('getId') @@ -975,7 +1039,7 @@ class SessionTest extends \Test\TestCase { $session = $this->createMock(ISession::class); $timeFactory = $this->createMock(ITimeFactory::class); $tokenProvider = $this->createMock(IProvider::class); - $userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config); + $userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random); $password = '123456'; $sessionId = 'session1234'; @@ -1015,7 +1079,7 @@ class SessionTest extends \Test\TestCase { $tokenProvider = new DefaultTokenProvider($mapper, $crypto, $this->config, $logger, $this->timeFactory); /** @var \OC\User\Session $userSession */ - $userSession = new Session($manager, $session, $this->timeFactory, $tokenProvider, $this->config); + $userSession = new Session($manager, $session, $this->timeFactory, $tokenProvider, $this->config, $this->random); $mapper->expects($this->any()) ->method('getToken') @@ -1065,7 +1129,7 @@ class SessionTest extends \Test\TestCase { $tokenProvider = new DefaultTokenProvider($mapper, $crypto, $this->config, $logger, $this->timeFactory); /** @var \OC\User\Session $userSession */ - $userSession = new Session($manager, $session, $this->timeFactory, $tokenProvider, $this->config); + $userSession = new Session($manager, $session, $this->timeFactory, $tokenProvider, $this->config, $this->random); $mapper->expects($this->any()) ->method('getToken') @@ -1092,4 +1156,27 @@ class SessionTest extends \Test\TestCase { $userSession->logClientIn('john', 'doe', $request, $this->throttler); } + + public function testCreateRememberMeToken() { + $user = $this->createMock(IUser::class); + $user + ->expects($this->exactly(2)) + ->method('getUID') + ->willReturn('UserUid'); + $this->random + ->expects($this->once()) + ->method('generate') + ->with(32) + ->willReturn('LongRandomToken'); + $this->config + ->expects($this->once()) + ->method('setUserValue') + ->with('UserUid', 'login_token', 'LongRandomToken', 10000); + $this->userSession + ->expects($this->once()) + ->method('setMagicInCookie') + ->with('UserUid', 'LongRandomToken'); + + $this->userSession->createRememberMeToken($user); + } } |