From fe7a2394661d0e40cd7330bfc8c44884b60ca203 Mon Sep 17 00:00:00 2001 From: Chris Kankiewicz Date: Mon, 6 Apr 2020 16:12:59 -0700 Subject: [PATCH] Split Twig 'url' function into separate functions --- app/src/Factories/TwigFactory.php | 2 ++ app/src/ViewFunctions/FileUrl.php | 27 +++++++++++++++ app/src/ViewFunctions/Url.php | 25 +++----------- app/src/ViewFunctions/ZipUrl.php | 23 +++++++++++++ app/views/components/file.twig | 2 +- app/views/components/header.twig | 2 +- tests/Factories/TwigFactoryTest.php | 12 ++++++- tests/ViewFunctions/FileUrlTest.php | 43 ++++++++++++++++++++++++ tests/ViewFunctions/UrlTest.php | 52 +---------------------------- tests/ViewFunctions/ZipUrlTest.php | 43 ++++++++++++++++++++++++ 10 files changed, 156 insertions(+), 75 deletions(-) create mode 100644 app/src/ViewFunctions/FileUrl.php create mode 100644 app/src/ViewFunctions/ZipUrl.php create mode 100644 tests/ViewFunctions/FileUrlTest.php create mode 100644 tests/ViewFunctions/ZipUrlTest.php diff --git a/app/src/Factories/TwigFactory.php b/app/src/Factories/TwigFactory.php index 1ca5c66..7a795ab 100644 --- a/app/src/Factories/TwigFactory.php +++ b/app/src/Factories/TwigFactory.php @@ -17,12 +17,14 @@ class TwigFactory ViewFunctions\Asset::class, ViewFunctions\Breadcrumbs::class, ViewFunctions\Config::class, + ViewFunctions\FileUrl::class, ViewFunctions\Icon::class, ViewFunctions\Markdown::class, ViewFunctions\ParentUrl::class, ViewFunctions\SizeForHumans::class, ViewFunctions\Translate::class, ViewFunctions\Url::class, + ViewFunctions\ZipUrl::class, ]; /** @var Container The application container */ diff --git a/app/src/ViewFunctions/FileUrl.php b/app/src/ViewFunctions/FileUrl.php new file mode 100644 index 0000000..b4731a0 --- /dev/null +++ b/app/src/ViewFunctions/FileUrl.php @@ -0,0 +1,27 @@ +escape($path); + } + + return empty($path) ? '' : sprintf('?dir=%s', $this->escape($path)); + } +} diff --git a/app/src/ViewFunctions/Url.php b/app/src/ViewFunctions/Url.php index 8879207..6eea135 100644 --- a/app/src/ViewFunctions/Url.php +++ b/app/src/ViewFunctions/Url.php @@ -3,7 +3,6 @@ namespace App\ViewFunctions; use App\Support\Str; -use RuntimeException; class Url extends ViewFunction { @@ -24,33 +23,17 @@ class Url extends ViewFunction } /** - * Return the URL for a given path and action. + * Return the URL for a given path. * - * @param string $path - * @param string|null $action + * @param string $path * * @return string */ - public function __invoke(string $path = '/', string $action = null): string + public function __invoke(string $path = '/'): string { $path = preg_replace('/^.?(\/|\\\)+/', '', $path); - switch ($action) { - case null: - return $this->escape($path); - - case 'dir': - return empty($path) ? '' : sprintf('?dir=%s', $this->escape($path)); - - case 'info': - return empty($path) ? '?info=.' : sprintf('?info=%s', $this->escape($path)); - - case 'zip': - return empty($path) ? '?zip=.' : sprintf('?zip=%s', $this->escape($path)); - - default: - throw new RuntimeException(sprintf('Invalid action "%s"', $action)); - } + return $this->escape($path); } /** diff --git a/app/src/ViewFunctions/ZipUrl.php b/app/src/ViewFunctions/ZipUrl.php new file mode 100644 index 0000000..97a2cca --- /dev/null +++ b/app/src/ViewFunctions/ZipUrl.php @@ -0,0 +1,23 @@ +escape($path)); + } +} diff --git a/app/views/components/file.twig b/app/views/components/file.twig index 9ce450c..c30ae59 100644 --- a/app/views/components/file.twig +++ b/app/views/components/file.twig @@ -1,5 +1,5 @@
diff --git a/app/views/components/header.twig b/app/views/components/header.twig index 05cba1b..e69aad9 100644 --- a/app/views/components/header.twig +++ b/app/views/components/header.twig @@ -14,7 +14,7 @@
{% if path and files is not empty and config('zip_downloads') %} - + {% endif %} diff --git a/tests/Factories/TwigFactoryTest.php b/tests/Factories/TwigFactoryTest.php index 7eea3db..c49f59e 100644 --- a/tests/Factories/TwigFactoryTest.php +++ b/tests/Factories/TwigFactoryTest.php @@ -42,6 +42,11 @@ class TwigFactoryTest extends TestCase $twig->getEnvironment()->getFunction('config')->getCallable() ); + $this->assertInstanceOf( + ViewFunctions\FileUrl::class, + $twig->getEnvironment()->getFunction('file_url')->getCallable() + ); + $this->assertInstanceOf( ViewFunctions\Icon::class, $twig->getEnvironment()->getFunction('icon')->getCallable() @@ -54,7 +59,7 @@ class TwigFactoryTest extends TestCase $this->assertInstanceOf( ViewFunctions\ParentUrl::class, - $twig->getEnvironment()->getFunction('parent_dir')->getCallable() + $twig->getEnvironment()->getFunction('parent_url')->getCallable() ); $this->assertInstanceOf( @@ -71,5 +76,10 @@ class TwigFactoryTest extends TestCase ViewFunctions\Url::class, $twig->getEnvironment()->getFunction('url')->getCallable() ); + + $this->assertInstanceOf( + ViewFunctions\ZipUrl::class, + $twig->getEnvironment()->getFunction('zip_url')->getCallable() + ); } } diff --git a/tests/ViewFunctions/FileUrlTest.php b/tests/ViewFunctions/FileUrlTest.php new file mode 100644 index 0000000..98e976c --- /dev/null +++ b/tests/ViewFunctions/FileUrlTest.php @@ -0,0 +1,43 @@ +assertEquals('', $url('/')); + $this->assertEquals('', $url('./')); + $this->assertEquals('?dir=some/path', $url('some/path')); + $this->assertEquals('?dir=some/path', $url('./some/path')); + $this->assertEquals('?dir=some/path', $url('./some/path')); + $this->assertEquals('?dir=some/file.test', $url('some/file.test')); + $this->assertEquals('?dir=some/file.test', $url('./some/file.test')); + } + + public function test_it_can_return_a_url_with_back_slashes(): void + { + $url = new FileUrl('\\'); + + $this->assertEquals('', $url('\\')); + $this->assertEquals('', $url('.\\')); + $this->assertEquals('?dir=some\path', $url('some\path')); + $this->assertEquals('?dir=some\path', $url('.\some\path')); + $this->assertEquals('?dir=some\file.test', $url('some\file.test')); + $this->assertEquals('?dir=some\file.test', $url('.\some\file.test')); + } + + public function test_url_segments_are_url_encoded(): void + { + $url = new FileUrl; + + $this->assertEquals('?dir=foo/bar%2Bbaz', $url('foo/bar+baz')); + $this->assertEquals('?dir=foo/bar%23baz', $url('foo/bar#baz')); + $this->assertEquals('?dir=foo/bar%26baz', $url('foo/bar&baz')); + } +} diff --git a/tests/ViewFunctions/UrlTest.php b/tests/ViewFunctions/UrlTest.php index 3b66820..999c2d3 100644 --- a/tests/ViewFunctions/UrlTest.php +++ b/tests/ViewFunctions/UrlTest.php @@ -3,7 +3,6 @@ namespace Tests\ViewFunctions; use App\ViewFunctions\Url; -use RuntimeException; use Tests\TestCase; class UrlTest extends TestCase @@ -21,43 +20,6 @@ class UrlTest extends TestCase $this->assertEquals('some/file.test', $url('./some/file.test')); } - public function test_it_can_return_a_directory_url(): void - { - $url = new Url; - - $this->assertEquals('', $url('/', 'dir')); - $this->assertEquals('', $url('./', 'dir')); - $this->assertEquals('?dir=some/path', $url('some/path', 'dir')); - $this->assertEquals('?dir=some/path', $url('./some/path', 'dir')); - $this->assertEquals('?dir=some/path', $url('./some/path', 'dir')); - $this->assertEquals('?dir=some/file.test', $url('some/file.test', 'dir')); - $this->assertEquals('?dir=some/file.test', $url('./some/file.test', 'dir')); - } - - public function test_it_can_return_a_file_info_url(): void - { - $url = new Url; - - $this->assertEquals('?info=.', $url('/', 'info')); - $this->assertEquals('?info=.', $url('./', 'info')); - $this->assertEquals('?info=some/path', $url('some/path', 'info')); - $this->assertEquals('?info=some/path', $url('./some/path', 'info')); - $this->assertEquals('?info=some/path', $url('./some/path', 'info')); - $this->assertEquals('?info=some/file.test', $url('some/file.test', 'info')); - $this->assertEquals('?info=some/file.test', $url('./some/file.test', 'info')); - } - - public function test_it_can_return_a_zip_url(): void - { - $url = new Url; - - $this->assertEquals('?zip=.', $url('/', 'zip')); - $this->assertEquals('?zip=.', $url('./', 'zip')); - $this->assertEquals('?zip=some/path', $url('some/path', 'zip')); - $this->assertEquals('?zip=some/path', $url('./some/path', 'zip')); - $this->assertEquals('?zip=some/path', $url('./some/path', 'zip')); - } - public function test_it_can_return_a_url_with_back_slashes(): void { $url = new Url('\\'); @@ -68,21 +30,9 @@ class UrlTest extends TestCase $this->assertEquals('some\path', $url('.\some\path')); $this->assertEquals('some\file.test', $url('some\file.test')); $this->assertEquals('some\file.test', $url('.\some\file.test')); - $this->assertEquals('?dir=some\path', $url('some\path', 'dir')); - $this->assertEquals('?info=some\path', $url('some\path', 'info')); - $this->assertEquals('?zip=some\path', $url('some\path', 'zip')); } - public function test_it_throws_an_exception_for_an_invalid_action(): void - { - $url = new Url; - - $this->expectException(RuntimeException::class); - - $url('some/path', 'INVALID_ACTION'); - } - - public function test_segments_are_url_encoded(): void + public function test_url_segments_are_url_encoded(): void { $url = new Url; diff --git a/tests/ViewFunctions/ZipUrlTest.php b/tests/ViewFunctions/ZipUrlTest.php new file mode 100644 index 0000000..37170d7 --- /dev/null +++ b/tests/ViewFunctions/ZipUrlTest.php @@ -0,0 +1,43 @@ +assertEquals('?zip=.', $url('/')); + $this->assertEquals('?zip=.', $url('./')); + $this->assertEquals('?zip=some/path', $url('some/path')); + $this->assertEquals('?zip=some/path', $url('./some/path')); + $this->assertEquals('?zip=some/path', $url('./some/path')); + $this->assertEquals('?zip=some/file.test', $url('some/file.test')); + $this->assertEquals('?zip=some/file.test', $url('./some/file.test')); + } + + public function test_it_can_return_a_url_with_back_slashes(): void + { + $url = new ZipUrl('\\'); + + $this->assertEquals('?zip=.', $url('\\')); + $this->assertEquals('?zip=.', $url('.\\')); + $this->assertEquals('?zip=some\path', $url('some\path')); + $this->assertEquals('?zip=some\path', $url('.\some\path')); + $this->assertEquals('?zip=some\file.test', $url('some\file.test')); + $this->assertEquals('?zip=some\file.test', $url('.\some\file.test')); + } + + public function test_url_segments_are_url_encoded(): void + { + $url = new ZipUrl; + + $this->assertEquals('?zip=foo/bar%2Bbaz', $url('foo/bar+baz')); + $this->assertEquals('?zip=foo/bar%23baz', $url('foo/bar#baz')); + $this->assertEquals('?zip=foo/bar%26baz', $url('foo/bar&baz')); + } +}