UtilsTest.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. <?php
  2. use Codeception\Util\Fixtures;
  3. use Grav\Common\Grav;
  4. use Grav\Common\Uri;
  5. use Grav\Common\Utils;
  6. /**
  7. * Class UtilsTest
  8. */
  9. class UtilsTest extends \Codeception\TestCase\Test
  10. {
  11. /** @var Grav $grav */
  12. protected $grav;
  13. /** @var Uri $uri */
  14. protected $uri;
  15. protected function _before(): void
  16. {
  17. $grav = Fixtures::get('grav');
  18. $this->grav = $grav();
  19. $this->uri = $this->grav['uri'];
  20. }
  21. protected function _after(): void
  22. {
  23. }
  24. public function testStartsWith(): void
  25. {
  26. self::assertTrue(Utils::startsWith('english', 'en'));
  27. self::assertTrue(Utils::startsWith('English', 'En'));
  28. self::assertTrue(Utils::startsWith('ENGLISH', 'EN'));
  29. self::assertTrue(Utils::startsWith(
  30. 'ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH',
  31. 'EN'
  32. ));
  33. self::assertFalse(Utils::startsWith('english', 'En'));
  34. self::assertFalse(Utils::startsWith('English', 'EN'));
  35. self::assertFalse(Utils::startsWith('ENGLISH', 'en'));
  36. self::assertFalse(Utils::startsWith(
  37. 'ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH',
  38. 'e'
  39. ));
  40. self::assertTrue(Utils::startsWith('english', 'En', false));
  41. self::assertTrue(Utils::startsWith('English', 'EN', false));
  42. self::assertTrue(Utils::startsWith('ENGLISH', 'en', false));
  43. self::assertTrue(Utils::startsWith(
  44. 'ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH',
  45. 'e',
  46. false
  47. ));
  48. }
  49. public function testEndsWith(): void
  50. {
  51. self::assertTrue(Utils::endsWith('english', 'sh'));
  52. self::assertTrue(Utils::endsWith('EngliSh', 'Sh'));
  53. self::assertTrue(Utils::endsWith('ENGLISH', 'SH'));
  54. self::assertTrue(Utils::endsWith(
  55. 'ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH',
  56. 'ENGLISH'
  57. ));
  58. self::assertFalse(Utils::endsWith('english', 'de'));
  59. self::assertFalse(Utils::endsWith('EngliSh', 'sh'));
  60. self::assertFalse(Utils::endsWith('ENGLISH', 'Sh'));
  61. self::assertFalse(Utils::endsWith(
  62. 'ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH',
  63. 'DEUSTCH'
  64. ));
  65. self::assertTrue(Utils::endsWith('english', 'SH', false));
  66. self::assertTrue(Utils::endsWith('EngliSh', 'sH', false));
  67. self::assertTrue(Utils::endsWith('ENGLISH', 'sh', false));
  68. self::assertTrue(Utils::endsWith(
  69. 'ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH',
  70. 'english',
  71. false
  72. ));
  73. }
  74. public function testContains(): void
  75. {
  76. self::assertTrue(Utils::contains('english', 'nglis'));
  77. self::assertTrue(Utils::contains('EngliSh', 'gliSh'));
  78. self::assertTrue(Utils::contains('ENGLISH', 'ENGLI'));
  79. self::assertTrue(Utils::contains(
  80. 'ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH',
  81. 'ENGLISH'
  82. ));
  83. self::assertFalse(Utils::contains('EngliSh', 'GLI'));
  84. self::assertFalse(Utils::contains('EngliSh', 'English'));
  85. self::assertFalse(Utils::contains('ENGLISH', 'SCH'));
  86. self::assertFalse(Utils::contains(
  87. 'ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH',
  88. 'DEUSTCH'
  89. ));
  90. self::assertTrue(Utils::contains('EngliSh', 'GLI', false));
  91. self::assertTrue(Utils::contains('EngliSh', 'ENGLISH', false));
  92. self::assertTrue(Utils::contains('ENGLISH', 'ish', false));
  93. self::assertTrue(Utils::contains(
  94. 'ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH',
  95. 'english',
  96. false
  97. ));
  98. }
  99. public function testSubstrToString(): void
  100. {
  101. self::assertEquals('en', Utils::substrToString('english', 'glish'));
  102. self::assertEquals('english', Utils::substrToString('english', 'test'));
  103. self::assertNotEquals('en', Utils::substrToString('english', 'lish'));
  104. self::assertEquals('en', Utils::substrToString('english', 'GLISH', false));
  105. self::assertEquals('english', Utils::substrToString('english', 'TEST', false));
  106. self::assertNotEquals('en', Utils::substrToString('english', 'LISH', false));
  107. }
  108. public function testMergeObjects(): void
  109. {
  110. $obj1 = new stdClass();
  111. $obj1->test1 = 'x';
  112. $obj2 = new stdClass();
  113. $obj2->test2 = 'y';
  114. $objMerged = Utils::mergeObjects($obj1, $obj2);
  115. self::assertObjectHasAttribute('test1', $objMerged);
  116. self::assertObjectHasAttribute('test2', $objMerged);
  117. }
  118. public function testDateFormats(): void
  119. {
  120. $dateFormats = Utils::dateFormats();
  121. self::assertIsArray($dateFormats);
  122. self::assertContainsOnly('string', $dateFormats);
  123. $default_format = $this->grav['config']->get('system.pages.dateformat.default');
  124. if ($default_format !== null) {
  125. self::assertArrayHasKey($default_format, $dateFormats);
  126. }
  127. }
  128. public function testTruncate(): void
  129. {
  130. self::assertEquals('engli' . '&hellip;', Utils::truncate('english', 5));
  131. self::assertEquals('english', Utils::truncate('english'));
  132. self::assertEquals('This is a string to truncate', Utils::truncate('This is a string to truncate'));
  133. self::assertEquals('Th' . '&hellip;', Utils::truncate('This is a string to truncate', 2));
  134. self::assertEquals('engli' . '...', Utils::truncate('english', 5, true, " ", "..."));
  135. self::assertEquals('english', Utils::truncate('english'));
  136. self::assertEquals('This is a string to truncate', Utils::truncate('This is a string to truncate'));
  137. self::assertEquals('This' . '&hellip;', Utils::truncate('This is a string to truncate', 3, true));
  138. self::assertEquals('<input' . '&hellip;', Utils::truncate('<input type="file" id="file" multiple />', 6, true));
  139. }
  140. public function testSafeTruncate(): void
  141. {
  142. self::assertEquals('This' . '&hellip;', Utils::safeTruncate('This is a string to truncate', 1));
  143. self::assertEquals('This' . '&hellip;', Utils::safeTruncate('This is a string to truncate', 4));
  144. self::assertEquals('This is' . '&hellip;', Utils::safeTruncate('This is a string to truncate', 5));
  145. }
  146. public function testTruncateHtml(): void
  147. {
  148. self::assertEquals('T...', Utils::truncateHtml('This is a string to truncate', 1));
  149. self::assertEquals('This is...', Utils::truncateHtml('This is a string to truncate', 7));
  150. self::assertEquals('<p>T...</p>', Utils::truncateHtml('<p>This is a string to truncate</p>', 1));
  151. self::assertEquals('<p>This...</p>', Utils::truncateHtml('<p>This is a string to truncate</p>', 4));
  152. self::assertEquals('<p>This is a...</p>', Utils::truncateHtml('<p>This is a string to truncate</p>', 10));
  153. self::assertEquals('<p>This is a string to truncate</p>', Utils::truncateHtml('<p>This is a string to truncate</p>', 100));
  154. self::assertEquals('<input type="file" id="file" multiple />', Utils::truncateHtml('<input type="file" id="file" multiple />', 6));
  155. self::assertEquals('<ol><li>item 1 <i>so...</i></li></ol>', Utils::truncateHtml('<ol><li>item 1 <i>something</i></li><li>item 2 <strong>bold</strong></li></ol>', 10));
  156. self::assertEquals("<p>This is a string.</p>\n<p>It splits two lines.</p>", Utils::truncateHtml("<p>This is a string.</p>\n<p>It splits two lines.</p>", 100));
  157. }
  158. public function testSafeTruncateHtml(): void
  159. {
  160. self::assertEquals('This...', Utils::safeTruncateHtml('This is a string to truncate', 1));
  161. self::assertEquals('This is a...', Utils::safeTruncateHtml('This is a string to truncate', 3));
  162. self::assertEquals('<p>This...</p>', Utils::safeTruncateHtml('<p>This is a string to truncate</p>', 1));
  163. self::assertEquals('<p>This is...</p>', Utils::safeTruncateHtml('<p>This is a string to truncate</p>', 2));
  164. self::assertEquals('<p>This is a string to...</p>', Utils::safeTruncateHtml('<p>This is a string to truncate</p>', 5));
  165. self::assertEquals('<p>This is a string to truncate</p>', Utils::safeTruncateHtml('<p>This is a string to truncate</p>', 20));
  166. self::assertEquals('<input type="file" id="file" multiple />', Utils::safeTruncateHtml('<input type="file" id="file" multiple />', 6));
  167. self::assertEquals('<ol><li>item 1 <i>something</i></li><li>item 2...</li></ol>', Utils::safeTruncateHtml('<ol><li>item 1 <i>something</i></li><li>item 2 <strong>bold</strong></li></ol>', 5));
  168. }
  169. public function testGenerateRandomString(): void
  170. {
  171. self::assertNotEquals(Utils::generateRandomString(), Utils::generateRandomString());
  172. self::assertNotEquals(Utils::generateRandomString(20), Utils::generateRandomString(20));
  173. }
  174. public function download(): void
  175. {
  176. }
  177. public function testGetMimeByExtension(): void
  178. {
  179. self::assertEquals('application/octet-stream', Utils::getMimeByExtension(''));
  180. self::assertEquals('text/html', Utils::getMimeByExtension('html'));
  181. self::assertEquals('application/json', Utils::getMimeByExtension('json'));
  182. self::assertEquals('application/atom+xml', Utils::getMimeByExtension('atom'));
  183. self::assertEquals('application/rss+xml', Utils::getMimeByExtension('rss'));
  184. self::assertEquals('image/jpeg', Utils::getMimeByExtension('jpg'));
  185. self::assertEquals('image/png', Utils::getMimeByExtension('png'));
  186. self::assertEquals('text/plain', Utils::getMimeByExtension('txt'));
  187. self::assertEquals('application/msword', Utils::getMimeByExtension('doc'));
  188. self::assertEquals('application/octet-stream', Utils::getMimeByExtension('foo'));
  189. self::assertEquals('foo/bar', Utils::getMimeByExtension('foo', 'foo/bar'));
  190. self::assertEquals('text/html', Utils::getMimeByExtension('foo', 'text/html'));
  191. }
  192. public function testGetExtensionByMime(): void
  193. {
  194. self::assertEquals('html', Utils::getExtensionByMime('*/*'));
  195. self::assertEquals('html', Utils::getExtensionByMime('text/*'));
  196. self::assertEquals('html', Utils::getExtensionByMime('text/html'));
  197. self::assertEquals('json', Utils::getExtensionByMime('application/json'));
  198. self::assertEquals('atom', Utils::getExtensionByMime('application/atom+xml'));
  199. self::assertEquals('rss', Utils::getExtensionByMime('application/rss+xml'));
  200. self::assertEquals('jpg', Utils::getExtensionByMime('image/jpeg'));
  201. self::assertEquals('png', Utils::getExtensionByMime('image/png'));
  202. self::assertEquals('txt', Utils::getExtensionByMime('text/plain'));
  203. self::assertEquals('doc', Utils::getExtensionByMime('application/msword'));
  204. self::assertEquals('html', Utils::getExtensionByMime('foo/bar'));
  205. self::assertEquals('baz', Utils::getExtensionByMime('foo/bar', 'baz'));
  206. }
  207. public function testNormalizePath(): void
  208. {
  209. self::assertEquals('/test', Utils::normalizePath('/test'));
  210. self::assertEquals('test', Utils::normalizePath('test'));
  211. self::assertEquals('test', Utils::normalizePath('../test'));
  212. self::assertEquals('/test', Utils::normalizePath('/../test'));
  213. self::assertEquals('/test2', Utils::normalizePath('/test/../test2'));
  214. self::assertEquals('/test3', Utils::normalizePath('/test/../test2/../test3'));
  215. self::assertEquals('//cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css', Utils::normalizePath('//cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css'));
  216. self::assertEquals('//use.fontawesome.com/releases/v5.8.1/css/all.css', Utils::normalizePath('//use.fontawesome.com/releases/v5.8.1/css/all.css'));
  217. self::assertEquals('//use.fontawesome.com/releases/v5.8.1/webfonts/fa-brands-400.eot', Utils::normalizePath('//use.fontawesome.com/releases/v5.8.1/css/../webfonts/fa-brands-400.eot'));
  218. self::assertEquals('http://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css', Utils::normalizePath('http://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css'));
  219. self::assertEquals('http://use.fontawesome.com/releases/v5.8.1/css/all.css', Utils::normalizePath('http://use.fontawesome.com/releases/v5.8.1/css/all.css'));
  220. self::assertEquals('http://use.fontawesome.com/releases/v5.8.1/webfonts/fa-brands-400.eot', Utils::normalizePath('http://use.fontawesome.com/releases/v5.8.1/css/../webfonts/fa-brands-400.eot'));
  221. self::assertEquals('https://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css', Utils::normalizePath('https://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css'));
  222. self::assertEquals('https://use.fontawesome.com/releases/v5.8.1/css/all.css', Utils::normalizePath('https://use.fontawesome.com/releases/v5.8.1/css/all.css'));
  223. self::assertEquals('https://use.fontawesome.com/releases/v5.8.1/webfonts/fa-brands-400.eot', Utils::normalizePath('https://use.fontawesome.com/releases/v5.8.1/css/../webfonts/fa-brands-400.eot'));
  224. }
  225. public function testIsFunctionDisabled(): void
  226. {
  227. $disabledFunctions = explode(',', ini_get('disable_functions'));
  228. if ($disabledFunctions[0]) {
  229. self::assertEquals(Utils::isFunctionDisabled($disabledFunctions[0]), true);
  230. }
  231. }
  232. public function testTimezones(): void
  233. {
  234. $timezones = Utils::timezones();
  235. self::assertIsArray($timezones);
  236. self::assertContainsOnly('string', $timezones);
  237. }
  238. public function testArrayFilterRecursive(): void
  239. {
  240. $array = [
  241. 'test' => '',
  242. 'test2' => 'test2'
  243. ];
  244. $array = Utils::arrayFilterRecursive($array, function ($k, $v) {
  245. return !(is_null($v) || $v === '');
  246. });
  247. self::assertContainsOnly('string', $array);
  248. self::assertArrayNotHasKey('test', $array);
  249. self::assertArrayHasKey('test2', $array);
  250. self::assertEquals('test2', $array['test2']);
  251. }
  252. public function testPathPrefixedByLangCode(): void
  253. {
  254. $languagesEnabled = $this->grav['config']->get('system.languages.supported', []);
  255. $arrayOfLanguages = ['en', 'de', 'it', 'es', 'dk', 'el'];
  256. $languagesNotEnabled = array_diff($arrayOfLanguages, $languagesEnabled);
  257. $oneLanguageNotEnabled = reset($languagesNotEnabled);
  258. if (count($languagesEnabled)) {
  259. $languageCodePathPrefix = Utils::pathPrefixedByLangCode('/' . $languagesEnabled[0] . '/test');
  260. $this->assertIsString($languageCodePathPrefix);
  261. $this->assertTrue(in_array($languageCodePathPrefix, $languagesEnabled));
  262. }
  263. self::assertFalse(Utils::pathPrefixedByLangCode('/' . $oneLanguageNotEnabled . '/test'));
  264. self::assertFalse(Utils::pathPrefixedByLangCode('/test'));
  265. self::assertFalse(Utils::pathPrefixedByLangCode('/xx'));
  266. self::assertFalse(Utils::pathPrefixedByLangCode('/xx/'));
  267. self::assertFalse(Utils::pathPrefixedByLangCode('/'));
  268. }
  269. public function testDate2timestamp(): void
  270. {
  271. $timestamp = strtotime('10 September 2000');
  272. self::assertSame($timestamp, Utils::date2timestamp('10 September 2000'));
  273. self::assertSame($timestamp, Utils::date2timestamp('2000-09-10 00:00:00'));
  274. }
  275. public function testResolve(): void
  276. {
  277. $array = [
  278. 'test' => [
  279. 'test2' => 'test2Value'
  280. ]
  281. ];
  282. self::assertEquals('test2Value', Utils::resolve($array, 'test.test2'));
  283. }
  284. public function testGetDotNotation(): void
  285. {
  286. $array = [
  287. 'test' => [
  288. 'test2' => 'test2Value',
  289. 'test3' => [
  290. 'test4' => 'test4Value'
  291. ]
  292. ]
  293. ];
  294. self::assertEquals('test2Value', Utils::getDotNotation($array, 'test.test2'));
  295. self::assertEquals('test4Value', Utils::getDotNotation($array, 'test.test3.test4'));
  296. self::assertEquals('defaultValue', Utils::getDotNotation($array, 'test.non_existent', 'defaultValue'));
  297. }
  298. public function testSetDotNotation(): void
  299. {
  300. $array = [
  301. 'test' => [
  302. 'test2' => 'test2Value',
  303. 'test3' => [
  304. 'test4' => 'test4Value'
  305. ]
  306. ]
  307. ];
  308. $new = [
  309. 'test1' => 'test1Value'
  310. ];
  311. Utils::setDotNotation($array, 'test.test3.test4', $new);
  312. self::assertEquals('test1Value', $array['test']['test3']['test4']['test1']);
  313. }
  314. public function testIsPositive(): void
  315. {
  316. self::assertTrue(Utils::isPositive(true));
  317. self::assertTrue(Utils::isPositive(1));
  318. self::assertTrue(Utils::isPositive('1'));
  319. self::assertTrue(Utils::isPositive('yes'));
  320. self::assertTrue(Utils::isPositive('on'));
  321. self::assertTrue(Utils::isPositive('true'));
  322. self::assertFalse(Utils::isPositive(false));
  323. self::assertFalse(Utils::isPositive(0));
  324. self::assertFalse(Utils::isPositive('0'));
  325. self::assertFalse(Utils::isPositive('no'));
  326. self::assertFalse(Utils::isPositive('off'));
  327. self::assertFalse(Utils::isPositive('false'));
  328. self::assertFalse(Utils::isPositive('some'));
  329. self::assertFalse(Utils::isPositive(2));
  330. }
  331. public function testGetNonce(): void
  332. {
  333. self::assertIsString(Utils::getNonce('test-action'));
  334. self::assertIsString(Utils::getNonce('test-action', true));
  335. self::assertSame(Utils::getNonce('test-action'), Utils::getNonce('test-action'));
  336. self::assertNotSame(Utils::getNonce('test-action'), Utils::getNonce('test-action2'));
  337. }
  338. public function testVerifyNonce(): void
  339. {
  340. self::assertTrue(Utils::verifyNonce(Utils::getNonce('test-action'), 'test-action'));
  341. }
  342. public function testUrl(): void
  343. {
  344. $this->uri->initializeWithUrl('http://testing.dev/path1/path2')->init();
  345. // Fail hard
  346. self::assertSame(false, Utils::url('', true));
  347. self::assertSame(false, Utils::url(''));
  348. self::assertSame(false, Utils::url(new stdClass()));
  349. self::assertSame(false, Utils::url(['foo','bar','baz']));
  350. self::assertSame(false, Utils::url('user://does/not/exist'));
  351. // Fail Gracefully
  352. self::assertSame('/', Utils::url('/', false, true));
  353. self::assertSame('/', Utils::url('', false, true));
  354. self::assertSame('/', Utils::url(new stdClass(), false, true));
  355. self::assertSame('/', Utils::url(['foo','bar','baz'], false, true));
  356. self::assertSame('/user/does/not/exist', Utils::url('user://does/not/exist', false, true));
  357. // Simple paths
  358. self::assertSame('/', Utils::url('/'));
  359. self::assertSame('/path1', Utils::url('/path1'));
  360. self::assertSame('/path1/path2', Utils::url('/path1/path2'));
  361. self::assertSame('/random/path1/path2', Utils::url('/random/path1/path2'));
  362. self::assertSame('/foobar.jpg', Utils::url('/foobar.jpg'));
  363. self::assertSame('/path1/foobar.jpg', Utils::url('/path1/foobar.jpg'));
  364. self::assertSame('/path1/path2/foobar.jpg', Utils::url('/path1/path2/foobar.jpg'));
  365. self::assertSame('/random/path1/path2/foobar.jpg', Utils::url('/random/path1/path2/foobar.jpg'));
  366. // Simple paths with domain
  367. self::assertSame('http://testing.dev/', Utils::url('/', true));
  368. self::assertSame('http://testing.dev/path1', Utils::url('/path1', true));
  369. self::assertSame('http://testing.dev/path1/path2', Utils::url('/path1/path2', true));
  370. self::assertSame('http://testing.dev/random/path1/path2', Utils::url('/random/path1/path2', true));
  371. self::assertSame('http://testing.dev/foobar.jpg', Utils::url('/foobar.jpg', true));
  372. self::assertSame('http://testing.dev/path1/foobar.jpg', Utils::url('/path1/foobar.jpg', true));
  373. self::assertSame('http://testing.dev/path1/path2/foobar.jpg', Utils::url('/path1/path2/foobar.jpg', true));
  374. self::assertSame('http://testing.dev/random/path1/path2/foobar.jpg', Utils::url('/random/path1/path2/foobar.jpg', true));
  375. // Relative paths from Grav root.
  376. self::assertSame('/subdir', Utils::url('subdir'));
  377. self::assertSame('/subdir/path1', Utils::url('subdir/path1'));
  378. self::assertSame('/subdir/path1/path2', Utils::url('subdir/path1/path2'));
  379. self::assertSame('/path1', Utils::url('path1'));
  380. self::assertSame('/path1/path2', Utils::url('path1/path2'));
  381. self::assertSame('/foobar.jpg', Utils::url('foobar.jpg'));
  382. self::assertSame('http://testing.dev/foobar.jpg', Utils::url('foobar.jpg', true));
  383. // Relative paths from Grav root with domain.
  384. self::assertSame('http://testing.dev/foobar.jpg', Utils::url('foobar.jpg', true));
  385. self::assertSame('http://testing.dev/foobar.jpg', Utils::url('/foobar.jpg', true));
  386. self::assertSame('http://testing.dev/path1/foobar.jpg', Utils::url('/path1/foobar.jpg', true));
  387. // All Non-existing streams should be treated as external URI / protocol.
  388. self::assertSame('http://domain.com/path', Utils::url('http://domain.com/path'));
  389. self::assertSame('ftp://domain.com/path', Utils::url('ftp://domain.com/path'));
  390. self::assertSame('sftp://domain.com/path', Utils::url('sftp://domain.com/path'));
  391. self::assertSame('ssh://domain.com', Utils::url('ssh://domain.com'));
  392. self::assertSame('pop://domain.com', Utils::url('pop://domain.com'));
  393. self::assertSame('foo://bar/baz', Utils::url('foo://bar/baz'));
  394. self::assertSame('foo://bar/baz', Utils::url('foo://bar/baz', true));
  395. // self::assertSame('mailto:joe@domain.com', Utils::url('mailto:joe@domain.com', true)); // FIXME <-
  396. }
  397. public function testUrlWithRoot(): void
  398. {
  399. $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/path1/path2', '/subdir')->init();
  400. // Fail hard
  401. self::assertSame(false, Utils::url('', true));
  402. self::assertSame(false, Utils::url(''));
  403. self::assertSame(false, Utils::url(new stdClass()));
  404. self::assertSame(false, Utils::url(['foo','bar','baz']));
  405. self::assertSame(false, Utils::url('user://does/not/exist'));
  406. // Fail Gracefully
  407. self::assertSame('/subdir/', Utils::url('/', false, true));
  408. self::assertSame('/subdir/', Utils::url('', false, true));
  409. self::assertSame('/subdir/', Utils::url(new stdClass(), false, true));
  410. self::assertSame('/subdir/', Utils::url(['foo','bar','baz'], false, true));
  411. self::assertSame('/subdir/user/does/not/exist', Utils::url('user://does/not/exist', false, true));
  412. // Simple paths
  413. self::assertSame('/subdir/', Utils::url('/'));
  414. self::assertSame('/subdir/path1', Utils::url('/path1'));
  415. self::assertSame('/subdir/path1/path2', Utils::url('/path1/path2'));
  416. self::assertSame('/subdir/random/path1/path2', Utils::url('/random/path1/path2'));
  417. self::assertSame('/subdir/foobar.jpg', Utils::url('/foobar.jpg'));
  418. self::assertSame('/subdir/path1/foobar.jpg', Utils::url('/path1/foobar.jpg'));
  419. self::assertSame('/subdir/path1/path2/foobar.jpg', Utils::url('/path1/path2/foobar.jpg'));
  420. self::assertSame('/subdir/random/path1/path2/foobar.jpg', Utils::url('/random/path1/path2/foobar.jpg'));
  421. // Simple paths with domain
  422. self::assertSame('http://testing.dev/subdir/', Utils::url('/', true));
  423. self::assertSame('http://testing.dev/subdir/path1', Utils::url('/path1', true));
  424. self::assertSame('http://testing.dev/subdir/path1/path2', Utils::url('/path1/path2', true));
  425. self::assertSame('http://testing.dev/subdir/random/path1/path2', Utils::url('/random/path1/path2', true));
  426. self::assertSame('http://testing.dev/subdir/foobar.jpg', Utils::url('/foobar.jpg', true));
  427. self::assertSame('http://testing.dev/subdir/path1/foobar.jpg', Utils::url('/path1/foobar.jpg', true));
  428. self::assertSame('http://testing.dev/subdir/path1/path2/foobar.jpg', Utils::url('/path1/path2/foobar.jpg', true));
  429. self::assertSame('http://testing.dev/subdir/random/path1/path2/foobar.jpg', Utils::url('/random/path1/path2/foobar.jpg', true));
  430. // Paths including the grav base.
  431. self::assertSame('/subdir/', Utils::url('/subdir'));
  432. self::assertSame('/subdir/path1', Utils::url('/subdir/path1'));
  433. self::assertSame('/subdir/path1/path2', Utils::url('/subdir/path1/path2'));
  434. self::assertSame('/subdir/foobar.jpg', Utils::url('/subdir/foobar.jpg'));
  435. self::assertSame('/subdir/path1/foobar.jpg', Utils::url('/subdir/path1/foobar.jpg'));
  436. // Relative paths from Grav root with domain.
  437. self::assertSame('http://testing.dev/subdir/', Utils::url('/subdir', true));
  438. self::assertSame('http://testing.dev/subdir/path1', Utils::url('/subdir/path1', true));
  439. self::assertSame('http://testing.dev/subdir/path1/path2', Utils::url('/subdir/path1/path2', true));
  440. self::assertSame('http://testing.dev/subdir/foobar.jpg', Utils::url('/subdir/foobar.jpg', true));
  441. self::assertSame('http://testing.dev/subdir/path1/foobar.jpg', Utils::url('/subdir/path1/foobar.jpg', true));
  442. // Relative paths from Grav root.
  443. self::assertSame('/subdir/subdir', Utils::url('subdir'));
  444. self::assertSame('/subdir/subdir/path1', Utils::url('subdir/path1'));
  445. self::assertSame('/subdir/subdir/path1/path2', Utils::url('subdir/path1/path2'));
  446. self::assertSame('/subdir/path1', Utils::url('path1'));
  447. self::assertSame('/subdir/path1/path2', Utils::url('path1/path2'));
  448. self::assertSame('/subdir/foobar.jpg', Utils::url('foobar.jpg'));
  449. self::assertSame('http://testing.dev/subdir/foobar.jpg', Utils::url('foobar.jpg', true));
  450. // All Non-existing streams should be treated as external URI / protocol.
  451. self::assertSame('http://domain.com/path', Utils::url('http://domain.com/path'));
  452. self::assertSame('ftp://domain.com/path', Utils::url('ftp://domain.com/path'));
  453. self::assertSame('sftp://domain.com/path', Utils::url('sftp://domain.com/path'));
  454. self::assertSame('ssh://domain.com', Utils::url('ssh://domain.com'));
  455. self::assertSame('pop://domain.com', Utils::url('pop://domain.com'));
  456. self::assertSame('foo://bar/baz', Utils::url('foo://bar/baz'));
  457. self::assertSame('foo://bar/baz', Utils::url('foo://bar/baz', true));
  458. // self::assertSame('mailto:joe@domain.com', Utils::url('mailto:joe@domain.com', true)); // FIXME <-
  459. }
  460. public function testUrlWithStreams(): void
  461. {
  462. }
  463. public function testUrlwithExternals(): void
  464. {
  465. $this->uri->initializeWithUrl('http://testing.dev/path1/path2')->init();
  466. self::assertSame('http://foo.com', Utils::url('http://foo.com'));
  467. self::assertSame('https://foo.com', Utils::url('https://foo.com'));
  468. self::assertSame('//foo.com', Utils::url('//foo.com'));
  469. self::assertSame('//foo.com?param=x', Utils::url('//foo.com?param=x'));
  470. }
  471. public function testCheckFilename(): void
  472. {
  473. // configure extension for consistent results
  474. /** @var \Grav\Common\Config\Config $config */
  475. $config = $this->grav['config'];
  476. $config->set('security.uploads_dangerous_extensions', ['php', 'html', 'htm', 'exe', 'js']);
  477. self::assertFalse(Utils::checkFilename('foo.php'));
  478. self::assertFalse(Utils::checkFilename('bar.js'));
  479. self::assertTrue(Utils::checkFilename('foo.json'));
  480. self::assertTrue(Utils::checkFilename('foo.xml'));
  481. self::assertTrue(Utils::checkFilename('foo.yaml'));
  482. self::assertTrue(Utils::checkFilename('foo.yml'));
  483. }
  484. }