2015-12-09 22:19:23 +01:00
|
|
|
<?php
|
|
|
|
use SilverStripe\Filesystem\Storage\AssetStore;
|
2016-06-15 06:03:16 +02:00
|
|
|
use SilverStripe\ORM\Versioning\Versioned;
|
|
|
|
use SilverStripe\ORM\DataObject;
|
2016-06-23 01:37:22 +02:00
|
|
|
use SilverStripe\Security\Member;
|
|
|
|
|
2016-06-15 06:03:16 +02:00
|
|
|
|
2015-12-09 22:19:23 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests {@see AssetControlExtension}
|
|
|
|
*/
|
|
|
|
class AssetControlExtensionTest extends SapphireTest {
|
|
|
|
|
|
|
|
protected $extraDataObjects = array(
|
|
|
|
'AssetControlExtensionTest_VersionedObject',
|
|
|
|
'AssetControlExtensionTest_Object'
|
|
|
|
);
|
|
|
|
|
|
|
|
public function setUp() {
|
|
|
|
parent::setUp();
|
|
|
|
|
|
|
|
// Set backend and base url
|
2016-06-15 06:03:16 +02:00
|
|
|
Versioned::set_stage(Versioned::DRAFT);
|
2015-12-09 22:19:23 +01:00
|
|
|
AssetStoreTest_SpyStore::activate('AssetControlExtensionTest');
|
2016-01-26 04:56:07 +01:00
|
|
|
$this->logInWithPermission('ADMIN');
|
2015-12-09 22:19:23 +01:00
|
|
|
|
|
|
|
// Setup fixture manually
|
|
|
|
$object1 = new AssetControlExtensionTest_VersionedObject();
|
|
|
|
$object1->Title = 'My object';
|
|
|
|
$fish1 = realpath(__DIR__ .'/../model/testimages/test-image-high-quality.jpg');
|
|
|
|
$object1->Header->setFromLocalFile($fish1, 'Header/MyObjectHeader.jpg');
|
|
|
|
$object1->Download->setFromString('file content', 'Documents/File.txt');
|
|
|
|
$object1->write();
|
2016-04-01 05:27:59 +02:00
|
|
|
$object1->publishSingle();
|
2015-12-09 22:19:23 +01:00
|
|
|
|
|
|
|
$object2 = new AssetControlExtensionTest_Object();
|
|
|
|
$object2->Title = 'Unversioned';
|
|
|
|
$object2->Image->setFromLocalFile($fish1, 'Images/BeautifulFish.jpg');
|
|
|
|
$object2->write();
|
|
|
|
|
|
|
|
$object3 = new AssetControlExtensionTest_ArchivedObject();
|
|
|
|
$object3->Title = 'Archived';
|
|
|
|
$object3->Header->setFromLocalFile($fish1, 'Archived/MyObjectHeader.jpg');
|
|
|
|
$object3->write();
|
2016-04-01 05:27:59 +02:00
|
|
|
$object3->publishSingle();
|
2015-12-09 22:19:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function tearDown() {
|
|
|
|
AssetStoreTest_SpyStore::reset();
|
|
|
|
parent::tearDown();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testFileDelete() {
|
2016-06-15 06:03:16 +02:00
|
|
|
Versioned::set_stage(Versioned::DRAFT);
|
2016-01-26 04:56:07 +01:00
|
|
|
|
2015-12-09 22:19:23 +01:00
|
|
|
/** @var AssetControlExtensionTest_VersionedObject $object1 */
|
|
|
|
$object1 = AssetControlExtensionTest_VersionedObject::get()
|
|
|
|
->filter('Title', 'My object')
|
|
|
|
->first();
|
|
|
|
/** @var AssetControlExtensionTest_Object $object2 */
|
|
|
|
$object2 = AssetControlExtensionTest_Object::get()
|
|
|
|
->filter('Title', 'Unversioned')
|
|
|
|
->first();
|
|
|
|
|
|
|
|
/** @var AssetControlExtensionTest_ArchivedObject $object3 */
|
|
|
|
$object3 = AssetControlExtensionTest_ArchivedObject::get()
|
|
|
|
->filter('Title', 'Archived')
|
|
|
|
->first();
|
|
|
|
|
|
|
|
$this->assertTrue($object1->Download->exists());
|
|
|
|
$this->assertTrue($object1->Header->exists());
|
|
|
|
$this->assertTrue($object2->Image->exists());
|
|
|
|
$this->assertTrue($object3->Header->exists());
|
|
|
|
$this->assertEquals(AssetStore::VISIBILITY_PUBLIC, $object1->Download->getVisibility());
|
|
|
|
$this->assertEquals(AssetStore::VISIBILITY_PUBLIC, $object1->Header->getVisibility());
|
|
|
|
$this->assertEquals(AssetStore::VISIBILITY_PUBLIC, $object2->Image->getVisibility());
|
|
|
|
$this->assertEquals(AssetStore::VISIBILITY_PUBLIC, $object3->Header->getVisibility());
|
|
|
|
|
|
|
|
// Check live stage for versioned objects
|
|
|
|
$object1Live = Versioned::get_one_by_stage('AssetControlExtensionTest_VersionedObject', 'Live',
|
|
|
|
array('"ID"' => $object1->ID)
|
|
|
|
);
|
|
|
|
$object3Live = Versioned::get_one_by_stage('AssetControlExtensionTest_ArchivedObject', 'Live',
|
|
|
|
array('"ID"' => $object3->ID)
|
|
|
|
);
|
|
|
|
$this->assertTrue($object1Live->Download->exists());
|
|
|
|
$this->assertTrue($object1Live->Header->exists());
|
|
|
|
$this->assertTrue($object3Live->Header->exists());
|
|
|
|
$this->assertEquals(AssetStore::VISIBILITY_PUBLIC, $object1Live->Download->getVisibility());
|
|
|
|
$this->assertEquals(AssetStore::VISIBILITY_PUBLIC, $object1Live->Header->getVisibility());
|
|
|
|
$this->assertEquals(AssetStore::VISIBILITY_PUBLIC, $object3Live->Header->getVisibility());
|
|
|
|
|
|
|
|
// Delete live records; Should cause versioned records to be protected
|
|
|
|
$object1Live->deleteFromStage('Live');
|
|
|
|
$object3Live->deleteFromStage('Live');
|
|
|
|
$this->assertTrue($object1->Download->exists());
|
|
|
|
$this->assertTrue($object1->Header->exists());
|
|
|
|
$this->assertTrue($object3->Header->exists());
|
|
|
|
$this->assertTrue($object1Live->Download->exists());
|
|
|
|
$this->assertTrue($object1Live->Header->exists());
|
|
|
|
$this->assertTrue($object3Live->Header->exists());
|
|
|
|
$this->assertEquals(AssetStore::VISIBILITY_PROTECTED, $object1->Download->getVisibility());
|
|
|
|
$this->assertEquals(AssetStore::VISIBILITY_PROTECTED, $object1->Header->getVisibility());
|
|
|
|
$this->assertEquals(AssetStore::VISIBILITY_PROTECTED, $object3->Header->getVisibility());
|
|
|
|
|
|
|
|
// Delete draft record; Should remove all records
|
|
|
|
// Archived assets only should remain
|
|
|
|
$object1->delete();
|
|
|
|
$object2->delete();
|
|
|
|
$object3->delete();
|
|
|
|
$this->assertFalse($object1->Download->exists());
|
|
|
|
$this->assertFalse($object1->Header->exists());
|
|
|
|
$this->assertFalse($object2->Image->exists());
|
|
|
|
$this->assertTrue($object3->Header->exists());
|
|
|
|
$this->assertFalse($object1Live->Download->exists());
|
|
|
|
$this->assertFalse($object1Live->Header->exists());
|
|
|
|
$this->assertTrue($object3Live->Header->exists());
|
|
|
|
$this->assertNull($object1->Download->getVisibility());
|
|
|
|
$this->assertNull($object1->Header->getVisibility());
|
|
|
|
$this->assertNull($object2->Image->getVisibility());
|
|
|
|
$this->assertEquals(AssetStore::VISIBILITY_PROTECTED, $object3->Header->getVisibility());
|
|
|
|
}
|
2016-01-26 04:56:07 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Test files being replaced
|
|
|
|
*/
|
|
|
|
public function testReplaceFile() {
|
2016-06-15 06:03:16 +02:00
|
|
|
Versioned::set_stage(Versioned::DRAFT);
|
2016-01-26 04:56:07 +01:00
|
|
|
|
|
|
|
/** @var AssetControlExtensionTest_VersionedObject $object1 */
|
|
|
|
$object1 = AssetControlExtensionTest_VersionedObject::get()
|
|
|
|
->filter('Title', 'My object')
|
|
|
|
->first();
|
|
|
|
/** @var AssetControlExtensionTest_Object $object2 */
|
|
|
|
$object2 = AssetControlExtensionTest_Object::get()
|
|
|
|
->filter('Title', 'Unversioned')
|
|
|
|
->first();
|
|
|
|
|
|
|
|
/** @var AssetControlExtensionTest_ArchivedObject $object3 */
|
|
|
|
$object3 = AssetControlExtensionTest_ArchivedObject::get()
|
|
|
|
->filter('Title', 'Archived')
|
|
|
|
->first();
|
|
|
|
|
|
|
|
$object1TupleOld = $object1->Header->getValue();
|
|
|
|
$object2TupleOld = $object2->Image->getValue();
|
|
|
|
$object3TupleOld = $object3->Header->getValue();
|
|
|
|
|
|
|
|
// Replace image and write each to filesystem
|
|
|
|
$fish1 = realpath(__DIR__ .'/../model/testimages/test-image-high-quality.jpg');
|
|
|
|
$object1->Header->setFromLocalFile($fish1, 'Header/Replaced_MyObjectHeader.jpg');
|
|
|
|
$object1->write();
|
|
|
|
$object2->Image->setFromLocalFile($fish1, 'Images/Replaced_BeautifulFish.jpg');
|
|
|
|
$object2->write();
|
|
|
|
$object3->Header->setFromLocalFile($fish1, 'Archived/Replaced_MyObjectHeader.jpg');
|
|
|
|
$object3->write();
|
|
|
|
|
|
|
|
// Check that old published records are left public, but removed for unversioned object2
|
|
|
|
$this->assertEquals(
|
|
|
|
AssetStore::VISIBILITY_PUBLIC,
|
|
|
|
$this->getAssetStore()->getVisibility($object1TupleOld['Filename'], $object1TupleOld['Hash'])
|
|
|
|
);
|
|
|
|
$this->assertEquals(
|
|
|
|
null, // Old file is destroyed
|
|
|
|
$this->getAssetStore()->getVisibility($object2TupleOld['Filename'], $object2TupleOld['Hash'])
|
|
|
|
);
|
|
|
|
$this->assertEquals(
|
|
|
|
AssetStore::VISIBILITY_PUBLIC,
|
|
|
|
$this->getAssetStore()->getVisibility($object3TupleOld['Filename'], $object3TupleOld['Hash'])
|
|
|
|
);
|
|
|
|
|
|
|
|
// Check that visibility of new file is correct
|
|
|
|
// Note that $object2 has no canView() is true, so assets end up public
|
|
|
|
$this->assertEquals(AssetStore::VISIBILITY_PROTECTED, $object1->Header->getVisibility());
|
|
|
|
$this->assertEquals(AssetStore::VISIBILITY_PUBLIC, $object2->Image->getVisibility());
|
|
|
|
$this->assertEquals(AssetStore::VISIBILITY_PROTECTED, $object3->Header->getVisibility());
|
|
|
|
|
|
|
|
// Publish changes to versioned records
|
2016-04-01 05:27:59 +02:00
|
|
|
$object1->publishSingle();
|
|
|
|
$object3->publishSingle();
|
2016-01-26 04:56:07 +01:00
|
|
|
|
|
|
|
// After publishing, old object1 is deleted, but since object3 has archiving enabled,
|
|
|
|
// the orphaned file is intentionally left in the protected store
|
|
|
|
$this->assertEquals(
|
|
|
|
null,
|
|
|
|
$this->getAssetStore()->getVisibility($object1TupleOld['Filename'], $object1TupleOld['Hash'])
|
|
|
|
);
|
|
|
|
$this->assertEquals(
|
|
|
|
AssetStore::VISIBILITY_PROTECTED,
|
|
|
|
$this->getAssetStore()->getVisibility($object3TupleOld['Filename'], $object3TupleOld['Hash'])
|
|
|
|
);
|
|
|
|
|
|
|
|
// And after publish, all files are public
|
|
|
|
$this->assertEquals(AssetStore::VISIBILITY_PUBLIC, $object1->Header->getVisibility());
|
|
|
|
$this->assertEquals(AssetStore::VISIBILITY_PUBLIC, $object3->Header->getVisibility());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return AssetStore
|
|
|
|
*/
|
|
|
|
protected function getAssetStore() {
|
|
|
|
return Injector::inst()->get('AssetStore');
|
|
|
|
}
|
|
|
|
|
2015-12-09 22:19:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Versioned object with attached assets
|
|
|
|
*
|
|
|
|
* @property string $Title
|
|
|
|
* @property DBFile $Header
|
|
|
|
* @property DBFile $Download
|
|
|
|
* @mixin Versioned
|
|
|
|
*/
|
|
|
|
class AssetControlExtensionTest_VersionedObject extends DataObject implements TestOnly {
|
|
|
|
private static $extensions = array(
|
2016-06-15 06:03:16 +02:00
|
|
|
'SilverStripe\\ORM\\Versioning\\Versioned'
|
2015-12-09 22:19:23 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
private static $db = array(
|
|
|
|
'Title' => 'Varchar(255)',
|
|
|
|
'Header' => "DBFile('image/supported')",
|
|
|
|
'Download' => 'DBFile'
|
|
|
|
);
|
2016-01-26 04:56:07 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Member $member
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function canView($member = null) {
|
|
|
|
if(!$member) {
|
|
|
|
$member = Member::currentUser();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Expectation that versioned::canView will hide this object in draft
|
|
|
|
$result = $this->extendedCan('canView', $member);
|
|
|
|
if($result !== null) {
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Open to public
|
|
|
|
return true;
|
|
|
|
}
|
2015-12-09 22:19:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A basic unversioned object
|
|
|
|
*
|
|
|
|
* @property string $Title
|
|
|
|
* @property DBFile $Image
|
|
|
|
*/
|
|
|
|
class AssetControlExtensionTest_Object extends DataObject implements TestOnly {
|
|
|
|
private static $db = array(
|
|
|
|
'Title' => 'Varchar(255)',
|
|
|
|
'Image' => "DBFile('image/supported')"
|
|
|
|
);
|
2016-01-26 04:56:07 +01:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Member $member
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function canView($member = null) {
|
|
|
|
return true;
|
|
|
|
}
|
2015-12-09 22:19:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Versioned object that always archives its assets
|
|
|
|
*/
|
|
|
|
class AssetControlExtensionTest_ArchivedObject extends AssetControlExtensionTest_VersionedObject {
|
2016-01-26 04:56:07 +01:00
|
|
|
private static $keep_archived_assets = true;
|
2015-12-09 22:19:23 +01:00
|
|
|
}
|