2009-10-11 02:06:58 +02:00
|
|
|
|
<?php
|
2016-06-03 10:51:02 +02:00
|
|
|
|
|
2016-07-12 08:51:08 +02:00
|
|
|
|
use SilverStripe\ORM\FieldType\DBField;
|
2016-06-03 10:51:02 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
/**
|
2014-08-15 08:53:05 +02:00
|
|
|
|
* See {@link SSViewerTest->testCastingHelpers()} for more tests related to casting and ViewableData behaviour,
|
2012-02-29 20:35:48 +01:00
|
|
|
|
* from a template-parsing perspective.
|
2014-08-15 08:53:05 +02:00
|
|
|
|
*
|
2012-04-12 08:02:46 +02:00
|
|
|
|
* @package framework
|
2009-10-11 02:06:58 +02:00
|
|
|
|
* @subpackage tests
|
|
|
|
|
*/
|
|
|
|
|
class ViewableDataTest extends SapphireTest {
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2016-06-03 10:51:02 +02:00
|
|
|
|
public function testCasting() {
|
|
|
|
|
$htmlString = """;
|
|
|
|
|
$textString = '"';
|
|
|
|
|
|
|
|
|
|
$htmlField = DBField::create_field('HTMLFragment', $textString);
|
|
|
|
|
|
|
|
|
|
$this->assertEquals($textString, $htmlField->forTemplate());
|
|
|
|
|
$this->assertEquals($htmlString, $htmlField->obj('HTMLATT')->forTemplate());
|
|
|
|
|
$this->assertEquals('%22', $htmlField->obj('URLATT')->forTemplate());
|
|
|
|
|
$this->assertEquals('%22', $htmlField->obj('RAWURLATT')->forTemplate());
|
|
|
|
|
$this->assertEquals($htmlString, $htmlField->obj('ATT')->forTemplate());
|
|
|
|
|
$this->assertEquals($textString, $htmlField->obj('RAW')->forTemplate());
|
|
|
|
|
$this->assertEquals('\"', $htmlField->obj('JS')->forTemplate());
|
2016-06-17 08:49:23 +02:00
|
|
|
|
$this->assertEquals($htmlString, $htmlField->obj('HTML')->forTemplate());
|
|
|
|
|
$this->assertEquals($htmlString, $htmlField->obj('XML')->forTemplate());
|
2016-06-03 10:51:02 +02:00
|
|
|
|
|
|
|
|
|
$textField = DBField::create_field('Text', $textString);
|
|
|
|
|
$this->assertEquals($htmlString, $textField->forTemplate());
|
|
|
|
|
$this->assertEquals($htmlString, $textField->obj('HTMLATT')->forTemplate());
|
|
|
|
|
$this->assertEquals('%22', $textField->obj('URLATT')->forTemplate());
|
|
|
|
|
$this->assertEquals('%22', $textField->obj('RAWURLATT')->forTemplate());
|
|
|
|
|
$this->assertEquals($htmlString, $textField->obj('ATT')->forTemplate());
|
|
|
|
|
$this->assertEquals($textString, $textField->obj('RAW')->forTemplate());
|
|
|
|
|
$this->assertEquals('\"', $textField->obj('JS')->forTemplate());
|
|
|
|
|
$this->assertEquals($htmlString, $textField->obj('HTML')->forTemplate());
|
|
|
|
|
$this->assertEquals($htmlString, $textField->obj('XML')->forTemplate());
|
|
|
|
|
}
|
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
public function testRequiresCasting() {
|
|
|
|
|
$caster = new ViewableDataTest_Castable();
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2016-06-03 10:51:02 +02:00
|
|
|
|
$this->assertInstanceOf('ViewableDataTest_RequiresCasting', $caster->obj('alwaysCasted'));
|
|
|
|
|
$this->assertInstanceOf('ViewableData_Caster', $caster->obj('noCastingInformation'));
|
2009-10-11 02:06:58 +02:00
|
|
|
|
}
|
2010-10-13 05:38:23 +02:00
|
|
|
|
|
|
|
|
|
public function testFailoverRequiresCasting() {
|
|
|
|
|
$caster = new ViewableDataTest_Castable();
|
2015-12-22 17:19:13 +01:00
|
|
|
|
$container = new ViewableDataTest_Container();
|
|
|
|
|
$container->setFailover($caster);
|
2010-10-13 05:38:23 +02:00
|
|
|
|
|
2016-06-03 10:51:02 +02:00
|
|
|
|
$this->assertInstanceOf('ViewableDataTest_RequiresCasting', $container->obj('alwaysCasted'));
|
|
|
|
|
$this->assertInstanceOf('ViewableDataTest_RequiresCasting', $caster->obj('alwaysCasted'));
|
2010-10-13 05:38:23 +02:00
|
|
|
|
|
2016-06-03 10:51:02 +02:00
|
|
|
|
$this->assertInstanceOf('ViewableData_Caster', $container->obj('noCastingInformation'));
|
|
|
|
|
$this->assertInstanceOf('ViewableData_Caster', $caster->obj('noCastingInformation'));
|
2010-10-13 05:38:23 +02:00
|
|
|
|
}
|
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
public function testCastingXMLVal() {
|
|
|
|
|
$caster = new ViewableDataTest_Castable();
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
$this->assertEquals('casted', $caster->XML_val('alwaysCasted'));
|
2016-06-03 10:51:02 +02:00
|
|
|
|
$this->assertEquals('casted', $caster->XML_val('noCastingInformation'));
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2016-06-03 10:51:02 +02:00
|
|
|
|
// Test automatic escaping is applied even to fields with no 'casting'
|
|
|
|
|
$this->assertEquals('casted', $caster->XML_val('unsafeXML'));
|
2009-10-11 02:06:58 +02:00
|
|
|
|
$this->assertEquals('<foo>', $caster->XML_val('castedUnsafeXML'));
|
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
public function testArrayCustomise() {
|
|
|
|
|
$viewableData = new ViewableDataTest_Castable();
|
|
|
|
|
$newViewableData = $viewableData->customise(array (
|
|
|
|
|
'test' => 'overwritten',
|
|
|
|
|
'alwaysCasted' => 'overwritten'
|
|
|
|
|
));
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
$this->assertEquals('test', $viewableData->XML_val('test'));
|
|
|
|
|
$this->assertEquals('casted', $viewableData->XML_val('alwaysCasted'));
|
2012-02-09 19:57:27 +01:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
$this->assertEquals('overwritten', $newViewableData->XML_val('test'));
|
|
|
|
|
$this->assertEquals('overwritten', $newViewableData->XML_val('alwaysCasted'));
|
2012-02-09 19:57:27 +01:00
|
|
|
|
|
|
|
|
|
$this->assertEquals('castable', $viewableData->forTemplate());
|
|
|
|
|
$this->assertEquals('castable', $newViewableData->forTemplate());
|
2009-10-11 02:06:58 +02:00
|
|
|
|
}
|
2012-02-09 19:57:27 +01:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
public function testObjectCustomise() {
|
|
|
|
|
$viewableData = new ViewableDataTest_Castable();
|
|
|
|
|
$newViewableData = $viewableData->customise(new ViewableDataTest_RequiresCasting());
|
2012-02-09 19:57:27 +01:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
$this->assertEquals('test', $viewableData->XML_val('test'));
|
|
|
|
|
$this->assertEquals('casted', $viewableData->XML_val('alwaysCasted'));
|
2012-02-09 19:57:27 +01:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
$this->assertEquals('overwritten', $newViewableData->XML_val('test'));
|
|
|
|
|
$this->assertEquals('casted', $newViewableData->XML_val('alwaysCasted'));
|
2012-02-09 19:57:27 +01:00
|
|
|
|
|
|
|
|
|
$this->assertEquals('castable', $viewableData->forTemplate());
|
|
|
|
|
$this->assertEquals('casted', $newViewableData->forTemplate());
|
2009-10-11 02:06:58 +02:00
|
|
|
|
}
|
2012-02-09 19:57:27 +01:00
|
|
|
|
|
2013-06-21 18:19:06 +02:00
|
|
|
|
public function testDefaultValueWrapping() {
|
|
|
|
|
$data = new ArrayData(array('Title' => 'SomeTitleValue'));
|
|
|
|
|
// this results in a cached raw string in ViewableData:
|
|
|
|
|
$this->assertTrue($data->hasValue('Title'));
|
|
|
|
|
$this->assertFalse($data->hasValue('SomethingElse'));
|
|
|
|
|
// this should cast the raw string to a StringField since we are
|
|
|
|
|
// passing true as the third argument:
|
|
|
|
|
$obj = $data->obj('Title', null, true);
|
|
|
|
|
$this->assertTrue(is_object($obj));
|
|
|
|
|
// and the string field should have the value of the raw string:
|
|
|
|
|
$this->assertEquals('SomeTitleValue', $obj->forTemplate());
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-15 01:56:11 +02:00
|
|
|
|
public function testCastingClass() {
|
|
|
|
|
$expected = array(
|
2016-06-03 10:51:02 +02:00
|
|
|
|
//'NonExistant' => null,
|
2010-10-15 01:56:11 +02:00
|
|
|
|
'Field' => 'CastingType',
|
|
|
|
|
'Argument' => 'ArgumentType',
|
|
|
|
|
'ArrayArgument' => 'ArrayArgumentType'
|
|
|
|
|
);
|
|
|
|
|
$obj = new ViewableDataTest_CastingClass();
|
|
|
|
|
|
|
|
|
|
foreach($expected as $field => $class) {
|
|
|
|
|
$this->assertEquals(
|
|
|
|
|
$class,
|
|
|
|
|
$obj->castingClass($field),
|
|
|
|
|
"castingClass() returns correct results for ::\$$field"
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-06-19 00:47:47 +02:00
|
|
|
|
|
|
|
|
|
public function testObjWithCachedStringValueReturnsValidObject() {
|
|
|
|
|
$obj = new ViewableDataTest_NoCastingInformation();
|
|
|
|
|
|
|
|
|
|
// Save a literal string into cache
|
|
|
|
|
$cache = true;
|
|
|
|
|
$uncastedData = $obj->obj('noCastingInformation', null, false, $cache);
|
|
|
|
|
|
|
|
|
|
// Fetch the cached string as an object
|
|
|
|
|
$forceReturnedObject = true;
|
|
|
|
|
$castedData = $obj->obj('noCastingInformation', null, $forceReturnedObject);
|
|
|
|
|
|
|
|
|
|
// Uncasted data should always be the nonempty string
|
|
|
|
|
$this->assertNotEmpty($uncastedData, 'Uncasted data was empty.');
|
2016-06-03 10:51:02 +02:00
|
|
|
|
//$this->assertTrue(is_string($uncastedData), 'Uncasted data should be a string.');
|
2013-06-19 00:47:47 +02:00
|
|
|
|
|
|
|
|
|
// Casted data should be the string wrapped in a DBField-object.
|
|
|
|
|
$this->assertNotEmpty($castedData, 'Casted data was empty.');
|
2016-06-15 06:03:16 +02:00
|
|
|
|
$this->assertInstanceOf('SilverStripe\\ORM\\FieldType\\DBField', $castedData, 'Casted data should be instance of DBField.');
|
2013-06-19 00:47:47 +02:00
|
|
|
|
|
|
|
|
|
$this->assertEquals($uncastedData, $castedData->getValue(), 'Casted and uncasted strings are not equal.');
|
|
|
|
|
}
|
2015-03-01 22:07:58 +01:00
|
|
|
|
|
|
|
|
|
public function testCaching() {
|
|
|
|
|
$objCached = new ViewableDataTest_Cached();
|
|
|
|
|
$objNotCached = new ViewableDataTest_NotCached();
|
|
|
|
|
|
|
|
|
|
$objCached->Test = 'AAA';
|
|
|
|
|
$objNotCached->Test = 'AAA';
|
|
|
|
|
|
|
|
|
|
$this->assertEquals('AAA', $objCached->obj('Test', null, true, true));
|
|
|
|
|
$this->assertEquals('AAA', $objNotCached->obj('Test', null, true, true));
|
|
|
|
|
|
|
|
|
|
$objCached->Test = 'BBB';
|
|
|
|
|
$objNotCached->Test = 'BBB';
|
|
|
|
|
|
|
|
|
|
// Cached data must be always the same
|
|
|
|
|
$this->assertEquals('AAA', $objCached->obj('Test', null, true, true));
|
|
|
|
|
$this->assertEquals('BBB', $objNotCached->obj('Test', null, true, true));
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-22 17:19:13 +01:00
|
|
|
|
public function testSetFailover() {
|
|
|
|
|
$failover = new ViewableData();
|
|
|
|
|
$container = new ViewableDataTest_Container();
|
|
|
|
|
$container->setFailover($failover);
|
|
|
|
|
|
|
|
|
|
$this->assertSame($failover, $container->getFailover(), 'getFailover() returned a different object');
|
|
|
|
|
$this->assertFalse($container->hasMethod('testMethod'), 'testMethod() is already defined when it shouldn’t be');
|
|
|
|
|
|
|
|
|
|
// Ensure that defined methods detected from the failover aren't cached when setting a new failover
|
|
|
|
|
$container->setFailover(new ViewableDataTest_Failover);
|
|
|
|
|
$this->assertTrue($container->hasMethod('testMethod'));
|
2016-06-03 18:04:22 +02:00
|
|
|
|
|
|
|
|
|
// Test the reverse - that defined methods previously detected in a failover are removed if they no longer exist
|
|
|
|
|
$container->setFailover($failover);
|
|
|
|
|
$this->assertSame($failover, $container->getFailover(), 'getFailover() returned a different object');
|
|
|
|
|
$this->assertFalse($container->hasMethod('testMethod'), 'testMethod() incorrectly reported as existing');
|
2015-12-22 17:19:13 +01:00
|
|
|
|
}
|
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**#@+
|
|
|
|
|
* @ignore
|
|
|
|
|
*/
|
|
|
|
|
class ViewableDataTest_Castable extends ViewableData {
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2013-03-21 19:48:54 +01:00
|
|
|
|
private static $default_cast = 'ViewableData_Caster';
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2013-03-21 19:48:54 +01:00
|
|
|
|
private static $casting = array (
|
2009-10-11 02:06:58 +02:00
|
|
|
|
'alwaysCasted' => 'ViewableDataTest_RequiresCasting',
|
2016-06-03 10:51:02 +02:00
|
|
|
|
'castedUnsafeXML' => 'ViewableData_UnescaptedCaster',
|
|
|
|
|
'test' => 'Text',
|
2009-10-11 02:06:58 +02:00
|
|
|
|
);
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
public $test = 'test';
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-15 23:48:24 +02:00
|
|
|
|
public $uncastedZeroValue = 0;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
public function alwaysCasted() {
|
|
|
|
|
return 'alwaysCasted';
|
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
public function noCastingInformation() {
|
|
|
|
|
return 'noCastingInformation';
|
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
public function unsafeXML() {
|
|
|
|
|
return '<foo>';
|
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
public function castedUnsafeXML() {
|
|
|
|
|
return $this->unsafeXML();
|
|
|
|
|
}
|
2012-02-09 19:57:27 +01:00
|
|
|
|
|
2012-12-08 12:20:20 +01:00
|
|
|
|
public function forTemplate() {
|
|
|
|
|
return 'castable';
|
|
|
|
|
}
|
2009-10-11 02:06:58 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ViewableDataTest_RequiresCasting extends ViewableData {
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
public $test = 'overwritten';
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
public function forTemplate() {
|
|
|
|
|
return 'casted';
|
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
public function setValue() {}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ViewableData_UnescaptedCaster extends ViewableData {
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
protected $value;
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
public function setValue($value) {
|
|
|
|
|
$this->value = $value;
|
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
public function forTemplate() {
|
|
|
|
|
return Convert::raw2xml($this->value);
|
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ViewableData_Caster extends ViewableData {
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
public function forTemplate() {
|
|
|
|
|
return 'casted';
|
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
public function setValue() {}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
|
2009-10-11 02:06:58 +02:00
|
|
|
|
}
|
|
|
|
|
|
2010-10-13 05:38:23 +02:00
|
|
|
|
class ViewableDataTest_Container extends ViewableData {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-15 01:56:11 +02:00
|
|
|
|
class ViewableDataTest_CastingClass extends ViewableData {
|
2013-03-21 19:48:54 +01:00
|
|
|
|
private static $casting = array(
|
2010-10-15 01:56:11 +02:00
|
|
|
|
'Field' => 'CastingType',
|
|
|
|
|
'Argument' => 'ArgumentType(Argument)',
|
|
|
|
|
'ArrayArgument' => 'ArrayArgumentType(array(foo, bar))'
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-19 00:47:47 +02:00
|
|
|
|
class ViewableDataTest_NoCastingInformation extends ViewableData {
|
|
|
|
|
public function noCastingInformation() {
|
|
|
|
|
return "No casting information";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-01 22:07:58 +01:00
|
|
|
|
class ViewableDataTest_Cached extends ViewableData {
|
|
|
|
|
public $Test;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ViewableDataTest_NotCached extends ViewableData {
|
|
|
|
|
public $Test;
|
|
|
|
|
|
|
|
|
|
protected function objCacheGet($key) {
|
|
|
|
|
// Disable caching
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-22 17:19:13 +01:00
|
|
|
|
class ViewableDataTest_Failover extends ViewableData {
|
|
|
|
|
public function testMethod() {}
|
|
|
|
|
}
|