Skip to content

Commit baf21fe

Browse files
committed
test: add tests for signed URL feature and exception handling
1 parent 683e4d6 commit baf21fe

File tree

2 files changed

+168
-0
lines changed

2 files changed

+168
-0
lines changed

tests/Feature/FacadeTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use AceOfAces\LaravelImageTransformUrl\Exceptions\InvalidConfigurationException;
6+
use AceOfAces\LaravelImageTransformUrl\Facades\ImageTransformUrl;
7+
use AceOfAces\LaravelImageTransformUrl\Tests\TestCase;
8+
9+
it('produces identical signed URLs for the signedUrl and temporarySignedUrl methods when given the same parameters', function () {
10+
/** @var TestCase $this */
11+
config()->set('image-transform-url.signed_urls.enabled', true);
12+
13+
$signedUrlOne = ImageTransformUrl::signedUrl(
14+
'path/to/image.jpg',
15+
['width' => 100, 'height' => 200],
16+
'images',
17+
now()->addMinutes(60)
18+
);
19+
20+
$signedUrlTwo = ImageTransformUrl::temporarySignedUrl(
21+
'path/to/image.jpg',
22+
['width' => 100, 'height' => 200],
23+
now()->addMinutes(60),
24+
'images'
25+
);
26+
27+
expect($signedUrlOne)->toBe($signedUrlTwo);
28+
});
29+
30+
it('throws an exception when signed URLs are not enabled', function () {
31+
/** @var TestCase $this */
32+
config()->set('image-transform-url.signed_urls.enabled', false);
33+
34+
ImageTransformUrl::signedUrl('path/to/image.jpg', ['width' => 100, 'height' => 200]);
35+
})->throws(InvalidConfigurationException::class, 'Signed URLs are not enabled. Please check your configuration.');

tests/Feature/SignedUrlTest.php

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use AceOfAces\LaravelImageTransformUrl\Facades\ImageTransformUrl;
6+
use AceOfAces\LaravelImageTransformUrl\Tests\TestCase;
7+
use Illuminate\Support\Facades\Cache;
8+
use Illuminate\Support\Facades\Storage;
9+
10+
beforeEach(function () {
11+
Cache::flush();
12+
Storage::fake(config()->string('image-transform-url.cache.disk'));
13+
});
14+
15+
function configureTestEnvironment(): void
16+
{
17+
config()->set('image-transform-url.signed_urls.enabled', true);
18+
config()->set('image-transform-url.signed_urls.for_source_directories', ['protected']);
19+
config()->set('image-transform-url.source_directories', [
20+
'test-data' => public_path('test-data'),
21+
'protected' => Storage::fake('local')->path('protected'),
22+
]);
23+
}
24+
25+
it('can protect a route with a signed URL', function () {
26+
/** @var TestCase $this */
27+
configureTestEnvironment();
28+
29+
Storage::disk('local')->put('protected/cat.jpg', file_get_contents(public_path('test-data/cat.jpg')));
30+
31+
assert(Storage::disk('local')->exists('protected/cat.jpg'));
32+
33+
$response = $this->get(route('image.transform', [
34+
'pathPrefix' => 'protected',
35+
'options' => 'width=100',
36+
'path' => 'cat.jpg',
37+
]));
38+
39+
$response->assertStatus(403);
40+
41+
$signedUrl = ImageTransformUrl::signedUrl('cat.jpg', [
42+
'width' => 100,
43+
], 'protected');
44+
45+
$secondResponse = $this->get($signedUrl);
46+
47+
expect($secondResponse)->toBeImage([
48+
'mime' => 'image/jpeg',
49+
]);
50+
});
51+
52+
it('can protect a route with a temporary signed URL that expires', function () {
53+
/** @var TestCase $this */
54+
configureTestEnvironment();
55+
56+
Storage::disk('local')->put('protected/cat.jpg', file_get_contents(public_path('test-data/cat.jpg')));
57+
58+
assert(Storage::disk('local')->exists('protected/cat.jpg'));
59+
60+
$signedUrl = ImageTransformUrl::signedUrl(
61+
'cat.jpg',
62+
['width' => 100],
63+
'protected',
64+
now()->addMinutes(60),
65+
);
66+
67+
$response = $this->get($signedUrl);
68+
69+
expect($response)->toBeImage([
70+
'mime' => 'image/jpeg',
71+
]);
72+
73+
$this->travel(61)->minutes();
74+
75+
$expiredResponse = $this->get($signedUrl);
76+
$expiredResponse->assertStatus(403);
77+
});
78+
79+
it('cannot manipulate signatures to access images', function () {
80+
/** @var TestCase $this */
81+
configureTestEnvironment();
82+
83+
Storage::disk('local')->put('protected/cat.jpg', file_get_contents(public_path('test-data/cat.jpg')));
84+
85+
assert(Storage::disk('local')->exists('protected/cat.jpg'));
86+
87+
$signedUrl = ImageTransformUrl::signedUrl('cat.jpg', [
88+
'width' => 100,
89+
], 'protected');
90+
91+
$manipulatedOptionsUrl = str_replace('width=100', 'width=500', $signedUrl);
92+
$manipulatedResponse = $this->get($manipulatedOptionsUrl);
93+
$manipulatedResponse->assertStatus(403);
94+
95+
$manipulatedSignatureUrl = substr($signedUrl, 0, -5).'12345';
96+
$manipulatedSignatureResponse = $this->get($manipulatedSignatureUrl);
97+
$manipulatedSignatureResponse->assertStatus(403);
98+
});
99+
100+
it('can use a protected directory as default source directory', function () {
101+
/** @var TestCase $this */
102+
configureTestEnvironment();
103+
104+
config()->set('image-transform-url.default_source_directory', 'protected');
105+
106+
Storage::disk('local')->put('protected/cat.jpg', file_get_contents(public_path('test-data/cat.jpg')));
107+
108+
assert(Storage::disk('local')->exists('protected/cat.jpg'));
109+
110+
$signedUrl = ImageTransformUrl::signedUrl('cat.jpg', [
111+
'width' => 100,
112+
]);
113+
114+
$response = $this->get($signedUrl);
115+
116+
expect($response)->toBeImage([
117+
'mime' => 'image/jpeg',
118+
]);
119+
});
120+
121+
it('can still access an unprotected source directory without signed URLs', function () {
122+
/** @var TestCase $this */
123+
configureTestEnvironment();
124+
125+
$response = $this->get(route('image.transform.default', [
126+
'options' => 'width=100',
127+
'path' => 'cat.jpg',
128+
]));
129+
130+
expect($response)->toBeImage([
131+
'mime' => 'image/jpeg',
132+
]);
133+
});

0 commit comments

Comments
 (0)