UrlGeneratorTest.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. <?php
  2. /**
  3. * Copyright (c) 2014 Bjoern Schiessle <schiessle@owncloud.com>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. namespace Test;
  9. use OC\Route\Router;
  10. use OCP\ICacheFactory;
  11. use OCP\IConfig;
  12. use OCP\IRequest;
  13. use OCP\IURLGenerator;
  14. use OCP\IUser;
  15. use OCP\IUserSession;
  16. /**
  17. * Class UrlGeneratorTest
  18. *
  19. * @package Test
  20. */
  21. class UrlGeneratorTest extends \Test\TestCase {
  22. /** @var \PHPUnit\Framework\MockObject\MockObject|IConfig */
  23. private $config;
  24. /** @var \PHPUnit\Framework\MockObject\MockObject|IUserSession */
  25. private $userSession;
  26. /** @var \PHPUnit\Framework\MockObject\MockObject|ICacheFactory */
  27. private $cacheFactory;
  28. /** @var \PHPUnit\Framework\MockObject\MockObject|IRequest */
  29. private $request;
  30. /** @var \PHPUnit\Framework\MockObject\MockObject|Router */
  31. private $router;
  32. /** @var IURLGenerator */
  33. private $urlGenerator;
  34. /** @var string */
  35. private $originalWebRoot;
  36. protected function setUp(): void {
  37. parent::setUp();
  38. $this->config = $this->createMock(IConfig::class);
  39. $this->userSession = $this->createMock(IUserSession::class);
  40. $this->cacheFactory = $this->createMock(ICacheFactory::class);
  41. $this->request = $this->createMock(IRequest::class);
  42. $this->router = $this->createMock(Router::class);
  43. $this->urlGenerator = new \OC\URLGenerator(
  44. $this->config,
  45. $this->userSession,
  46. $this->cacheFactory,
  47. $this->request,
  48. $this->router
  49. );
  50. $this->originalWebRoot = \OC::$WEBROOT;
  51. }
  52. protected function tearDown(): void {
  53. // Reset webRoot
  54. \OC::$WEBROOT = $this->originalWebRoot;
  55. }
  56. private function mockBaseUrl() {
  57. $this->request->expects($this->once())
  58. ->method('getServerProtocol')
  59. ->willReturn('http');
  60. $this->request->expects($this->once())
  61. ->method('getServerHost')
  62. ->willReturn('localhost');
  63. }
  64. /**
  65. * @small
  66. * test linkTo URL construction
  67. * @dataProvider provideDocRootAppUrlParts
  68. */
  69. public function testLinkToDocRoot($app, $file, $args, $expectedResult) {
  70. \OC::$WEBROOT = '';
  71. $result = $this->urlGenerator->linkTo($app, $file, $args);
  72. $this->assertEquals($expectedResult, $result);
  73. }
  74. /**
  75. * @small
  76. * test linkTo URL construction in sub directory
  77. * @dataProvider provideSubDirAppUrlParts
  78. */
  79. public function testLinkToSubDir($app, $file, $args, $expectedResult) {
  80. \OC::$WEBROOT = '/nextcloud';
  81. $result = $this->urlGenerator->linkTo($app, $file, $args);
  82. $this->assertEquals($expectedResult, $result);
  83. }
  84. /**
  85. * @dataProvider provideRoutes
  86. */
  87. public function testLinkToRouteAbsolute($route, $expected) {
  88. $this->mockBaseUrl();
  89. \OC::$WEBROOT = '/nextcloud';
  90. $this->router->expects($this->once())
  91. ->method('generate')
  92. ->willReturnCallback(function ($routeName, $parameters) {
  93. if ($routeName === 'core.Preview.getPreview') {
  94. return '/index.php/core/preview.png';
  95. } elseif ($routeName === 'cloud_federation_api.requesthandlercontroller.addShare') {
  96. return '/index.php/ocm/shares';
  97. }
  98. });
  99. $result = $this->urlGenerator->linkToRouteAbsolute($route);
  100. $this->assertEquals($expected, $result);
  101. }
  102. public function provideRoutes() {
  103. return [
  104. ['core.Preview.getPreview', 'http://localhost/nextcloud/index.php/core/preview.png'],
  105. ['cloud_federation_api.requesthandlercontroller.addShare', 'http://localhost/nextcloud/index.php/ocm/shares'],
  106. ];
  107. }
  108. public function provideDocRootAppUrlParts() {
  109. return [
  110. ['files', 'ajax/download.php', [], '/index.php/apps/files/ajax/download.php'],
  111. ['files', 'ajax/download.php', ['trut' => 'trat', 'dut' => 'dat'], '/index.php/apps/files/ajax/download.php?trut=trat&dut=dat'],
  112. ['', 'index.php', ['trut' => 'trat', 'dut' => 'dat'], '/index.php?trut=trat&dut=dat'],
  113. ];
  114. }
  115. public function provideSubDirAppUrlParts() {
  116. return [
  117. ['files', 'ajax/download.php', [], '/nextcloud/index.php/apps/files/ajax/download.php'],
  118. ['files', 'ajax/download.php', ['trut' => 'trat', 'dut' => 'dat'], '/nextcloud/index.php/apps/files/ajax/download.php?trut=trat&dut=dat'],
  119. ['', 'index.php', ['trut' => 'trat', 'dut' => 'dat'], '/nextcloud/index.php?trut=trat&dut=dat'],
  120. ];
  121. }
  122. /**
  123. * @small
  124. * test absolute URL construction
  125. * @dataProvider provideDocRootURLs
  126. */
  127. public function testGetAbsoluteURLDocRoot($url, $expectedResult) {
  128. $this->mockBaseUrl();
  129. \OC::$WEBROOT = '';
  130. $result = $this->urlGenerator->getAbsoluteURL($url);
  131. $this->assertEquals($expectedResult, $result);
  132. }
  133. /**
  134. * @small
  135. * test absolute URL construction
  136. * @dataProvider provideSubDirURLs
  137. */
  138. public function testGetAbsoluteURLSubDir($url, $expectedResult) {
  139. $this->mockBaseUrl();
  140. \OC::$WEBROOT = '/nextcloud';
  141. $result = $this->urlGenerator->getAbsoluteURL($url);
  142. $this->assertEquals($expectedResult, $result);
  143. }
  144. public function provideDocRootURLs() {
  145. return [
  146. ['index.php', 'http://localhost/index.php'],
  147. ['/index.php', 'http://localhost/index.php'],
  148. ['/apps/index.php', 'http://localhost/apps/index.php'],
  149. ['apps/index.php', 'http://localhost/apps/index.php'],
  150. ];
  151. }
  152. public function provideSubDirURLs() {
  153. return [
  154. ['', 'http://localhost/nextcloud/'],
  155. ['/', 'http://localhost/nextcloud/'],
  156. ['index.php', 'http://localhost/nextcloud/index.php'],
  157. ['/index.php', 'http://localhost/nextcloud/index.php'],
  158. ['/apps/index.php', 'http://localhost/nextcloud/apps/index.php'],
  159. ['apps/index.php', 'http://localhost/nextcloud/apps/index.php'],
  160. ];
  161. }
  162. public function testGetBaseUrl() {
  163. $this->mockBaseUrl();
  164. \OC::$WEBROOT = '/nextcloud';
  165. $actual = $this->urlGenerator->getBaseUrl();
  166. $expected = 'http://localhost/nextcloud';
  167. $this->assertEquals($expected, $actual);
  168. }
  169. public function testGetWebroot() {
  170. \OC::$WEBROOT = '/nextcloud';
  171. $actual = $this->urlGenerator->getWebroot();
  172. $this->assertEquals(\OC::$WEBROOT, $actual);
  173. }
  174. /**
  175. * @dataProvider provideOCSRoutes
  176. */
  177. public function testLinkToOCSRouteAbsolute(string $route, string $expected) {
  178. $this->mockBaseUrl();
  179. \OC::$WEBROOT = '/nextcloud';
  180. $this->router->expects($this->once())
  181. ->method('generate')
  182. ->willReturnCallback(function ($routeName, $parameters) {
  183. if ($routeName === 'ocs.core.OCS.getCapabilities') {
  184. return '/index.php/ocsapp/cloud/capabilities';
  185. } elseif ($routeName === 'ocs.core.WhatsNew.dismiss') {
  186. return '/index.php/ocsapp/core/whatsnew';
  187. }
  188. });
  189. $result = $this->urlGenerator->linkToOCSRouteAbsolute($route);
  190. $this->assertEquals($expected, $result);
  191. }
  192. public function provideOCSRoutes() {
  193. return [
  194. ['core.OCS.getCapabilities', 'http://localhost/nextcloud/ocs/v2.php/cloud/capabilities'],
  195. ['core.WhatsNew.dismiss', 'http://localhost/nextcloud/ocs/v2.php/core/whatsnew'],
  196. ];
  197. }
  198. private function mockLinkToDefaultPageUrl(string $defaultAppConfig = '', bool $ignoreFrontControllerConfig = false) {
  199. $this->config->expects($this->exactly(2))
  200. ->method('getSystemValue')
  201. ->withConsecutive(
  202. ['defaultapp', $this->anything()],
  203. ['htaccess.IgnoreFrontController', $this->anything()],
  204. )
  205. ->will($this->onConsecutiveCalls(
  206. $defaultAppConfig,
  207. $ignoreFrontControllerConfig
  208. ));
  209. $this->config->expects($this->once())
  210. ->method('getAppValue')
  211. ->with('core', 'defaultpage')
  212. ->willReturn('');
  213. }
  214. public function testLinkToDefaultPageUrlWithRedirectUrlWithoutFrontController() {
  215. $this->mockBaseUrl();
  216. $_REQUEST['redirect_url'] = 'myRedirectUrl.com';
  217. $this->assertSame('http://localhost' . \OC::$WEBROOT . '/myRedirectUrl.com', $this->urlGenerator->linkToDefaultPageUrl());
  218. }
  219. public function testLinkToDefaultPageUrlWithRedirectUrlRedirectBypassWithoutFrontController() {
  220. $this->mockBaseUrl();
  221. $this->mockLinkToDefaultPageUrl();
  222. putenv('front_controller_active=false');
  223. $_REQUEST['redirect_url'] = 'myRedirectUrl.com@foo.com:a';
  224. $this->assertSame('http://localhost' . \OC::$WEBROOT . '/index.php/apps/files/', $this->urlGenerator->linkToDefaultPageUrl());
  225. }
  226. public function testLinkToDefaultPageUrlWithRedirectUrlRedirectBypassWithFrontController() {
  227. $this->mockBaseUrl();
  228. $this->mockLinkToDefaultPageUrl();
  229. putenv('front_controller_active=true');
  230. $_REQUEST['redirect_url'] = 'myRedirectUrl.com@foo.com:a';
  231. $this->assertSame('http://localhost' . \OC::$WEBROOT . '/apps/files/', $this->urlGenerator->linkToDefaultPageUrl());
  232. }
  233. public function testLinkToDefaultPageUrlWithRedirectUrlWithIgnoreFrontController() {
  234. $this->mockBaseUrl();
  235. $this->mockLinkToDefaultPageUrl('', true);
  236. putenv('front_controller_active=false');
  237. $_REQUEST['redirect_url'] = 'myRedirectUrl.com@foo.com:a';
  238. $this->assertSame('http://localhost' . \OC::$WEBROOT . '/apps/files/', $this->urlGenerator->linkToDefaultPageUrl());
  239. }
  240. /**
  241. * @dataProvider provideDefaultApps
  242. */
  243. public function testLinkToDefaultPageUrlWithDefaultApps($defaultAppConfig, $expectedPath) {
  244. $userId = $this->getUniqueID();
  245. /** @var \PHPUnit\Framework\MockObject\MockObject|IUser $userMock */
  246. $userMock = $this->createMock(IUser::class);
  247. $userMock->expects($this->once())
  248. ->method('getUID')
  249. ->willReturn($userId);
  250. $this->mockBaseUrl();
  251. $this->mockLinkToDefaultPageUrl($defaultAppConfig);
  252. $this->config->expects($this->once())
  253. ->method('getUserValue')
  254. ->with($userId, 'core', 'defaultapp')
  255. ->willReturn('');
  256. $this->userSession->expects($this->once())
  257. ->method('isLoggedIn')
  258. ->willReturn(true);
  259. $this->userSession->expects($this->once())
  260. ->method('getUser')
  261. ->willReturn($userMock);
  262. $this->assertEquals('http://localhost' . \OC::$WEBROOT . $expectedPath, $this->urlGenerator->linkToDefaultPageUrl());
  263. }
  264. public function provideDefaultApps(): array {
  265. return [
  266. // none specified, default to files
  267. [
  268. '',
  269. '/index.php/apps/files/',
  270. ],
  271. // unexisting or inaccessible app specified, default to files
  272. [
  273. 'unexist',
  274. '/index.php/apps/files/',
  275. ],
  276. // non-standard app
  277. [
  278. 'settings',
  279. '/index.php/apps/settings/',
  280. ],
  281. // non-standard app with fallback
  282. [
  283. 'unexist,settings',
  284. '/index.php/apps/settings/',
  285. ],
  286. ];
  287. }
  288. public function imagePathProvider(): array {
  289. return [
  290. ['core', 'favicon-mask.svg', \OC::$WEBROOT . '/core/img/favicon-mask.svg'],
  291. ['files', 'external.svg', \OC::$WEBROOT . '/apps/files/img/external.svg'],
  292. ];
  293. }
  294. /**
  295. * @dataProvider imagePathProvider
  296. */
  297. public function testImagePath(string $appName, string $file, string $result): void {
  298. $this->assertSame($result, $this->urlGenerator->imagePath($appName, $file));
  299. }
  300. }