silverstripe-framework/tests/model/ImageTest.php

306 lines
10 KiB
PHP
Raw Normal View History

<?php
use Filesystem as SS_Filesystem;
use League\Flysystem\Filesystem;
use SilverStripe\Filesystem\Flysystem\AssetAdapter;
use SilverStripe\Filesystem\Flysystem\FlysystemAssetStore;
use SilverStripe\Filesystem\Flysystem\FlysystemUrlPlugin;
/**
* @package framework
* @subpackage tests
*/
class ImageTest extends SapphireTest {
2014-08-15 08:53:05 +02:00
protected static $fixture_file = 'ImageTest.yml';
2014-08-15 08:53:05 +02:00
public function setUp() {
parent::setUp();
2014-08-15 08:53:05 +02:00
// Execute specific subclass
if(get_class($this) == "ImageTest") {
$this->markTestSkipped(sprintf('Skipping %s ', get_class($this)));
return;
}
// Set backend root to /ImageTest
AssetStoreTest_SpyStore::activate('ImageTest');
// Copy test images for each of the fixture references
$files = File::get()->exclude('ClassName', 'Folder');
foreach($files as $image) {
$filePath = AssetStoreTest_SpyStore::getLocalPath($image); // Only correct for test asset store
$sourcePath = BASE_PATH . '/framework/tests/model/testimages/' . $image->Name;
if(!file_exists($filePath)) {
SS_Filesystem::makeFolder(dirname($filePath));
if (!copy($sourcePath, $filePath)) {
user_error('Failed to copy test images', E_USER_ERROR);
}
}
}
}
2014-08-15 08:53:05 +02:00
public function tearDown() {
AssetStoreTest_SpyStore::reset();
parent::tearDown();
}
2014-08-15 08:53:05 +02:00
public function testGetTagWithTitle() {
Config::inst()->update('DBFile', 'force_resample', false);
2016-03-08 21:50:18 +01:00
$image = $this->objFromFixture('Image', 'imageWithTitle');
$expected = '<img src="/assets/ImageTest/folder/444065542b/test-image.png" alt="This is a image Title" />';
$actual = trim($image->getTag());
2014-08-15 08:53:05 +02:00
$this->assertEquals($expected, $actual);
}
2014-08-15 08:53:05 +02:00
public function testGetTagWithoutTitle() {
Config::inst()->update('DBFile', 'force_resample', false);
2016-03-08 21:50:18 +01:00
$image = $this->objFromFixture('Image', 'imageWithoutTitle');
$expected = '<img src="/assets/ImageTest/folder/444065542b/test-image.png" alt="test image" />';
$actual = trim($image->getTag());
2014-08-15 08:53:05 +02:00
$this->assertEquals($expected, $actual);
}
2014-08-15 08:53:05 +02:00
public function testGetTagWithoutTitleContainingDots() {
Config::inst()->update('DBFile', 'force_resample', false);
2016-03-08 21:50:18 +01:00
$image = $this->objFromFixture('Image', 'imageWithoutTitleContainingDots');
$expected = '<img src="/assets/ImageTest/folder/46affab704/test.image.with.dots.png" alt="test.image.with.dots" />';
$actual = trim($image->getTag());
2014-08-15 08:53:05 +02:00
$this->assertEquals($expected, $actual);
}
2014-08-15 08:53:05 +02:00
/**
* Tests that multiple image manipulations may be performed on a single Image
*/
public function testMultipleGenerateManipulationCalls() {
$image = $this->objFromFixture('Image', 'imageWithoutTitle');
2014-08-15 08:53:05 +02:00
$imageFirst = $image->ScaleWidth(200);
$this->assertNotNull($imageFirst);
$expected = 200;
$actual = $imageFirst->getWidth();
$this->assertEquals($expected, $actual);
2014-08-15 08:53:05 +02:00
$imageSecond = $imageFirst->ScaleHeight(100);
$this->assertNotNull($imageSecond);
$expected = 100;
$actual = $imageSecond->getHeight();
$this->assertEquals($expected, $actual);
}
2014-08-15 08:53:05 +02:00
/**
* Tests that image manipulations that do not affect the resulting dimensions
* of the output image do not resample the file.
*/
public function testReluctanceToResampling() {
$image = $this->objFromFixture('Image', 'imageWithoutTitle');
$this->assertTrue($image->isSize(300, 300));
2014-08-15 08:53:05 +02:00
// Set width to 300 pixels
$imageScaleWidth = $image->ScaleWidth(300);
$this->assertEquals($imageScaleWidth->getWidth(), 300);
$this->assertEquals($image->Filename, $imageScaleWidth->Filename);
2014-08-15 08:53:05 +02:00
// Set height to 300 pixels
$imageScaleHeight = $image->ScaleHeight(300);
$this->assertEquals($imageScaleHeight->getHeight(), 300);
$this->assertEquals($image->Filename, $imageScaleHeight->Filename);
2014-08-15 08:53:05 +02:00
// Crop image to 300 x 300
$imageCropped = $image->Fill(300, 300);
$this->assertTrue($imageCropped->isSize(300, 300));
$this->assertEquals($image->Filename, $imageCropped->Filename);
2014-08-15 08:53:05 +02:00
// Resize (padded) to 300 x 300
$imageSized = $image->Pad(300, 300);
$this->assertTrue($imageSized->isSize(300, 300));
$this->assertEquals($image->Filename, $imageSized->Filename);
2014-08-15 08:53:05 +02:00
// Padded image 300 x 300 (same as above)
$imagePadded = $image->Pad(300, 300);
$this->assertTrue($imagePadded->isSize(300, 300));
$this->assertEquals($image->Filename, $imagePadded->Filename);
2014-08-15 08:53:05 +02:00
// Resized (stretched) to 300 x 300
$imageStretched = $image->ResizedImage(300, 300);
$this->assertTrue($imageStretched->isSize(300, 300));
$this->assertEquals($image->Filename, $imageStretched->Filename);
2014-08-15 08:53:05 +02:00
// Fit (various options)
$imageFit = $image->Fit(300, 600);
$this->assertTrue($imageFit->isSize(300, 300));
$this->assertEquals($image->Filename, $imageFit->Filename);
$imageFit = $image->Fit(600, 300);
$this->assertTrue($imageFit->isSize(300, 300));
$this->assertEquals($image->Filename, $imageFit->Filename);
$imageFit = $image->Fit(300, 300);
$this->assertTrue($imageFit->isSize(300, 300));
$this->assertEquals($image->Filename, $imageFit->Filename);
}
/**
2016-03-08 21:50:18 +01:00
* Tests that a URL to a resampled image is provided when force_resample is
* set to true, if the resampled file is smaller than the original.
*/
public function testForceResample() {
$imageHQ = $this->objFromFixture('Image', 'highQualityJPEG');
$imageHQR = $imageHQ->Resampled();
$imageLQ = $this->objFromFixture('Image', 'lowQualityJPEG');
$imageLQR = $imageLQ->Resampled();
Merge remote-tracking branch 'origin/3' # Conflicts: # control/Director.php # control/HTTP.php # core/startup/ParameterConfirmationToken.php # docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md # docs/en/00_Getting_Started/04_Directory_Structure.md # docs/en/00_Getting_Started/05_Coding_Conventions.md # docs/en/01_Tutorials/01_Building_A_Basic_Site.md # docs/en/01_Tutorials/02_Extending_A_Basic_Site.md # docs/en/01_Tutorials/03_Forms.md # docs/en/01_Tutorials/04_Site_Search.md # docs/en/01_Tutorials/05_Dataobject_Relationship_Management.md # docs/en/02_Developer_Guides/12_Search/01_Searchcontext.md # docs/en/02_Developer_Guides/13_i18n/index.md # docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/06_Javascript_Development.md # docs/en/03_Upgrading/index.md # docs/en/changelogs/index.md # docs/en/howto/customize-cms-menu.md # docs/en/howto/navigation-menu.md # docs/en/index.md # docs/en/installation/index.md # docs/en/installation/windows-manual-iis-6.md # docs/en/misc/contributing/code.md # docs/en/misc/contributing/issues.md # docs/en/misc/module-release-process.md # docs/en/reference/dataobject.md # docs/en/reference/execution-pipeline.md # docs/en/reference/grid-field.md # docs/en/reference/modeladmin.md # docs/en/reference/rssfeed.md # docs/en/reference/templates.md # docs/en/topics/commandline.md # docs/en/topics/debugging.md # docs/en/topics/email.md # docs/en/topics/forms.md # docs/en/topics/index.md # docs/en/topics/module-development.md # docs/en/topics/modules.md # docs/en/topics/page-type-templates.md # docs/en/topics/page-types.md # docs/en/topics/search.md # docs/en/topics/testing/index.md # docs/en/topics/testing/testing-guide-troubleshooting.md # docs/en/topics/theme-development.md # docs/en/tutorials/1-building-a-basic-site.md # docs/en/tutorials/2-extending-a-basic-site.md # docs/en/tutorials/3-forms.md # docs/en/tutorials/4-site-search.md # docs/en/tutorials/5-dataobject-relationship-management.md # docs/en/tutorials/building-a-basic-site.md # docs/en/tutorials/dataobject-relationship-management.md # docs/en/tutorials/extending-a-basic-site.md # docs/en/tutorials/forms.md # docs/en/tutorials/index.md # docs/en/tutorials/site-search.md # main.php # model/SQLQuery.php # security/ChangePasswordForm.php # security/MemberLoginForm.php # tests/control/ControllerTest.php # tests/core/startup/ParameterConfirmationTokenTest.php # tests/model/SQLQueryTest.php # tests/security/SecurityTest.php # tests/view/SSViewerTest.php # view/SSTemplateParser.php # view/SSTemplateParser.php.inc # view/SSViewer.php
2016-01-20 01:16:27 +01:00
// Test resampled file is served when force_resample = true
Config::inst()->update('DBFile', 'force_resample', true);
$this->assertLessThan($imageHQ->getAbsoluteSize(), $imageHQR->getAbsoluteSize(), 'Resampled image is smaller than original');
$this->assertEquals($imageHQ->getURL(), $imageHQR->getSourceURL(), 'Path to a resampled image was returned by getURL()');
Merge remote-tracking branch 'origin/3' # Conflicts: # control/Director.php # control/HTTP.php # core/startup/ParameterConfirmationToken.php # docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md # docs/en/00_Getting_Started/04_Directory_Structure.md # docs/en/00_Getting_Started/05_Coding_Conventions.md # docs/en/01_Tutorials/01_Building_A_Basic_Site.md # docs/en/01_Tutorials/02_Extending_A_Basic_Site.md # docs/en/01_Tutorials/03_Forms.md # docs/en/01_Tutorials/04_Site_Search.md # docs/en/01_Tutorials/05_Dataobject_Relationship_Management.md # docs/en/02_Developer_Guides/12_Search/01_Searchcontext.md # docs/en/02_Developer_Guides/13_i18n/index.md # docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/06_Javascript_Development.md # docs/en/03_Upgrading/index.md # docs/en/changelogs/index.md # docs/en/howto/customize-cms-menu.md # docs/en/howto/navigation-menu.md # docs/en/index.md # docs/en/installation/index.md # docs/en/installation/windows-manual-iis-6.md # docs/en/misc/contributing/code.md # docs/en/misc/contributing/issues.md # docs/en/misc/module-release-process.md # docs/en/reference/dataobject.md # docs/en/reference/execution-pipeline.md # docs/en/reference/grid-field.md # docs/en/reference/modeladmin.md # docs/en/reference/rssfeed.md # docs/en/reference/templates.md # docs/en/topics/commandline.md # docs/en/topics/debugging.md # docs/en/topics/email.md # docs/en/topics/forms.md # docs/en/topics/index.md # docs/en/topics/module-development.md # docs/en/topics/modules.md # docs/en/topics/page-type-templates.md # docs/en/topics/page-types.md # docs/en/topics/search.md # docs/en/topics/testing/index.md # docs/en/topics/testing/testing-guide-troubleshooting.md # docs/en/topics/theme-development.md # docs/en/tutorials/1-building-a-basic-site.md # docs/en/tutorials/2-extending-a-basic-site.md # docs/en/tutorials/3-forms.md # docs/en/tutorials/4-site-search.md # docs/en/tutorials/5-dataobject-relationship-management.md # docs/en/tutorials/building-a-basic-site.md # docs/en/tutorials/dataobject-relationship-management.md # docs/en/tutorials/extending-a-basic-site.md # docs/en/tutorials/forms.md # docs/en/tutorials/index.md # docs/en/tutorials/site-search.md # main.php # model/SQLQuery.php # security/ChangePasswordForm.php # security/MemberLoginForm.php # tests/control/ControllerTest.php # tests/core/startup/ParameterConfirmationTokenTest.php # tests/model/SQLQueryTest.php # tests/security/SecurityTest.php # tests/view/SSViewerTest.php # view/SSTemplateParser.php # view/SSTemplateParser.php.inc # view/SSViewer.php
2016-01-20 01:16:27 +01:00
// Test original file is served when force_resample = true but original file is low quality
$this->assertGreaterThanOrEqual($imageLQ->getAbsoluteSize(), $imageLQR->getAbsoluteSize(), 'Resampled image is larger or same size as original');
$this->assertNotEquals($imageLQ->getURL(), $imageLQR->getSourceURL(), 'Path to the original image file was returned by getURL()');
Merge remote-tracking branch 'origin/3' # Conflicts: # control/Director.php # control/HTTP.php # core/startup/ParameterConfirmationToken.php # docs/en/00_Getting_Started/01_Installation/05_Common_Problems.md # docs/en/00_Getting_Started/04_Directory_Structure.md # docs/en/00_Getting_Started/05_Coding_Conventions.md # docs/en/01_Tutorials/01_Building_A_Basic_Site.md # docs/en/01_Tutorials/02_Extending_A_Basic_Site.md # docs/en/01_Tutorials/03_Forms.md # docs/en/01_Tutorials/04_Site_Search.md # docs/en/01_Tutorials/05_Dataobject_Relationship_Management.md # docs/en/02_Developer_Guides/12_Search/01_Searchcontext.md # docs/en/02_Developer_Guides/13_i18n/index.md # docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/06_Javascript_Development.md # docs/en/03_Upgrading/index.md # docs/en/changelogs/index.md # docs/en/howto/customize-cms-menu.md # docs/en/howto/navigation-menu.md # docs/en/index.md # docs/en/installation/index.md # docs/en/installation/windows-manual-iis-6.md # docs/en/misc/contributing/code.md # docs/en/misc/contributing/issues.md # docs/en/misc/module-release-process.md # docs/en/reference/dataobject.md # docs/en/reference/execution-pipeline.md # docs/en/reference/grid-field.md # docs/en/reference/modeladmin.md # docs/en/reference/rssfeed.md # docs/en/reference/templates.md # docs/en/topics/commandline.md # docs/en/topics/debugging.md # docs/en/topics/email.md # docs/en/topics/forms.md # docs/en/topics/index.md # docs/en/topics/module-development.md # docs/en/topics/modules.md # docs/en/topics/page-type-templates.md # docs/en/topics/page-types.md # docs/en/topics/search.md # docs/en/topics/testing/index.md # docs/en/topics/testing/testing-guide-troubleshooting.md # docs/en/topics/theme-development.md # docs/en/tutorials/1-building-a-basic-site.md # docs/en/tutorials/2-extending-a-basic-site.md # docs/en/tutorials/3-forms.md # docs/en/tutorials/4-site-search.md # docs/en/tutorials/5-dataobject-relationship-management.md # docs/en/tutorials/building-a-basic-site.md # docs/en/tutorials/dataobject-relationship-management.md # docs/en/tutorials/extending-a-basic-site.md # docs/en/tutorials/forms.md # docs/en/tutorials/index.md # docs/en/tutorials/site-search.md # main.php # model/SQLQuery.php # security/ChangePasswordForm.php # security/MemberLoginForm.php # tests/control/ControllerTest.php # tests/core/startup/ParameterConfirmationTokenTest.php # tests/model/SQLQueryTest.php # tests/security/SecurityTest.php # tests/view/SSViewerTest.php # view/SSTemplateParser.php # view/SSTemplateParser.php.inc # view/SSViewer.php
2016-01-20 01:16:27 +01:00
// Test original file is served when force_resample = false
Config::inst()->update('DBFile', 'force_resample', false);
$this->assertNotEquals($imageHQ->getURL(), $imageHQR->getSourceURL(), 'Path to the original image file was returned by getURL()');
}
2014-08-15 08:53:05 +02:00
public function testImageResize() {
$image = $this->objFromFixture('Image', 'imageWithoutTitle');
$this->assertTrue($image->isSize(300, 300));
2014-08-15 08:53:05 +02:00
// Test normal resize
$resized = $image->Pad(150, 100);
$this->assertTrue($resized->isSize(150, 100));
2014-08-15 08:53:05 +02:00
// Test cropped resize
$cropped = $image->Fill(100, 200);
$this->assertTrue($cropped->isSize(100, 200));
2014-08-15 08:53:05 +02:00
// Test padded resize
$padded = $image->Pad(200, 100);
$this->assertTrue($padded->isSize(200, 100));
2014-08-15 08:53:05 +02:00
// Test Fit
$ratio = $image->Fit(80, 160);
$this->assertTrue($ratio->isSize(80, 80));
// Test FitMax
$fitMaxDn = $image->FitMax(200, 100);
$this->assertTrue($fitMaxDn->isSize(100, 100));
$fitMaxUp = $image->FitMax(500, 400);
$this->assertTrue($fitMaxUp->isSize(300, 300));
2016-03-08 21:50:18 +01:00
//Test ScaleMax
$scaleMaxWDn = $image->ScaleMaxWidth(200);
$this->assertTrue($scaleMaxWDn->isSize(200, 200));
$scaleMaxWUp = $image->ScaleMaxWidth(400);
$this->assertTrue($scaleMaxWUp->isSize(300, 300));
$scaleMaxHDn = $image->ScaleMaxHeight(200);
$this->assertTrue($scaleMaxHDn->isSize(200, 200));
$scaleMaxHUp = $image->ScaleMaxHeight(400);
$this->assertTrue($scaleMaxHUp->isSize(300, 300));
// Test FillMax
$cropMaxDn = $image->FillMax(200, 100);
$this->assertTrue($cropMaxDn->isSize(200, 100));
$cropMaxUp = $image->FillMax(400, 200);
$this->assertTrue($cropMaxUp->isSize(300, 150));
2016-03-08 21:50:18 +01:00
// Test Clip
$clipWDn = $image->CropWidth(200);
$this->assertTrue($clipWDn->isSize(200, 300));
$clipWUp = $image->CropWidth(400);
$this->assertTrue($clipWUp->isSize(300, 300));
$clipHDn = $image->CropHeight(200);
$this->assertTrue($clipHDn->isSize(300, 200));
$clipHUp = $image->CropHeight(400);
$this->assertTrue($clipHUp->isSize(300, 300));
}
/**
2014-11-18 23:05:07 +01:00
* @expectedException InvalidArgumentException
*/
public function testGenerateImageWithInvalidParameters() {
$image = $this->objFromFixture('Image', 'imageWithoutTitle');
$image->ScaleHeight('String');
$image->Pad(600,600,'XXXXXX');
}
2014-08-15 08:53:05 +02:00
public function testCacheFilename() {
$image = $this->objFromFixture('Image', 'imageWithoutTitle');
$imageFirst = $image->Pad(200,200,'CCCCCC');
$imageFilename = $imageFirst->getURL();
// Encoding of the arguments is duplicated from cacheFilename
$neededPart = 'Pad' . Convert::base64url_encode(array(200,200,'CCCCCC'));
$this->assertContains($neededPart, $imageFilename, 'Filename for cached image is correctly generated');
}
2014-08-15 08:53:05 +02:00
/**
2016-03-08 21:50:18 +01:00
* Test that propertes from the source Image are inherited by resampled images
*/
public function testPropertyInheritance() {
$testString = 'This is a test';
$origImage = $this->objFromFixture('Image', 'imageWithTitle');
$origImage->TestProperty = $testString;
$resampled = $origImage->ScaleWidth(10);
$this->assertEquals($resampled->TestProperty, $testString);
$resampled2 = $resampled->ScaleWidth(5);
$this->assertEquals($resampled2->TestProperty, $testString);
}
2016-03-08 12:20:51 +01:00
public function testShortcodeHandlerFallsBackToFileProperties() {
$image = $this->objFromFixture('Image', 'imageWithTitle');
$parser = new ShortcodeParser();
$parser->register('image', array('Image', 'handle_shortcode'));
$this->assertEquals(
sprintf(
'<img src="%s" alt="%s">',
$image->Link(),
$image->Title
),
$parser->parse(sprintf('[image id=%d]', $image->ID))
);
}
public function testShortcodeHandlerUsesShortcodeProperties() {
$image = $this->objFromFixture('Image', 'imageWithTitle');
$parser = new ShortcodeParser();
$parser->register('image', array('Image', 'handle_shortcode'));
$this->assertEquals(
sprintf(
'<img src="%s" alt="Alt content" title="Title content">',
$image->Link()
),
$parser->parse(sprintf(
'[image id="%d" alt="Alt content" title="Title content"]',
$image->ID
))
);
}
public function testShortcodeHandlerAddsDefaultAttributes() {
$image = $this->objFromFixture('Image', 'imageWithoutTitle');
$parser = new ShortcodeParser();
$parser->register('image', array('Image', 'handle_shortcode'));
$this->assertEquals(
sprintf(
'<img src="%s" alt="%s">',
$image->Link(),
$image->Title
),
$parser->parse(sprintf(
'[image id="%d"]',
$image->ID
))
);
}
}