Completed
Push — master ( 98eea6...214a1e )
by Damian
15s
created

testShortcodeHandlerUsesShortcodeProperties()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 16
rs 9.4285
c 1
b 0
f 0
cc 1
eloc 11
nc 1
nop 0
1
<?php
2
3
use Filesystem as SS_Filesystem;
4
use League\Flysystem\Filesystem;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Filesystem.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
5
use SilverStripe\Filesystem\Flysystem\AssetAdapter;
6
use SilverStripe\Filesystem\Flysystem\FlysystemAssetStore;
7
use SilverStripe\Filesystem\Flysystem\FlysystemUrlPlugin;
8
9
/**
10
 * @package framework
11
 * @subpackage tests
12
 */
13
class ImageTest extends SapphireTest {
14
15
	protected static $fixture_file = 'ImageTest.yml';
16
17
	public function setUp() {
18
		parent::setUp();
19
20
		// Execute specific subclass
21
		if(get_class($this) == "ImageTest") {
22
			$this->markTestSkipped(sprintf('Skipping %s ', get_class($this)));
23
			return;
24
		}
25
26
		// Set backend root to /ImageTest
27
		AssetStoreTest_SpyStore::activate('ImageTest');
28
29
		// Copy test images for each of the fixture references
30
		$files = File::get()->exclude('ClassName', 'Folder');
31
		foreach($files as $image) {
32
			$filePath = AssetStoreTest_SpyStore::getLocalPath($image); // Only correct for test asset store
33
			$sourcePath = BASE_PATH . '/framework/tests/model/testimages/' . $image->Name;
34
			if(!file_exists($filePath)) {
35
				SS_Filesystem::makeFolder(dirname($filePath));
36
				if (!copy($sourcePath, $filePath)) {
37
					user_error('Failed to copy test images', E_USER_ERROR);
38
				}
39
			}
40
		}
41
	}
42
43
	public function tearDown() {
44
		AssetStoreTest_SpyStore::reset();
45
		parent::tearDown();
46
	}
47
48
	public function testGetTagWithTitle() {
49
		Config::inst()->update('DBFile', 'force_resample', false);
50
51
		$image = $this->objFromFixture('Image', 'imageWithTitle');
52
		$expected = '<img src="/assets/ImageTest/folder/444065542b/test-image.png" alt="This is a image Title" />';
53
		$actual = trim($image->getTag());
54
55
		$this->assertEquals($expected, $actual);
56
	}
57
58
	public function testGetTagWithoutTitle() {
59
		Config::inst()->update('DBFile', 'force_resample', false);
60
61
		$image = $this->objFromFixture('Image', 'imageWithoutTitle');
62
		$expected = '<img src="/assets/ImageTest/folder/444065542b/test-image.png" alt="test image" />';
63
		$actual = trim($image->getTag());
64
65
		$this->assertEquals($expected, $actual);
66
	}
67
68
	public function testGetTagWithoutTitleContainingDots() {
69
		Config::inst()->update('DBFile', 'force_resample', false);
70
71
		$image = $this->objFromFixture('Image', 'imageWithoutTitleContainingDots');
72
		$expected = '<img src="/assets/ImageTest/folder/46affab704/test.image.with.dots.png" alt="test.image.with.dots" />';
73
		$actual = trim($image->getTag());
74
75
		$this->assertEquals($expected, $actual);
76
	}
77
78
	/**
79
	 * Tests that multiple image manipulations may be performed on a single Image
80
	 */
81
	public function testMultipleGenerateManipulationCalls() {
82
		$image = $this->objFromFixture('Image', 'imageWithoutTitle');
83
84
		$imageFirst = $image->ScaleWidth(200);
85
		$this->assertNotNull($imageFirst);
86
		$expected = 200;
87
		$actual = $imageFirst->getWidth();
88
89
		$this->assertEquals($expected, $actual);
90
91
		$imageSecond = $imageFirst->ScaleHeight(100);
92
		$this->assertNotNull($imageSecond);
93
		$expected = 100;
94
		$actual = $imageSecond->getHeight();
95
		$this->assertEquals($expected, $actual);
96
	}
97
98
	/**
99
	 * Tests that image manipulations that do not affect the resulting dimensions
100
	 * of the output image do not resample the file.
101
	 */
102
	public function testReluctanceToResampling() {
103
		$image = $this->objFromFixture('Image', 'imageWithoutTitle');
104
		$this->assertTrue($image->isSize(300, 300));
105
106
		// Set width to 300 pixels
107
		$imageScaleWidth = $image->ScaleWidth(300);
108
		$this->assertEquals($imageScaleWidth->getWidth(), 300);
109
		$this->assertEquals($image->Filename, $imageScaleWidth->Filename);
110
111
		// Set height to 300 pixels
112
		$imageScaleHeight = $image->ScaleHeight(300);
113
		$this->assertEquals($imageScaleHeight->getHeight(), 300);
114
		$this->assertEquals($image->Filename, $imageScaleHeight->Filename);
115
116
		// Crop image to 300 x 300
117
		$imageCropped = $image->Fill(300, 300);
118
		$this->assertTrue($imageCropped->isSize(300, 300));
119
		$this->assertEquals($image->Filename, $imageCropped->Filename);
120
121
		// Resize (padded) to 300 x 300
122
		$imageSized = $image->Pad(300, 300);
123
		$this->assertTrue($imageSized->isSize(300, 300));
124
		$this->assertEquals($image->Filename, $imageSized->Filename);
125
126
		// Padded image 300 x 300 (same as above)
127
		$imagePadded = $image->Pad(300, 300);
128
		$this->assertTrue($imagePadded->isSize(300, 300));
129
		$this->assertEquals($image->Filename, $imagePadded->Filename);
130
131
		// Resized (stretched) to 300 x 300
132
		$imageStretched = $image->ResizedImage(300, 300);
133
		$this->assertTrue($imageStretched->isSize(300, 300));
134
		$this->assertEquals($image->Filename, $imageStretched->Filename);
135
136
		// Fit (various options)
137
		$imageFit = $image->Fit(300, 600);
138
		$this->assertTrue($imageFit->isSize(300, 300));
139
		$this->assertEquals($image->Filename, $imageFit->Filename);
140
		$imageFit = $image->Fit(600, 300);
141
		$this->assertTrue($imageFit->isSize(300, 300));
142
		$this->assertEquals($image->Filename, $imageFit->Filename);
143
		$imageFit = $image->Fit(300, 300);
144
		$this->assertTrue($imageFit->isSize(300, 300));
145
		$this->assertEquals($image->Filename, $imageFit->Filename);
146
	}
147
148
	/**
149
	 * Tests that a URL to a resampled image is provided when force_resample is
150
	 * set to true, if the resampled file is smaller than the original.
151
	 */
152
	public function testForceResample() {
153
		$imageHQ = $this->objFromFixture('Image', 'highQualityJPEG');
154
		$imageHQR = $imageHQ->Resampled();
155
		$imageLQ = $this->objFromFixture('Image', 'lowQualityJPEG');
156
		$imageLQR = $imageLQ->Resampled();
157
158
		// Test resampled file is served when force_resample = true
159
		Config::inst()->update('DBFile', 'force_resample', true);
160
		$this->assertLessThan($imageHQ->getAbsoluteSize(), $imageHQR->getAbsoluteSize(), 'Resampled image is smaller than original');
161
		$this->assertEquals($imageHQ->getURL(), $imageHQR->getSourceURL(), 'Path to a resampled image was returned by getURL()');
162
163
		// Test original file is served when force_resample = true but original file is low quality
164
		$this->assertGreaterThanOrEqual($imageLQ->getAbsoluteSize(), $imageLQR->getAbsoluteSize(), 'Resampled image is larger or same size as original');
165
		$this->assertNotEquals($imageLQ->getURL(), $imageLQR->getSourceURL(), 'Path to the original image file was returned by getURL()');
166
167
		// Test original file is served when force_resample = false
168
		Config::inst()->update('DBFile', 'force_resample', false);
169
		$this->assertNotEquals($imageHQ->getURL(), $imageHQR->getSourceURL(), 'Path to the original image file was returned by getURL()');
170
	}
171
172
	public function testImageResize() {
173
		$image = $this->objFromFixture('Image', 'imageWithoutTitle');
174
		$this->assertTrue($image->isSize(300, 300));
175
176
		// Test normal resize
177
		$resized = $image->Pad(150, 100);
178
		$this->assertTrue($resized->isSize(150, 100));
179
180
		// Test cropped resize
181
		$cropped = $image->Fill(100, 200);
182
		$this->assertTrue($cropped->isSize(100, 200));
183
184
		// Test padded resize
185
		$padded = $image->Pad(200, 100);
186
		$this->assertTrue($padded->isSize(200, 100));
187
188
		// Test Fit
189
		$ratio = $image->Fit(80, 160);
190
		$this->assertTrue($ratio->isSize(80, 80));
191
192
		// Test FitMax
193
		$fitMaxDn = $image->FitMax(200, 100);
194
		$this->assertTrue($fitMaxDn->isSize(100, 100));
195
		$fitMaxUp = $image->FitMax(500, 400);
196
		$this->assertTrue($fitMaxUp->isSize(300, 300));
197
198
		//Test ScaleMax
199
		$scaleMaxWDn = $image->ScaleMaxWidth(200);
200
		$this->assertTrue($scaleMaxWDn->isSize(200, 200));
201
		$scaleMaxWUp = $image->ScaleMaxWidth(400);
202
		$this->assertTrue($scaleMaxWUp->isSize(300, 300));
203
		$scaleMaxHDn = $image->ScaleMaxHeight(200);
204
		$this->assertTrue($scaleMaxHDn->isSize(200, 200));
205
		$scaleMaxHUp = $image->ScaleMaxHeight(400);
206
		$this->assertTrue($scaleMaxHUp->isSize(300, 300));
207
208
		// Test FillMax
209
		$cropMaxDn = $image->FillMax(200, 100);
210
		$this->assertTrue($cropMaxDn->isSize(200, 100));
211
		$cropMaxUp = $image->FillMax(400, 200);
212
		$this->assertTrue($cropMaxUp->isSize(300, 150));
213
214
		// Test Clip
215
		$clipWDn = $image->CropWidth(200);
216
		$this->assertTrue($clipWDn->isSize(200, 300));
217
		$clipWUp = $image->CropWidth(400);
218
		$this->assertTrue($clipWUp->isSize(300, 300));
219
		$clipHDn = $image->CropHeight(200);
220
		$this->assertTrue($clipHDn->isSize(300, 200));
221
		$clipHUp = $image->CropHeight(400);
222
		$this->assertTrue($clipHUp->isSize(300, 300));
223
	}
224
225
	/**
226
	 * @expectedException InvalidArgumentException
227
	 */
228
	public function testGenerateImageWithInvalidParameters() {
229
		$image = $this->objFromFixture('Image', 'imageWithoutTitle');
230
		$image->ScaleHeight('String');
231
		$image->Pad(600,600,'XXXXXX');
232
	}
233
234
	public function testCacheFilename() {
235
		$image = $this->objFromFixture('Image', 'imageWithoutTitle');
236
		$imageFirst = $image->Pad(200,200,'CCCCCC');
237
		$imageFilename = $imageFirst->getURL();
238
			// Encoding of the arguments is duplicated from cacheFilename
239
		$neededPart = 'Pad' . Convert::base64url_encode(array(200,200,'CCCCCC'));
240
		$this->assertContains($neededPart, $imageFilename, 'Filename for cached image is correctly generated');
241
	}
242
243
	/**
244
	 * Test that propertes from the source Image are inherited by resampled images
245
	 */
246
	public function testPropertyInheritance() {
247
		$testString = 'This is a test';
248
		$origImage = $this->objFromFixture('Image', 'imageWithTitle');
249
		$origImage->TestProperty = $testString;
0 ignored issues
show
Documentation introduced by
The property TestProperty does not exist on object<DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
250
		$resampled = $origImage->ScaleWidth(10);
251
		$this->assertEquals($resampled->TestProperty, $testString);
252
		$resampled2 = $resampled->ScaleWidth(5);
253
		$this->assertEquals($resampled2->TestProperty, $testString);
254
	}
255
256
	public function testShortcodeHandlerFallsBackToFileProperties() {
257
		$image = $this->objFromFixture('Image', 'imageWithTitle');
258
		$parser = new ShortcodeParser();
259
		$parser->register('image', array('Image', 'handle_shortcode'));
260
261
		$this->assertEquals(
262
			sprintf(
263
				'<img src="%s" alt="%s">',
264
				$image->Link(),
265
				$image->Title
266
			),
267
			$parser->parse(sprintf('[image id=%d]', $image->ID))
268
		);
269
	}
270
271
	public function testShortcodeHandlerUsesShortcodeProperties() {
272
		$image = $this->objFromFixture('Image', 'imageWithTitle');
273
		$parser = new ShortcodeParser();
274
		$parser->register('image', array('Image', 'handle_shortcode'));
275
276
		$this->assertEquals(
277
			sprintf(
278
				'<img src="%s" alt="Alt content" title="Title content">',
279
				$image->Link()
280
			),
281
			$parser->parse(sprintf(
282
				'[image id="%d" alt="Alt content" title="Title content"]',
283
				$image->ID
284
			))
285
		);
286
	}
287
288
	public function testShortcodeHandlerAddsDefaultAttributes() {
289
		$image = $this->objFromFixture('Image', 'imageWithoutTitle');
290
		$parser = new ShortcodeParser();
291
		$parser->register('image', array('Image', 'handle_shortcode'));
292
293
		$this->assertEquals(
294
			sprintf(
295
				'<img src="%s" alt="%s">',
296
				$image->Link(),
297
				$image->Title
298
			),
299
			$parser->parse(sprintf(
300
				'[image id="%d"]',
301
				$image->ID
302
			))
303
		);
304
	}
305
}
306