Merge remote-tracking branch 'refs/remotes/scienceninjas/pull/gridfield-tests'

This commit is contained in:
Sam Minnee 2012-01-10 16:02:06 +13:00
commit 88f645ef59
2 changed files with 478 additions and 38 deletions

157
forms/gridfield/GridField.php Normal file → Executable file
View File

@ -64,6 +64,8 @@ class GridField extends FormField {
/**
* Internal dispatcher for column handlers.
* Keys are column names and values are GridField_ColumnProvider objects
*
* @var array
*/
protected $columnDispatch = null;
@ -90,8 +92,8 @@ class GridField extends FormField {
$this->config = $config;
}
$this->config->addComponent(new GridState_Component());
$this->setComponents($this->config);
$this->components[] = new GridState_Component();
$this->state = new GridState($this);
@ -101,9 +103,12 @@ class GridField extends FormField {
}
/**
* Set the modelClass that this field will get it column headers from
* Set the modelClass (dataobject) that this field will get it column headers from.
* If no $displayFields has been set, the displayfields will be fetched from
* this modelclass $summary_fields
*
* @param string $modelClassName
* @param string $modelClassName
* @see GridField::getDisplayFields()
*/
public function setModelClass($modelClassName) {
$this->modelClassName = $modelClassName;
@ -111,7 +116,7 @@ class GridField extends FormField {
}
/**
* Returns a dataclass that is a DataObject type that this field should look like.
* Returns a dataclass that is a DataObject type that this GridField should look like.
*
* @throws Exception
* @return string
@ -124,9 +129,10 @@ class GridField extends FormField {
}
/**
* Set which Components that this GridFields contain by using a GridFieldConfig
* Set which GridFieldComponent's that this GridFields contain by using a GridFieldConfig
*
* @param GridFieldConfig $config
* @param GridFieldConfig $config
* @see GridFieldComponent
*/
protected function setComponents(GridFieldConfig $config) {
$this->components = $config->getComponents();
@ -134,7 +140,7 @@ class GridField extends FormField {
}
/**
* Get a default configuration for this gridfield
* Get a default configuration for this GridField
*
* @return GridFieldConfig
*/
@ -155,7 +161,10 @@ class GridField extends FormField {
}
/**
* Get the DisplayFields
*
* @return array
* @see GridField::setDisplayFields
*/
public function getDisplayFields() {
if(!$this->displayFields) {
@ -165,6 +174,7 @@ class GridField extends FormField {
}
/**
* Get the GridFieldConfig
*
* @return GridFieldConfig
*/
@ -173,10 +183,13 @@ class GridField extends FormField {
}
/**
* Override the default behaviour of showing the models summaryFields with
* these fields instead
* Example: array( 'Name' => 'Members name', 'Email' => 'Email address')
*
* @param array $fields
*/
public function setDisplayFields(array $fields) {
public function setDisplayFields($fields) {
if(!is_array($fields)) {
throw new InvalidArgumentException('Arguments passed to GridField::setDisplayFields() must be an array');
}
@ -185,7 +198,11 @@ class GridField extends FormField {
}
/**
* Specify castings with fieldname as the key, and the desired casting as value.
* Example: array("MyCustomDate"=>"Date","MyShortText"=>"Text->FirstSentence")
*
* @param array $casting
* @todo refactor this into GridFieldComponent
*/
public function setFieldCasting($casting) {
$this->fieldCasting = $casting;
@ -193,7 +210,12 @@ class GridField extends FormField {
}
/**
* Specify custom formatting for fields, e.g. to render a link instead of pure text.
* Caution: Make sure to escape special php-characters like in a normal php-statement.
* Example: "myFieldName" => '<a href=\"custom-admin/$ID\">$ID</a>'
*
* @param array $casting
* @todo refactor this into GridFieldComponent
*/
public function getFieldCasting() {
return $this->fieldCasting;
@ -201,6 +223,7 @@ class GridField extends FormField {
/**
* @param array $casting
* @todo refactor this into GridFieldComponent
*/
public function setFieldFormatting($formatting) {
$this->fieldFormatting = $formatting;
@ -209,16 +232,18 @@ class GridField extends FormField {
/**
* @param array $casting
* @todo refactor this into GridFieldComponent
*/
public function getFieldFormatting() {
return $this->fieldFormatting;
}
/**
* Taken from TablelistField
*
* @param $value
* Cast a arbitrary value with the help of a castingDefintion
*
* @param $value
* @param $castingDefinition
* @todo refactor this into GridFieldComponent
*/
public function getCastedValue($value, $castingDefinition) {
if(is_array($castingDefinition)) {
@ -264,14 +289,12 @@ class GridField extends FormField {
}
/**
* Get the current GridState
* Get the current GridState_Data or the GridState
*
* @return GridState
* @param bool $getData - flag for returning the GridState_Data or the GridState
* @return GridState_data|GridState
*/
public function getState($getData=true) {
if(!$this->state) {
throw new LogicException('State has not been defined');
}
if($getData) {
return $this->state->getData();
}
@ -279,7 +302,7 @@ class GridField extends FormField {
}
/**
* Returns the whole gridfield rendered with all the attached Elements
* Returns the whole gridfield rendered with all the attached components
*
* @return string
*/
@ -346,7 +369,12 @@ class GridField extends FormField {
);
}
function getColumns() {
/**
* Get the columns of this GridField, they are provided by attached GridField_ColumnProvider
*
* @return array
*/
public function getColumns() {
// Get column list
$columns = array();
foreach($this->components as $item) {
@ -356,10 +384,20 @@ class GridField extends FormField {
}
return $columns;
}
/**
* Get the value from a column
*
* @param DataObject $record
* @param string $column
* @return string
* @throws InvalidArgumentException
*/
public function getColumnContent($record, $column) {
// Build the column dispatch
if(!$this->columnDispatch) $this->buildColumnDispatch();
if(!$this->columnDispatch) {
$this->buildColumnDispatch();
}
$handler = $this->columnDispatch[$column];
if($handler) {
@ -368,44 +406,79 @@ class GridField extends FormField {
throw new InvalidArgumentException("Bad column '$column'");
}
}
/**
* Get extra columns attributes used as HTML attributes
*
* @param DataObject $record
* @param string $column
* @return array
* @throws LogicException
* @throws InvalidArgumentException
*/
public function getColumnAttributes($record, $column) {
// Build the column dispatch
if(!$this->columnDispatch) $this->buildColumnDispatch();
if(!$this->columnDispatch) {
$this->buildColumnDispatch();
}
$handler = $this->columnDispatch[$column];
if($handler) {
$attrs = $handler->getColumnAttributes($this, $record, $column);
if(is_array($attrs)) return $attrs;
else if($attrs) throw new LogicException("Non-array response from " . get_class($handler) . "::getColumnAttributes()");
else return array();
if(is_array($attrs)) {
return $attrs;
} elseif($attrs) {
throw new LogicException("Non-array response from " . get_class($handler) . "::getColumnAttributes()");
} else {
return array();
}
} else {
throw new InvalidArgumentException("Bad column '$column'");
}
}
/**
* Get metadata for a column, example array('Title'=>'Email address')
*
* @param string $column
* @return array
* @throws LogicException
* @throws InvalidArgumentException
*/
public function getColumnMetadata($column) {
// Build the column dispatch
if(!$this->columnDispatch) $this->buildColumnDispatch();
if(!$this->columnDispatch) {
$this->buildColumnDispatch();
}
$handler = $this->columnDispatch[$column];
if($handler) {
$metadata = $handler->getColumnMetadata($this, $column);
if(is_array($metadata)) return $metadata;
else if($metadata) throw new LogicException("Non-array response from " . get_class($handler) . "::getColumnMetadata()");
else return array();
} else {
throw new InvalidArgumentException("Bad column '$column'");
$metadata = $handler->getColumnMetadata($this, $column);
if(is_array($metadata)) {
return $metadata;
} elseif($metadata) {
throw new LogicException("Non-array response from " . get_class($handler) . "::getColumnMetadata()");
}
}
throw new InvalidArgumentException("Bad column '$column'");
}
/**
* Return how many columns the grid will have
*
* @return int
*/
public function getColumnCount() {
// Build the column dispatch
if(!$this->columnDispatch) $this->buildColumnDispatch();
return count($this->columnDispatch);
}
/**
* Build an columnDispatch that maps a GridField_ColumnProvider to a column
* for reference later
*
*/
protected function buildColumnDispatch() {
$this->columnDispatch = array();
foreach($this->components as $item) {
@ -451,9 +524,17 @@ class GridField extends FormField {
return $form->forTemplate();
break;
}
}
/**
* Pass an action on the first GridField_ActionProvider that matches the $actionName
*
* @param string $actionName
* @param mixed $args
* @param arrray $data - send data from a form
* @return type
* @throws InvalidArgumentException
*/
public function handleAction($actionName, $args, $data) {
$actionName = strtolower($actionName);
foreach($this->components as $item) {

View File

@ -0,0 +1,359 @@
<?php
class GridFieldtest extends SapphireTest {
/**
* @covers GridField::__construct
* @covers GridFIeld::requireDefaultCSS
*/
public function testGridField() {
$obj = new GridField('testfield', 'testfield');
$this->assertTrue($obj instanceof GridField, 'Test that the constructor arguments are valid');
$css = Requirements::backend()->get_css();
$this->assertTrue(isset($css['sapphire/css/GridField.css']), 'GridField.css should have been aquired');
}
/**
* @covers GridField::__construct
* @covers GridField::getList
*/
public function testGridFieldSetList() {
$list = ArrayList::create(array(1=>'hello', 2=>'goodbye'));
$obj = new GridField('testfield', 'testfield', $list);
$this->assertEquals($list, $obj->getList(), 'Testing getList');
}
/**
* @covers GridField::__construct
* @covers GridField::getConfig
* @covers GridField::setComponents
* @covers GridField::getDefaultConfig
*/
public function testGridFieldDefaultConfig() {
$obj = new GridField('testfield', 'testfield');
$expectedComponents = new ArrayList(array(
0 => new GridFieldSortableHeader,
1 => new GridFieldFilter,
2 => new GridFieldDefaultColumns,
3 => new GridFieldPaginator,
4 => new GridState_Component,
));
$this->assertEquals($expectedComponents, $obj->getConfig()->getComponents(), 'Testing default Config');
}
/**
* @covers GridField::__construct
* @covers GridField::setComponents
*/
public function testGridFieldSetCustomConfig() {
$config = GridFieldConfig::create();
$config->addComponent(new GridFieldSortableHeader());
$config->addComponent(new GridFieldDefaultColumns());
$obj = new GridField('testfield', 'testfield', ArrayList::create(array()),$config);
$expectedComponents = new ArrayList(array(
0 => new GridFieldSortableHeader,
1 => new GridFieldDefaultColumns,
2 => new GridState_Component,
));
$this->assertEquals($expectedComponents, $obj->getConfig()->getComponents(), 'Testing default Config');
}
/**
* @covers GridField::getModelClass
* @covers GridField::setModelClass
*/
public function testGridFieldModelClass() {
$obj = new GridField('testfield', 'testfield', DataList::create('Member'));
$this->assertEquals('Member', $obj->getModelClass(), 'Should return Member');
$obj->setModelClass('DataModel');
$this->assertEquals('DataModel', $obj->getModelClass(), 'Should return Member');
}
/**
* @covers GridField::getModelClass
*/
public function testGridFieldModelClassThrowsException() {
$this->setExpectedException('LogicException');
$obj = new GridField('testfield', 'testfield', ArrayList::create());
$obj->getModelClass();
}
/**
* @covers GridField::getDisplayFields
*/
public function testGridFieldGetDefaultDisplayFields() {
$obj = new GridField('testfield', 'testfield', DataList::create('Member'));
$expected = array(
'FirstName' => 'First Name',
'Surname' => 'Last Name',
'Email' => 'Email',
);
$this->assertEquals($expected, $obj->getDisplayFields());
}
/**
* @covers GridField::setDisplayFields
* @covers GridField::getDisplayFields
*/
public function testGridFieldCustomDisplayFields() {
$obj = new GridField('testfield', 'testfield', DataList::create('Member'));
$expected = array('Email' => 'Email');
$obj->setDisplayFields($expected);
$this->assertEquals($expected, $obj->getDisplayFields());
}
/**
* @covers GridField::setDisplayFields
* @covers GridField::getDisplayFields
*/
public function testGridFieldDisplayFieldsWithBadArguments() {
$this->setExpectedException('InvalidArgumentException');
$obj = new GridField('testfield', 'testfield', DataList::create('Member'));
$obj->setDisplayFields(new stdClass());
}
/**
* @covers GridField::setList
* @covers GridField::getList
*/
public function testSetAndGetList() {
$list = DataList::create('Member');
$arrayList = ArrayList::create(array(1,2,3));
$obj = new GridField('testfield', 'testfield', $list);
$this->assertEquals($list, $obj->getList());
$obj->setList($arrayList);
$this->assertEquals($arrayList, $obj->getList());
}
/**
* @covers GridField::getState
*/
public function testGetState() {
$obj = new GridField('testfield', 'testfield');
$this->assertTrue($obj->getState() instanceof GridState_Data);
$this->assertTrue($obj->getState(false) instanceof GridState);
}
/**
* @covers GridField::getColumns
*/
public function testGetColumns(){
$obj = new GridField('testfield', 'testfield', DataList::create('Member'));
$expected = array (
0 => 'FirstName',
1 => 'Surname',
2 => 'Email',
);
$this->assertEquals($expected, $obj->getColumns());
}
/**
* @covers GridField::getColumnCount
*/
public function testGetColumnCount() {
$obj = new GridField('testfield', 'testfield', DataList::create('Member'));
$this->assertEquals(3, $obj->getColumnCount());
}
/**
* @covers GridField::getColumnContent
*/
public function testGetColumnContent() {
$list = DataList::create('Member');
$obj = new GridField('testfield', 'testfield', $list);
$this->assertEquals('ADMIN@example.org', $obj->getColumnContent($list->first(), 'Email'));
}
/**
* @covers GridField::getColumnContent
*/
public function testGetColumnContentBadArguments() {
$this->setExpectedException('InvalidArgumentException');
$list = DataList::create('Member');
$obj = new GridField('testfield', 'testfield', $list);
$obj->getColumnContent($list->first(), 'non-existing');
}
/**
* @covers GridField::getColumnAttributes
*/
public function testGetColumnAttributesEmptyArray() {
$list = DataList::create('Member');
$obj = new GridField('testfield', 'testfield', $list);
$this->assertEquals(array(), $obj->getColumnAttributes($list->first(), 'Email'));
}
/**
* @covers GridField::getColumnAttributes
*/
public function testGetColumnAttributes() {
$list = DataList::create('Member');
$config = GridFieldConfig::create()->addComponent(new GridFieldTest_Component);
$obj = new GridField('testfield', 'testfield', $list, $config);
$this->assertEquals(array('class'=>'css-class'), $obj->getColumnAttributes($list->first(), 'Email'));
}
/**
* @covers GridField::getColumnAttributes
*/
public function testGetColumnAttributesBadArguments() {
$this->setExpectedException('InvalidArgumentException');
$list = DataList::create('Member');
$config = GridFieldConfig::create()->addComponent(new GridFieldTest_Component);
$obj = new GridField('testfield', 'testfield', $list, $config);
$obj->getColumnAttributes($list->first(), 'Non-existing');
}
public function testGetColumnAttributesBadResponseFromComponent() {
$this->setExpectedException('LogicException');
$list = DataList::create('Member');
$config = GridFieldConfig::create()->addComponent(new GridFieldTest_Component);
$obj = new GridField('testfield', 'testfield', $list, $config);
$obj->getColumnAttributes($list->first(), 'Surname');
}
/**
* @covers GridField::getColumnMetadata
*/
public function testGetColumnMetadata() {
$list = DataList::create('Member');
$config = GridFieldConfig::create()->addComponent(new GridFieldTest_Component);
$obj = new GridField('testfield', 'testfield', $list, $config);
$this->assertEquals(array('metadata'=>'istrue'), $obj->getColumnMetadata('Email'));
}
/**
* @covers GridField::getColumnMetadata
*/
public function testGetColumnMetadataBadResponseFromComponent() {
$this->setExpectedException('LogicException');
$list = DataList::create('Member');
$config = GridFieldConfig::create()->addComponent(new GridFieldTest_Component);
$obj = new GridField('testfield', 'testfield', $list, $config);
$obj->getColumnMetadata('Surname');
}
/**
* @covers GridField::getColumnMetadata
*/
public function testGetColumnMetadataBadArguments() {
$this->setExpectedException('InvalidArgumentException');
$list = ArrayList::create();
$config = GridFieldConfig::create()->addComponent(new GridFieldTest_Component);
$obj = new GridField('testfield', 'testfield', $list, $config);
$obj->getColumnMetadata('non-exist-qweqweqwe');
}
/**
* @covers GridField::handleAction
*/
public function testHandleActionBadArgument() {
$this->setExpectedException('InvalidArgumentException');
$obj = new GridField('testfield', 'testfield');
$obj->handleAction('prft', array(), array());
}
/**
* @covers GridField::handleAction
*/
public function testHandleAction() {
$config = GridFieldConfig::create()->addComponent(new GridFieldTest_Component);
$obj = new GridField('testfield', 'testfield', ArrayList::create(), $config);
$this->assertEquals('handledAction is executed', $obj->handleAction('jump', array(), array()));
}
/**
* @covers GridField::getFieldCasting
* @covers GridField::setFieldCasting
*/
public function testFieldCasting() {
$obj = new GridField('testfield', 'testfield');
$this->assertEquals(array(), $obj->getFieldCasting());
$obj->setFieldCasting(array("MyShortText"=>"Text->FirstSentence"));
$this->assertEquals(array("MyShortText"=>"Text->FirstSentence"), $obj->getFieldCasting());
}
/**
* @covers GridField::getFieldFormatting
* @covers GridField::setFieldFormatting
*/
public function testFieldFormatting() {
$obj = new GridField('testfield', 'testfield');
$this->assertEquals(array(), $obj->getFieldFormatting());
$obj->setFieldFormatting(array("myFieldName" => '<a href=\"custom-admin/$ID\">$ID</a>'));
$this->assertEquals(array("myFieldName" => '<a href=\"custom-admin/$ID\">$ID</a>'), $obj->getFieldFormatting());
}
/**
* @covers GridField::getCastedValue
*/
public function testGetCastedValue() {
$obj = new GridField('testfield', 'testfield');
$value = $obj->getCastedValue('This is a sentance. This ia another.', array('Text->FirstSentence'));
$this->assertEquals('This is a sentance.', $value);
}
/**
* @covers GridField::getCastedValue
*/
public function testGetCastedValueObject() {
$obj = new GridField('testfield', 'testfield');
$value = $obj->getCastedValue('This is a sentance. This ia another.', 'Date');
$this->assertEquals('1970-01-01', $value);
}
/**
* @covers GridField::gridFieldAlterAction
*/
public function testGridFieldAlterAction() {
$config = GridFieldConfig::create()->addComponent(new GridFieldTest_Component);
$obj = new GridField('testfield', 'testfield', ArrayList::create(), $config);
$id = 'testGridStateActionField';
Session::set($id, array('grid'=>'', 'actionName'=>'jump'));
$form = new Form($this, 'mockform', new FieldList(array($obj)), new FieldList());
$request = new SS_HTTPRequest('POST', 'url');
$obj->gridFieldAlterAction(array('StateID'=>$id), $form, $request);
}
}
class GridFieldTest_Component implements GridField_ColumnProvider, GridField_ActionProvider, TestOnly{
public function augmentColumns($gridField, &$columns) {}
public function getColumnContent($gridField, $record, $columnName) {}
public function getColumnAttributes($gridField, $record, $columnName) {
if($columnName=='Surname'){
return 'shouldnotbestring';
}
return array('class'=>'css-class');
}
public function getColumnMetadata($gridField, $columnName) {
if($columnName=='Surname'){
return 'shouldnotbestring';
} elseif( $columnName == 'FirstName') {
return array();
}
return array('metadata'=>'istrue');
}
public function getColumnsHandled($gridField) {
return array('Email', 'Surname', 'FirstName');
}
public function getActions($gridField) {
return array('jump');
}
public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
return 'handledAction is executed';
}
}