mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
MNT Add tests for using GridField with arbitrary data
Note that the main tests are added as behat tests in the admin module
This commit is contained in:
parent
2cafba2bd5
commit
7073246a37
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace SilverStripe\Forms\Tests\GridField;
|
namespace SilverStripe\Forms\Tests\GridField;
|
||||||
|
|
||||||
|
use LogicException;
|
||||||
use SilverStripe\Control\HTTPRequest;
|
use SilverStripe\Control\HTTPRequest;
|
||||||
use SilverStripe\Core\Convert;
|
use SilverStripe\Core\Convert;
|
||||||
use SilverStripe\Dev\CSSContentParser;
|
use SilverStripe\Dev\CSSContentParser;
|
||||||
@ -17,6 +18,7 @@ use SilverStripe\Forms\Tests\GridField\GridFieldTest\Player;
|
|||||||
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Stadium;
|
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Stadium;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Team;
|
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Team;
|
||||||
use SilverStripe\ORM\ArrayList;
|
use SilverStripe\ORM\ArrayList;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
class GridFieldAddExistingAutocompleterTest extends FunctionalTest
|
class GridFieldAddExistingAutocompleterTest extends FunctionalTest
|
||||||
{
|
{
|
||||||
@ -167,6 +169,118 @@ class GridFieldAddExistingAutocompleterTest extends FunctionalTest
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetHTMLFragmentsNeedsDataObject()
|
||||||
|
{
|
||||||
|
$component = new GridFieldAddExistingAutocompleter();
|
||||||
|
$gridField = $this->getGridFieldForComponent($component);
|
||||||
|
$list = new ArrayList();
|
||||||
|
$dataClass = ArrayData::class;
|
||||||
|
$list->setDataClass($dataClass);
|
||||||
|
$gridField->setList($list);
|
||||||
|
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$this->expectExceptionMessage(
|
||||||
|
GridFieldAddExistingAutocompleter::class
|
||||||
|
. " must be used with DataObject subclasses. Found '$dataClass'"
|
||||||
|
);
|
||||||
|
// Calling the method will throw an exception.
|
||||||
|
$component->getHTMLFragments($gridField);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetManipulatedDataNeedsDataObject()
|
||||||
|
{
|
||||||
|
$component = new GridFieldAddExistingAutocompleter();
|
||||||
|
$gridField = $this->getGridFieldForComponent($component);
|
||||||
|
$list = new ArrayList();
|
||||||
|
$dataClass = ArrayData::class;
|
||||||
|
$list->setDataClass($dataClass);
|
||||||
|
$gridField->setList($list);
|
||||||
|
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$this->expectExceptionMessage(
|
||||||
|
GridFieldAddExistingAutocompleter::class
|
||||||
|
. " must be used with DataObject subclasses. Found '$dataClass'"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Calling the method will throw an exception.
|
||||||
|
$component->getManipulatedData($gridField, $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDoSearchNeedsDataObject()
|
||||||
|
{
|
||||||
|
$component = new GridFieldAddExistingAutocompleter();
|
||||||
|
$gridField = $this->getGridFieldForComponent($component);
|
||||||
|
$list = new ArrayList();
|
||||||
|
$dataClass = ArrayData::class;
|
||||||
|
$list->setDataClass($dataClass);
|
||||||
|
$gridField->setList($list);
|
||||||
|
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$this->expectExceptionMessage(
|
||||||
|
GridFieldAddExistingAutocompleter::class
|
||||||
|
. " must be used with DataObject subclasses. Found '$dataClass'"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Calling the method will throw an exception.
|
||||||
|
$component->doSearch($gridField, new HTTPRequest('GET', ''));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testScaffoldSearchFieldsNeedsDataObject()
|
||||||
|
{
|
||||||
|
$component = new GridFieldAddExistingAutocompleter();
|
||||||
|
$gridField = $this->getGridFieldForComponent($component);
|
||||||
|
$list = new ArrayList();
|
||||||
|
$dataClass = ArrayData::class;
|
||||||
|
$list->setDataClass($dataClass);
|
||||||
|
$gridField->setList($list);
|
||||||
|
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$this->expectExceptionMessage(
|
||||||
|
GridFieldAddExistingAutocompleter::class
|
||||||
|
. " must be used with DataObject subclasses. Found '$dataClass'"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Calling the method will either throw an exception or not.
|
||||||
|
// The test pass/failure is explicitly about whether an exception is thrown.
|
||||||
|
$component->scaffoldSearchFields($dataClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetPlaceholderTextNeedsDataObject()
|
||||||
|
{
|
||||||
|
$component = new GridFieldAddExistingAutocompleter();
|
||||||
|
$gridField = $this->getGridFieldForComponent($component);
|
||||||
|
$list = new ArrayList();
|
||||||
|
$dataClass = ArrayData::class;
|
||||||
|
$list->setDataClass($dataClass);
|
||||||
|
$gridField->setList($list);
|
||||||
|
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$this->expectExceptionMessage(
|
||||||
|
GridFieldAddExistingAutocompleter::class
|
||||||
|
. " must be used with DataObject subclasses. Found '$dataClass'"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Calling the method will either throw an exception or not.
|
||||||
|
// The test pass/failure is explicitly about whether an exception is thrown.
|
||||||
|
$component->getPlaceholderText($dataClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSetPlaceholderTextDoesntNeedDataObject()
|
||||||
|
{
|
||||||
|
$component = new GridFieldAddExistingAutocompleter();
|
||||||
|
$gridField = $this->getGridFieldForComponent($component);
|
||||||
|
$list = new ArrayList();
|
||||||
|
$dataClass = ArrayData::class;
|
||||||
|
$list->setDataClass($dataClass);
|
||||||
|
$gridField->setList($list);
|
||||||
|
|
||||||
|
// Prevent from being marked risky.
|
||||||
|
// This test passes if there's no exception thrown.
|
||||||
|
$this->expectNotToPerformAssertions();
|
||||||
|
|
||||||
|
$component->setPlaceholderText('');
|
||||||
|
}
|
||||||
|
|
||||||
protected function getGridFieldForComponent($component)
|
protected function getGridFieldForComponent($component)
|
||||||
{
|
{
|
||||||
$config = GridFieldConfig::create()->addComponents(
|
$config = GridFieldConfig::create()->addComponents(
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace SilverStripe\Forms\Tests\GridField;
|
namespace SilverStripe\Forms\Tests\GridField;
|
||||||
|
|
||||||
|
use LogicException;
|
||||||
use SilverStripe\Core\Injector\Injector;
|
use SilverStripe\Core\Injector\Injector;
|
||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
@ -9,11 +10,14 @@ use SilverStripe\Forms\Form;
|
|||||||
use SilverStripe\Forms\GridField\GridField;
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
use SilverStripe\Forms\GridField\GridFieldAddNewButton;
|
use SilverStripe\Forms\GridField\GridFieldAddNewButton;
|
||||||
use SilverStripe\Forms\GridField\GridFieldConfig;
|
use SilverStripe\Forms\GridField\GridFieldConfig;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldConfig_Base;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\Person;
|
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\Person;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\PeopleGroup;
|
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\PeopleGroup;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\Category;
|
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\Category;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\TestController;
|
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\TestController;
|
||||||
|
use SilverStripe\ORM\ArrayList;
|
||||||
use SilverStripe\ORM\SS_List;
|
use SilverStripe\ORM\SS_List;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
class GridFieldAddNewButtonTest extends SapphireTest
|
class GridFieldAddNewButtonTest extends SapphireTest
|
||||||
{
|
{
|
||||||
@ -76,6 +80,24 @@ class GridFieldAddNewButtonTest extends SapphireTest
|
|||||||
$this->mockButtonFragments($list, null);
|
$this->mockButtonFragments($list, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetHTMLFragmentsThrowsException()
|
||||||
|
{
|
||||||
|
$component = new GridFieldAddNewButton();
|
||||||
|
$config = new GridFieldConfig_Base();
|
||||||
|
$config->addComponent($component);
|
||||||
|
$gridField = new GridField('dummy', 'dummy', new ArrayList(), $config);
|
||||||
|
$modelClass = ArrayData::class;
|
||||||
|
$gridField->setModelClass($modelClass);
|
||||||
|
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$this->expectExceptionMessage(
|
||||||
|
GridFieldAddNewButton::class . ' cannot be used with models that do not implement canCreate().'
|
||||||
|
. " Remove this component from your GridField or implement canCreate() on $modelClass"
|
||||||
|
);
|
||||||
|
|
||||||
|
$component->getHTMLFragments($gridField);
|
||||||
|
}
|
||||||
|
|
||||||
protected function mockButtonFragments(SS_List $list, $parent = null)
|
protected function mockButtonFragments(SS_List $list, $parent = null)
|
||||||
{
|
{
|
||||||
$form = Form::create(
|
$form = Form::create(
|
||||||
|
@ -3,15 +3,18 @@
|
|||||||
namespace SilverStripe\Forms\Tests\GridField;
|
namespace SilverStripe\Forms\Tests\GridField;
|
||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
|
use LogicException;
|
||||||
use SilverStripe\Forms\GridField\GridFieldDataColumns;
|
use SilverStripe\Forms\GridField\GridFieldDataColumns;
|
||||||
use SilverStripe\Security\Member;
|
use SilverStripe\Security\Member;
|
||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
use SilverStripe\Forms\GridField\GridField;
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldConfig_Base;
|
||||||
|
use SilverStripe\ORM\ArrayList;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
use stdClass;
|
use stdClass;
|
||||||
|
|
||||||
class GridFieldDataColumnsTest extends SapphireTest
|
class GridFieldDataColumnsTest extends SapphireTest
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::getDisplayFields
|
* @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::getDisplayFields
|
||||||
*/
|
*/
|
||||||
@ -23,6 +26,19 @@ class GridFieldDataColumnsTest extends SapphireTest
|
|||||||
$this->assertEquals($expected, $columns->getDisplayFields($obj));
|
$this->assertEquals($expected, $columns->getDisplayFields($obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::getDisplayFields
|
||||||
|
*/
|
||||||
|
public function testGridFieldGetDisplayFieldsWithArrayList()
|
||||||
|
{
|
||||||
|
$list = new ArrayList([new ArrayData(['Title' => 'My Item'])]);
|
||||||
|
$obj = new GridField('testfield', 'testfield', $list);
|
||||||
|
$expected = ['Title' => 'Title'];
|
||||||
|
$columns = $obj->getConfig()->getComponentByType(GridFieldDataColumns::class);
|
||||||
|
$columns->setDisplayFields($expected);
|
||||||
|
$this->assertEquals($expected, $columns->getDisplayFields($obj));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::setDisplayFields
|
* @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::setDisplayFields
|
||||||
* @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::getDisplayFields
|
* @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::getDisplayFields
|
||||||
@ -76,4 +92,22 @@ class GridFieldDataColumnsTest extends SapphireTest
|
|||||||
$columns->getFieldFormatting()
|
$columns->getFieldFormatting()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetDisplayFieldsThrowsException()
|
||||||
|
{
|
||||||
|
$component = new GridFieldDataColumns();
|
||||||
|
$config = new GridFieldConfig_Base();
|
||||||
|
$config->addComponent($component);
|
||||||
|
$gridField = new GridField('dummy', 'dummy', new ArrayList(), $config);
|
||||||
|
$modelClass = ArrayData::class;
|
||||||
|
$gridField->setModelClass($modelClass);
|
||||||
|
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$this->expectExceptionMessage(
|
||||||
|
'Cannot dynamically determine columns. Pass the column names to setDisplayFields()'
|
||||||
|
. " or implement a summaryFields() method on $modelClass"
|
||||||
|
);
|
||||||
|
|
||||||
|
$component->getDisplayFields($gridField);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace SilverStripe\Forms\Tests\GridField;
|
namespace SilverStripe\Forms\Tests\GridField;
|
||||||
|
|
||||||
|
use LogicException;
|
||||||
|
use ReflectionMethod;
|
||||||
use SilverStripe\Control\Controller;
|
use SilverStripe\Control\Controller;
|
||||||
use SilverStripe\Control\HTTPRequest;
|
use SilverStripe\Control\HTTPRequest;
|
||||||
use SilverStripe\Control\HTTPResponse_Exception;
|
use SilverStripe\Control\HTTPResponse_Exception;
|
||||||
@ -12,6 +14,7 @@ use SilverStripe\Forms\FieldList;
|
|||||||
use SilverStripe\Forms\Form;
|
use SilverStripe\Forms\Form;
|
||||||
use SilverStripe\Forms\GridField\GridField;
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
use SilverStripe\Forms\GridField\GridFieldConfig;
|
use SilverStripe\Forms\GridField\GridFieldConfig;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldConfig_Base;
|
||||||
use SilverStripe\Forms\GridField\GridFieldDeleteAction;
|
use SilverStripe\Forms\GridField\GridFieldDeleteAction;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Cheerleader;
|
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Cheerleader;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Permissions;
|
use SilverStripe\Forms\Tests\GridField\GridFieldTest\Permissions;
|
||||||
@ -22,6 +25,7 @@ use SilverStripe\ORM\DataList;
|
|||||||
use SilverStripe\ORM\ValidationException;
|
use SilverStripe\ORM\ValidationException;
|
||||||
use SilverStripe\Security\Security;
|
use SilverStripe\Security\Security;
|
||||||
use SilverStripe\Security\SecurityToken;
|
use SilverStripe\Security\SecurityToken;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
class GridFieldDeleteActionTest extends SapphireTest
|
class GridFieldDeleteActionTest extends SapphireTest
|
||||||
{
|
{
|
||||||
@ -230,4 +234,70 @@ class GridFieldDeleteActionTest extends SapphireTest
|
|||||||
$group = $action->getGroup($gridField, $this->list->first(), 'dummy');
|
$group = $action->getGroup($gridField, $this->list->first(), 'dummy');
|
||||||
$this->assertNull($group, 'A menu group does not exist when the user cannot delete');
|
$this->assertNull($group, 'A menu group does not exist when the user cannot delete');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function provideHandleActionThrowsException()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'unlinks relation' => [true],
|
||||||
|
'deletes related record' => [false],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideHandleActionThrowsException
|
||||||
|
*/
|
||||||
|
public function testHandleActionThrowsException(bool $unlinkRelation)
|
||||||
|
{
|
||||||
|
$component = new GridFieldDeleteAction();
|
||||||
|
$config = new GridFieldConfig_Base();
|
||||||
|
$config->addComponent($component);
|
||||||
|
$gridField = new GridField('dummy', 'dummy', new ArrayList([new ArrayData(['ID' => 1])]), $config);
|
||||||
|
$modelClass = ArrayData::class;
|
||||||
|
$gridField->setModelClass($modelClass);
|
||||||
|
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$permissionMethod = $unlinkRelation ? 'canEdit' : 'canDelete';
|
||||||
|
$this->expectExceptionMessage(
|
||||||
|
GridFieldDeleteAction::class . " cannot be used with models that don't implement {$permissionMethod}()."
|
||||||
|
. " Remove this component from your GridField or implement {$permissionMethod}() on $modelClass"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Calling the method will throw an exception.
|
||||||
|
$secondArg = $unlinkRelation ? 'unlinkrelation' : 'deleterecord';
|
||||||
|
$component->handleAction($gridField, $secondArg, ['RecordID' => 1], []);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideGetRemoveActionThrowsException()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'removes relation' => [true],
|
||||||
|
'deletes related record' => [false],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideGetRemoveActionThrowsException
|
||||||
|
*/
|
||||||
|
public function testGetRemoveActionThrowsException(bool $removeRelation)
|
||||||
|
{
|
||||||
|
$component = new GridFieldDeleteAction();
|
||||||
|
$component->setRemoveRelation($removeRelation);
|
||||||
|
$config = new GridFieldConfig_Base();
|
||||||
|
$config->addComponent($component);
|
||||||
|
$gridField = new GridField('dummy', 'dummy', new ArrayList([new ArrayData(['ID' => 1])]), $config);
|
||||||
|
$modelClass = ArrayData::class;
|
||||||
|
$gridField->setModelClass($modelClass);
|
||||||
|
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$permissionMethod = $removeRelation ? 'canEdit' : 'canDelete';
|
||||||
|
$this->expectExceptionMessage(
|
||||||
|
GridFieldDeleteAction::class . " cannot be used with models that don't implement {$permissionMethod}()."
|
||||||
|
. " Remove this component from your GridField or implement {$permissionMethod}() on $modelClass"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Calling the method will throw an exception.
|
||||||
|
$reflectionMethod = new ReflectionMethod($component, 'getRemoveAction');
|
||||||
|
$reflectionMethod->setAccessible(true);
|
||||||
|
$reflectionMethod->invokeArgs($component, [$gridField, new ArrayData(), '']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,20 @@
|
|||||||
|
|
||||||
namespace SilverStripe\Forms\Tests\GridField;
|
namespace SilverStripe\Forms\Tests\GridField;
|
||||||
|
|
||||||
|
use LogicException;
|
||||||
|
use ReflectionMethod;
|
||||||
use SilverStripe\Control\Controller;
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Control\HTTPRequest;
|
||||||
use SilverStripe\Dev\CSSContentParser;
|
use SilverStripe\Dev\CSSContentParser;
|
||||||
use SilverStripe\Dev\FunctionalTest;
|
use SilverStripe\Dev\FunctionalTest;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
use SilverStripe\Forms\Form;
|
use SilverStripe\Forms\Form;
|
||||||
use SilverStripe\Forms\GridField\GridField;
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
|
||||||
use SilverStripe\Forms\GridField\GridFieldDetailForm;
|
use SilverStripe\Forms\GridField\GridFieldDetailForm;
|
||||||
use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest;
|
use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest;
|
||||||
use SilverStripe\Forms\HiddenField;
|
use SilverStripe\Forms\HiddenField;
|
||||||
|
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\ArrayDataWithID;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\Category;
|
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\Category;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\CategoryController;
|
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\CategoryController;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\GroupController;
|
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\GroupController;
|
||||||
@ -17,6 +23,8 @@ use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\PeopleGroup;
|
|||||||
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\Person;
|
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\Person;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\PolymorphicPeopleGroup;
|
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\PolymorphicPeopleGroup;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\TestController;
|
use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\TestController;
|
||||||
|
use SilverStripe\ORM\ArrayList;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
class GridFieldDetailFormTest extends FunctionalTest
|
class GridFieldDetailFormTest extends FunctionalTest
|
||||||
{
|
{
|
||||||
@ -460,4 +468,121 @@ class GridFieldDetailFormTest extends FunctionalTest
|
|||||||
|
|
||||||
$this->autoFollowRedirection = $origAutoFollow;
|
$this->autoFollowRedirection = $origAutoFollow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function provideGetRecordFromRequestFindExisting()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'No records' => [
|
||||||
|
'data' => [],
|
||||||
|
'hasRecord' => false,
|
||||||
|
],
|
||||||
|
'Records exist but without ID field' => [
|
||||||
|
'data' => [new ArrayDataWithID()],
|
||||||
|
'hasRecord' => false,
|
||||||
|
],
|
||||||
|
'Record exists with matching ID' => [
|
||||||
|
'data' => [new ArrayDataWithID(['ID' => 32])],
|
||||||
|
'hasRecord' => true,
|
||||||
|
],
|
||||||
|
'Record exists, no matching ID' => [
|
||||||
|
'data' => [new ArrayDataWithID(['ID' => 1])],
|
||||||
|
'hasRecord' => false,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideGetRecordFromRequestFindExisting
|
||||||
|
*/
|
||||||
|
public function testGetRecordFromRequestFindExisting(array $data, bool $hasRecord)
|
||||||
|
{
|
||||||
|
$controller = new TestController();
|
||||||
|
$form = $controller->Form(null, new ArrayList($data));
|
||||||
|
$gridField = $form->Fields()->dataFieldByName('testfield');
|
||||||
|
if (empty($data)) {
|
||||||
|
$gridField->setModelClass(ArrayDataWithID::class);
|
||||||
|
}
|
||||||
|
$component = $gridField->getConfig()->getComponentByType(GridFieldDetailForm::class);
|
||||||
|
$request = new HTTPRequest('GET', $gridField->Link('item/32'));
|
||||||
|
$request->match(Controller::join_links($gridField->Link(), 'item/$ID'));
|
||||||
|
|
||||||
|
$reflectionMethod = new ReflectionMethod($component, 'getRecordFromRequest');
|
||||||
|
$reflectionMethod->setAccessible(true);
|
||||||
|
$this->assertSame($hasRecord, (bool) $reflectionMethod->invoke($component, $gridField, $request));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideGetRecordFromRequestCreateNew()
|
||||||
|
{
|
||||||
|
// Note that in all of these scenarios a new record gets created, so it *shouldn't* matter what's already in there.
|
||||||
|
return [
|
||||||
|
'No records' => [
|
||||||
|
'data' => [],
|
||||||
|
],
|
||||||
|
'Records exist but without ID field' => [
|
||||||
|
'data' => [new ArrayDataWithID()],
|
||||||
|
],
|
||||||
|
'Record exists with ID field' => [
|
||||||
|
'data' => [new ArrayDataWithID(['ID' => 32])],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideGetRecordFromRequestCreateNew
|
||||||
|
*/
|
||||||
|
public function testGetRecordFromRequestCreateNew(array $data)
|
||||||
|
{
|
||||||
|
$controller = new TestController();
|
||||||
|
$form = $controller->Form(null, new ArrayList($data));
|
||||||
|
$gridField = $form->Fields()->dataFieldByName('testfield');
|
||||||
|
if (empty($data)) {
|
||||||
|
$gridField->setModelClass(ArrayDataWithID::class);
|
||||||
|
}
|
||||||
|
$component = $gridField->getConfig()->getComponentByType(GridFieldDetailForm::class);
|
||||||
|
$request = new HTTPRequest('GET', $gridField->Link('item/new'));
|
||||||
|
$request->match(Controller::join_links($gridField->Link(), 'item/$ID'));
|
||||||
|
|
||||||
|
$reflectionMethod = new ReflectionMethod($component, 'getRecordFromRequest');
|
||||||
|
$reflectionMethod->setAccessible(true);
|
||||||
|
$this->assertEquals(new ArrayDataWithID(['ID' => 0]), $reflectionMethod->invoke($component, $gridField, $request));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideGetRecordFromRequestWithoutData()
|
||||||
|
{
|
||||||
|
// Note that in all of these scenarios a new record gets created, so it *shouldn't* matter what's already in there.
|
||||||
|
return [
|
||||||
|
'No records' => [
|
||||||
|
'data' => [],
|
||||||
|
],
|
||||||
|
'Records exist but without ID field' => [
|
||||||
|
'data' => [new ArrayData()],
|
||||||
|
],
|
||||||
|
'Record exists with ID field' => [
|
||||||
|
'data' => [new ArrayData(['ID' => 32])],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideGetRecordFromRequestWithoutData
|
||||||
|
*/
|
||||||
|
public function testGetRecordFromRequestWithoutData(array $data)
|
||||||
|
{
|
||||||
|
$controller = new TestController();
|
||||||
|
$form = $controller->Form(null, new ArrayList($data));
|
||||||
|
$gridField = $form->Fields()->dataFieldByName('testfield');
|
||||||
|
if (empty($data)) {
|
||||||
|
$gridField->setModelClass(ArrayData::class);
|
||||||
|
}
|
||||||
|
$component = $gridField->getConfig()->getComponentByType(GridFieldDetailForm::class);
|
||||||
|
$request = new HTTPRequest('GET', $gridField->Link('item/new'));
|
||||||
|
$request->match(Controller::join_links($gridField->Link(), 'item/$ID'));
|
||||||
|
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$this->expectExceptionMessage(ArrayData::class . ' must have an ID field.');
|
||||||
|
|
||||||
|
$reflectionMethod = new ReflectionMethod($component, 'getRecordFromRequest');
|
||||||
|
$reflectionMethod->setAccessible(true);
|
||||||
|
$reflectionMethod->invoke($component, $gridField, $request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
|
class ArrayDataWithID extends ArrayData implements TestOnly
|
||||||
|
{
|
||||||
|
public function __construct($value = [])
|
||||||
|
{
|
||||||
|
$value['ID'] ??= 0;
|
||||||
|
parent::__construct($value);
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
namespace SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest;
|
namespace SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest;
|
||||||
|
|
||||||
use SilverStripe\Control\Controller;
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Control\HTTPRequest;
|
||||||
use SilverStripe\Dev\TestOnly;
|
use SilverStripe\Dev\TestOnly;
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
use SilverStripe\Forms\Form;
|
use SilverStripe\Forms\Form;
|
||||||
@ -12,6 +13,7 @@ use SilverStripe\Forms\GridField\GridFieldDetailForm;
|
|||||||
use SilverStripe\Forms\GridField\GridFieldEditButton;
|
use SilverStripe\Forms\GridField\GridFieldEditButton;
|
||||||
use SilverStripe\Forms\GridField\GridFieldToolbarHeader;
|
use SilverStripe\Forms\GridField\GridFieldToolbarHeader;
|
||||||
use SilverStripe\Forms\GridField\GridFieldViewButton;
|
use SilverStripe\Forms\GridField\GridFieldViewButton;
|
||||||
|
use SilverStripe\ORM\SS_List;
|
||||||
|
|
||||||
class TestController extends Controller implements TestOnly
|
class TestController extends Controller implements TestOnly
|
||||||
{
|
{
|
||||||
@ -32,14 +34,17 @@ class TestController extends Controller implements TestOnly
|
|||||||
|
|
||||||
protected $template = 'BlankPage';
|
protected $template = 'BlankPage';
|
||||||
|
|
||||||
public function Form()
|
public function Form(?HTTPRequest $request = null, ?SS_List $list = null)
|
||||||
{
|
{
|
||||||
$group = PeopleGroup::get()
|
if (!$list) {
|
||||||
->filter('Name', 'My Group')
|
$group = PeopleGroup::get()
|
||||||
->sort('Name')
|
->filter('Name', 'My Group')
|
||||||
->First();
|
->sort('Name')
|
||||||
|
->First();
|
||||||
|
$list = $group->People();
|
||||||
|
}
|
||||||
|
|
||||||
$field = new GridField('testfield', 'testfield', $group->People());
|
$field = new GridField('testfield', 'testfield', $list);
|
||||||
$field->getConfig()->addComponent(new GridFieldToolbarHeader());
|
$field->getConfig()->addComponent(new GridFieldToolbarHeader());
|
||||||
$field->getConfig()->addComponent(new GridFieldAddNewButton('toolbar-header-right'));
|
$field->getConfig()->addComponent(new GridFieldAddNewButton('toolbar-header-right'));
|
||||||
$field->getConfig()->addComponent(new GridFieldViewButton());
|
$field->getConfig()->addComponent(new GridFieldViewButton());
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Forms\Tests\GridField;
|
||||||
|
|
||||||
|
use LogicException;
|
||||||
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Dev\SapphireTest;
|
||||||
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldConfig_Base;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldDetailForm;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest;
|
||||||
|
use SilverStripe\ORM\ArrayList;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
|
class GridFieldDetailForm_ItemRequestTest extends SapphireTest
|
||||||
|
{
|
||||||
|
protected $usesDatabase = false;
|
||||||
|
|
||||||
|
public function testItemEditFormThrowsException()
|
||||||
|
{
|
||||||
|
$gridField = new GridField('dummy', 'dummy', new ArrayList(), new GridFieldConfig_Base());
|
||||||
|
$modelClass = ArrayData::class;
|
||||||
|
$gridField->setModelClass($modelClass);
|
||||||
|
$itemRequest = new GridFieldDetailForm_ItemRequest($gridField, new GridFieldDetailForm(), new ArrayData(), new Controller(), '');
|
||||||
|
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$this->expectExceptionMessage(
|
||||||
|
'Cannot dynamically determine form fields. Pass the fields to GridFieldDetailForm::setFields()'
|
||||||
|
. " or implement a getCMSFields() method on $modelClass"
|
||||||
|
);
|
||||||
|
|
||||||
|
$itemRequest->ItemEditForm();
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,8 @@
|
|||||||
namespace SilverStripe\Forms\Tests\GridField;
|
namespace SilverStripe\Forms\Tests\GridField;
|
||||||
|
|
||||||
use League\Csv\Reader;
|
use League\Csv\Reader;
|
||||||
|
use LogicException;
|
||||||
|
use ReflectionMethod;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldExportButtonTest\NoView;
|
use SilverStripe\Forms\Tests\GridField\GridFieldExportButtonTest\NoView;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldExportButtonTest\Team;
|
use SilverStripe\Forms\Tests\GridField\GridFieldExportButtonTest\Team;
|
||||||
use SilverStripe\ORM\DataList;
|
use SilverStripe\ORM\DataList;
|
||||||
@ -12,8 +14,10 @@ use SilverStripe\Dev\SapphireTest;
|
|||||||
use SilverStripe\Forms\GridField\GridFieldConfig;
|
use SilverStripe\Forms\GridField\GridFieldConfig;
|
||||||
use SilverStripe\Forms\GridField\GridFieldExportButton;
|
use SilverStripe\Forms\GridField\GridFieldExportButton;
|
||||||
use SilverStripe\Forms\GridField\GridField;
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldDataColumns;
|
||||||
use SilverStripe\Forms\GridField\GridFieldPaginator;
|
use SilverStripe\Forms\GridField\GridFieldPaginator;
|
||||||
use SilverStripe\ORM\FieldType\DBField;
|
use SilverStripe\ORM\FieldType\DBField;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
class GridFieldExportButtonTest extends SapphireTest
|
class GridFieldExportButtonTest extends SapphireTest
|
||||||
{
|
{
|
||||||
@ -155,13 +159,16 @@ class GridFieldExportButtonTest extends SapphireTest
|
|||||||
public function testArrayListInput()
|
public function testArrayListInput()
|
||||||
{
|
{
|
||||||
$button = new GridFieldExportButton();
|
$button = new GridFieldExportButton();
|
||||||
|
$columns = new GridFieldDataColumns();
|
||||||
|
$columns->setDisplayFields(['ID' => 'ID']);
|
||||||
|
$this->gridField->getConfig()->addComponent($columns);
|
||||||
$this->gridField->getConfig()->addComponent(new GridFieldPaginator());
|
$this->gridField->getConfig()->addComponent(new GridFieldPaginator());
|
||||||
|
|
||||||
//Create an ArrayList 1 greater the Paginator's default 15 rows
|
//Create an ArrayList 1 greater the Paginator's default 15 rows
|
||||||
$arrayList = new ArrayList();
|
$arrayList = new ArrayList();
|
||||||
for ($i = 1; $i <= 16; $i++) {
|
for ($i = 1; $i <= 16; $i++) {
|
||||||
$dataobject = new DataObject(['ID' => $i]);
|
$datum = new ArrayData(['ID' => $i]);
|
||||||
$arrayList->add($dataobject);
|
$arrayList->add($datum);
|
||||||
}
|
}
|
||||||
$this->gridField->setList($arrayList);
|
$this->gridField->setList($arrayList);
|
||||||
|
|
||||||
@ -192,6 +199,25 @@ class GridFieldExportButtonTest extends SapphireTest
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetExportColumnsForGridFieldThrowsException()
|
||||||
|
{
|
||||||
|
$component = new GridFieldExportButton();
|
||||||
|
$gridField = new GridField('dummy', 'dummy', new ArrayList());
|
||||||
|
$gridField->getConfig()->removeComponentsByType(GridFieldDataColumns::class);
|
||||||
|
$modelClass = ArrayData::class;
|
||||||
|
$gridField->setModelClass($modelClass);
|
||||||
|
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$this->expectExceptionMessage(
|
||||||
|
'Cannot dynamically determine columns. Add a GridFieldDataColumns component to your GridField'
|
||||||
|
. " or implement a summaryFields() method on $modelClass"
|
||||||
|
);
|
||||||
|
|
||||||
|
$reflectionMethod = new ReflectionMethod($component, 'getExportColumnsForGridField');
|
||||||
|
$reflectionMethod->setAccessible(true);
|
||||||
|
$reflectionMethod->invoke($component, $gridField);
|
||||||
|
}
|
||||||
|
|
||||||
protected function createReader($string)
|
protected function createReader($string)
|
||||||
{
|
{
|
||||||
$reader = Reader::createFromString($string);
|
$reader = Reader::createFromString($string);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace SilverStripe\Forms\Tests\GridField;
|
namespace SilverStripe\Forms\Tests\GridField;
|
||||||
|
|
||||||
|
use LogicException;
|
||||||
use SilverStripe\Control\HTTPRequest;
|
use SilverStripe\Control\HTTPRequest;
|
||||||
use SilverStripe\Core\Config\Config;
|
use SilverStripe\Core\Config\Config;
|
||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
@ -20,6 +21,7 @@ use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\TeamGroup;
|
|||||||
use SilverStripe\ORM\ArrayList;
|
use SilverStripe\ORM\ArrayList;
|
||||||
use SilverStripe\ORM\DataList;
|
use SilverStripe\ORM\DataList;
|
||||||
use SilverStripe\ORM\DataObject;
|
use SilverStripe\ORM\DataObject;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
class GridFieldFilterHeaderTest extends SapphireTest
|
class GridFieldFilterHeaderTest extends SapphireTest
|
||||||
{
|
{
|
||||||
@ -226,4 +228,20 @@ class GridFieldFilterHeaderTest extends SapphireTest
|
|||||||
|
|
||||||
$this->assertNull($htmlFragment);
|
$this->assertNull($htmlFragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetDisplayFieldsThrowsException()
|
||||||
|
{
|
||||||
|
$component = new GridFieldFilterHeader();
|
||||||
|
$gridField = new GridField('dummy', 'dummy', new ArrayList());
|
||||||
|
$modelClass = ArrayData::class;
|
||||||
|
$gridField->setModelClass($modelClass);
|
||||||
|
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$this->expectExceptionMessage(
|
||||||
|
'Cannot dynamically instantiate SearchContext. Pass the SearchContext to setSearchContext()'
|
||||||
|
. " or implement a getDefaultSearchContext() method on $modelClass"
|
||||||
|
);
|
||||||
|
|
||||||
|
$component->getSearchContext($gridField);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
29
tests/php/Forms/GridField/GridFieldLevelupTest.php
Normal file
29
tests/php/Forms/GridField/GridFieldLevelupTest.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Forms\Tests\GridField;
|
||||||
|
|
||||||
|
use LogicException;
|
||||||
|
use SilverStripe\Dev\SapphireTest;
|
||||||
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldLevelup;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
|
class GridFieldLevelupTest extends SapphireTest
|
||||||
|
{
|
||||||
|
protected $usesDatabase = false;
|
||||||
|
|
||||||
|
public function testGetHTMLFragmentsThrowsException()
|
||||||
|
{
|
||||||
|
$component = new GridFieldLevelup(0);
|
||||||
|
$gridField = new GridField('dummy');
|
||||||
|
$modelClass = ArrayData::class;
|
||||||
|
$gridField->setModelClass($modelClass);
|
||||||
|
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$this->expectExceptionMessage(
|
||||||
|
GridFieldLevelup::class . " must be used with DataObject subclasses. Found '$modelClass'"
|
||||||
|
);
|
||||||
|
|
||||||
|
$component->getHTMLFragments($gridField);
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace SilverStripe\Forms\Tests\GridField;
|
namespace SilverStripe\Forms\Tests\GridField;
|
||||||
|
|
||||||
|
use LogicException;
|
||||||
|
use ReflectionMethod;
|
||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
use SilverStripe\Control\Controller;
|
use SilverStripe\Control\Controller;
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
@ -10,7 +12,10 @@ use SilverStripe\Forms\GridField\GridFieldPrintButton;
|
|||||||
use SilverStripe\Forms\GridField\GridFieldConfig;
|
use SilverStripe\Forms\GridField\GridFieldConfig;
|
||||||
use SilverStripe\Forms\GridField\GridFieldPaginator;
|
use SilverStripe\Forms\GridField\GridFieldPaginator;
|
||||||
use SilverStripe\Forms\GridField\GridField;
|
use SilverStripe\Forms\GridField\GridField;
|
||||||
|
use SilverStripe\Forms\GridField\GridFieldDataColumns;
|
||||||
use SilverStripe\Forms\Tests\GridField\GridFieldPrintButtonTest\TestObject;
|
use SilverStripe\Forms\Tests\GridField\GridFieldPrintButtonTest\TestObject;
|
||||||
|
use SilverStripe\ORM\ArrayList;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
class GridFieldPrintButtonTest extends SapphireTest
|
class GridFieldPrintButtonTest extends SapphireTest
|
||||||
{
|
{
|
||||||
@ -33,21 +38,19 @@ class GridFieldPrintButtonTest extends SapphireTest
|
|||||||
|
|
||||||
public function testLimit()
|
public function testLimit()
|
||||||
{
|
{
|
||||||
$this->assertEquals(42, $this->getTestableRows()->count());
|
$this->assertEquals(42, $this->getTestableRows(TestObject::get())->count());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCanViewIsRespected()
|
public function testCanViewIsRespected()
|
||||||
{
|
{
|
||||||
$orig = TestObject::$canView;
|
$orig = TestObject::$canView;
|
||||||
TestObject::$canView = false;
|
TestObject::$canView = false;
|
||||||
$this->assertEquals(0, $this->getTestableRows()->count());
|
$this->assertEquals(0, $this->getTestableRows(TestObject::get())->count());
|
||||||
TestObject::$canView = $orig;
|
TestObject::$canView = $orig;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getTestableRows()
|
private function getTestableRows($list)
|
||||||
{
|
{
|
||||||
$list = TestObject::get();
|
|
||||||
|
|
||||||
$button = new GridFieldPrintButton();
|
$button = new GridFieldPrintButton();
|
||||||
$button->setPrintColumns(['Name' => 'My Name']);
|
$button->setPrintColumns(['Name' => 'My Name']);
|
||||||
|
|
||||||
@ -62,4 +65,50 @@ class GridFieldPrintButtonTest extends SapphireTest
|
|||||||
$printData = $button->generatePrintData($gridField);
|
$printData = $button->generatePrintData($gridField);
|
||||||
return $printData->ItemRows;
|
return $printData->ItemRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGeneratePrintData()
|
||||||
|
{
|
||||||
|
$names = [
|
||||||
|
'Bob',
|
||||||
|
'Alice',
|
||||||
|
'John',
|
||||||
|
'Jane',
|
||||||
|
'Sam',
|
||||||
|
];
|
||||||
|
|
||||||
|
$list = new ArrayList();
|
||||||
|
foreach ($names as $name) {
|
||||||
|
$list->add(new ArrayData(['Name' => $name]));
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows = $this->getTestableRows($list);
|
||||||
|
|
||||||
|
$foundNames = [];
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
foreach ($row->ItemRow as $column) {
|
||||||
|
$foundNames[] = $column->CellString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertSame($names, $foundNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetPrintColumnsForGridFieldThrowsException()
|
||||||
|
{
|
||||||
|
$component = new GridFieldPrintButton();
|
||||||
|
$gridField = new GridField('dummy', 'dummy', new ArrayList());
|
||||||
|
$gridField->getConfig()->removeComponentsByType(GridFieldDataColumns::class);
|
||||||
|
$modelClass = ArrayData::class;
|
||||||
|
$gridField->setModelClass($modelClass);
|
||||||
|
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$this->expectExceptionMessage(
|
||||||
|
'Cannot dynamically determine columns. Add a GridFieldDataColumns component to your GridField'
|
||||||
|
. " or implement a summaryFields() method on $modelClass"
|
||||||
|
);
|
||||||
|
|
||||||
|
$reflectionMethod = new ReflectionMethod($component, 'getPrintColumnsForGridField');
|
||||||
|
$reflectionMethod->setAccessible(true);
|
||||||
|
$reflectionMethod->invoke($component, $gridField);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
304
tests/php/ORM/Search/BasicSearchContextTest.php
Normal file
304
tests/php/ORM/Search/BasicSearchContextTest.php
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\ORM\Tests\Search;
|
||||||
|
|
||||||
|
use ReflectionMethod;
|
||||||
|
use SilverStripe\Core\Config\Config;
|
||||||
|
use SilverStripe\Dev\SapphireTest;
|
||||||
|
use SilverStripe\Forms\TextField;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\HiddenField;
|
||||||
|
use SilverStripe\ORM\ArrayList;
|
||||||
|
use SilverStripe\ORM\Filters\ExactMatchFilter;
|
||||||
|
use SilverStripe\ORM\Filters\SearchFilter;
|
||||||
|
use SilverStripe\ORM\Filters\StartsWithFilter;
|
||||||
|
use SilverStripe\ORM\Search\BasicSearchContext;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
|
class BasicSearchContextTest extends SapphireTest
|
||||||
|
{
|
||||||
|
protected static $fixture_file = 'BasicSearchContextTest.yml';
|
||||||
|
|
||||||
|
protected static $extra_dataobjects = [
|
||||||
|
SearchContextTest\GeneralSearch::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
private function getList(): ArrayList
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
[
|
||||||
|
'Name' => 'James',
|
||||||
|
'Email' => 'james@example.com',
|
||||||
|
'HairColor' => 'brown',
|
||||||
|
'EyeColor' => 'brown',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'Name' => 'John',
|
||||||
|
'Email' => 'john@example.com',
|
||||||
|
'HairColor' => 'blond',
|
||||||
|
'EyeColor' => 'blue',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'Name' => 'Jane',
|
||||||
|
'Email' => 'jane@example.com',
|
||||||
|
'HairColor' => 'brown',
|
||||||
|
'EyeColor' => 'green',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'Name' => 'Hemi',
|
||||||
|
'Email' => 'hemi@example.com',
|
||||||
|
'HairColor' => 'black',
|
||||||
|
'EyeColor' => 'brown eyes',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'Name' => 'Sara',
|
||||||
|
'Email' => 'sara@example.com',
|
||||||
|
'HairColor' => 'black',
|
||||||
|
'EyeColor' => 'green',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'Name' => 'MatchNothing',
|
||||||
|
'Email' => 'MatchNothing',
|
||||||
|
'HairColor' => 'MatchNothing',
|
||||||
|
'EyeColor' => 'MatchNothing',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$list = new ArrayList();
|
||||||
|
foreach ($data as $datum) {
|
||||||
|
$list->add(new ArrayData($datum));
|
||||||
|
}
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getSearchableFields(string $generalField): FieldList
|
||||||
|
{
|
||||||
|
return new FieldList([
|
||||||
|
new HiddenField($generalField),
|
||||||
|
new TextField('Name'),
|
||||||
|
new TextField('Email'),
|
||||||
|
new TextField('HairColor'),
|
||||||
|
new TextField('EyeColor'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testResultSetFilterReturnsExpectedCount()
|
||||||
|
{
|
||||||
|
$context = new BasicSearchContext(ArrayData::class);
|
||||||
|
$results = $context->getQuery(['Name' => ''], existingQuery: $this->getList());
|
||||||
|
|
||||||
|
$this->assertEquals(6, $results->Count());
|
||||||
|
|
||||||
|
$results = $context->getQuery(['EyeColor' => 'green'], existingQuery: $this->getList());
|
||||||
|
$this->assertEquals(2, $results->Count());
|
||||||
|
|
||||||
|
$results = $context->getQuery(['EyeColor' => 'green', 'HairColor' => 'black'], existingQuery: $this->getList());
|
||||||
|
$this->assertEquals(1, $results->Count());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideApplySearchFilters()
|
||||||
|
{
|
||||||
|
$idFilter = new ExactMatchFilter('ID');
|
||||||
|
$idFilter->setModifiers(['nocase']);
|
||||||
|
return [
|
||||||
|
'defaults to PartialMatch' => [
|
||||||
|
'searchParams' => [
|
||||||
|
'q' => 'This one gets ignored',
|
||||||
|
'ID' => 47,
|
||||||
|
'Name' => 'some search term',
|
||||||
|
],
|
||||||
|
'filters' => null,
|
||||||
|
'expected' => [
|
||||||
|
'q' => 'This one gets ignored',
|
||||||
|
'ID:PartialMatch' => 47,
|
||||||
|
'Name:PartialMatch' => 'some search term',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'respects custom filters and modifiers' => [
|
||||||
|
'searchParams' => [
|
||||||
|
'q' => 'This one gets ignored',
|
||||||
|
'ID' => 47,
|
||||||
|
'Name' => 'some search term',
|
||||||
|
],
|
||||||
|
'filters' => ['ID' => $idFilter],
|
||||||
|
'expected' => [
|
||||||
|
'q' => 'This one gets ignored',
|
||||||
|
'ID:ExactMatch:nocase' => 47,
|
||||||
|
'Name:PartialMatch' => 'some search term',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideApplySearchFilters
|
||||||
|
*/
|
||||||
|
public function testApplySearchFilters(array $searchParams, ?array $filters, array $expected)
|
||||||
|
{
|
||||||
|
$context = new BasicSearchContext(ArrayData::class);
|
||||||
|
$reflectionApplySearchFilters = new ReflectionMethod($context, 'applySearchFilters');
|
||||||
|
$reflectionApplySearchFilters->setAccessible(true);
|
||||||
|
|
||||||
|
if ($filters) {
|
||||||
|
$context->setFilters($filters);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertSame($expected, $reflectionApplySearchFilters->invoke($context, $searchParams));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideGetGeneralSearchFilterTerm()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'defaults to case-insensitive partial match' => [
|
||||||
|
'filterType' => null,
|
||||||
|
'fieldFilter' => null,
|
||||||
|
'expected' => 'PartialMatch:nocase',
|
||||||
|
],
|
||||||
|
'uses default even when config is explicitly "null"' => [
|
||||||
|
'filterType' => null,
|
||||||
|
'fieldFilter' => new StartsWithFilter('MyField'),
|
||||||
|
'expected' => 'PartialMatch:nocase',
|
||||||
|
],
|
||||||
|
'uses configuration filter over field-specific filter' => [
|
||||||
|
'filterType' => ExactMatchFilter::class,
|
||||||
|
'fieldFilter' => new StartsWithFilter(),
|
||||||
|
'expected' => 'ExactMatch',
|
||||||
|
],
|
||||||
|
'uses field-specific filter if provided and config is empty string' => [
|
||||||
|
'filterType' => '',
|
||||||
|
'fieldFilter' => new StartsWithFilter('MyField'),
|
||||||
|
'expected' => 'StartsWith',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideGetGeneralSearchFilterTerm
|
||||||
|
*/
|
||||||
|
public function testGetGeneralSearchFilterTerm(?string $filterType, ?SearchFilter $fieldFilter, string $expected)
|
||||||
|
{
|
||||||
|
$context = new BasicSearchContext(ArrayData::class);
|
||||||
|
$reflectionGetGeneralSearchFilterTerm = new ReflectionMethod($context, 'getGeneralSearchFilterTerm');
|
||||||
|
$reflectionGetGeneralSearchFilterTerm->setAccessible(true);
|
||||||
|
|
||||||
|
if ($fieldFilter) {
|
||||||
|
$context->setFilters(['MyField' => $fieldFilter]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Config::modify()->set(ArrayData::class, 'general_search_field_filter', $filterType);
|
||||||
|
|
||||||
|
$this->assertSame($expected, $reflectionGetGeneralSearchFilterTerm->invoke($context, 'MyField'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideGetQuery()
|
||||||
|
{
|
||||||
|
// Note that the search TERM is the same for both scenarios,
|
||||||
|
// but because the search FIELD is different, we get different results.
|
||||||
|
return [
|
||||||
|
'search against hair' => [
|
||||||
|
'searchParams' => [
|
||||||
|
'HairColor' => 'brown',
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'James',
|
||||||
|
'Jane',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'search against eyes' => [
|
||||||
|
'searchParams' => [
|
||||||
|
'EyeColor' => 'brown',
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'James',
|
||||||
|
'Hemi',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'search against all' => [
|
||||||
|
'searchParams' => [
|
||||||
|
'q' => 'brown',
|
||||||
|
],
|
||||||
|
'expected' => [
|
||||||
|
'James',
|
||||||
|
'Jane',
|
||||||
|
'Hemi',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideGetQuery
|
||||||
|
*/
|
||||||
|
public function testGetQuery(array $searchParams, array $expected)
|
||||||
|
{
|
||||||
|
$list = $this->getList();
|
||||||
|
$context = new BasicSearchContext(ArrayData::class);
|
||||||
|
$context->setFields($this->getSearchableFields(BasicSearchContext::config()->get('general_search_field_name')));
|
||||||
|
|
||||||
|
$results = $context->getQuery($searchParams, existingQuery: $list);
|
||||||
|
$this->assertSame($expected, $results->column('Name'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGeneralSearch()
|
||||||
|
{
|
||||||
|
$list = $this->getList();
|
||||||
|
$generalField = BasicSearchContext::config()->get('general_search_field_name');
|
||||||
|
$context = new BasicSearchContext(ArrayData::class);
|
||||||
|
$context->setFields($this->getSearchableFields($generalField));
|
||||||
|
|
||||||
|
$results = $context->getQuery([$generalField => 'brown'], existingQuery: $list);
|
||||||
|
$this->assertSame(['James', 'Jane', 'Hemi'], $results->column('Name'));
|
||||||
|
$results = $context->getQuery([$generalField => 'b'], existingQuery: $list);
|
||||||
|
$this->assertSame(['James', 'John', 'Jane', 'Hemi', 'Sara'], $results->column('Name'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGeneralSearchSplitTerms()
|
||||||
|
{
|
||||||
|
$list = $this->getList();
|
||||||
|
$generalField = BasicSearchContext::config()->get('general_search_field_name');
|
||||||
|
$context = new BasicSearchContext(ArrayData::class);
|
||||||
|
$context->setFields($this->getSearchableFields($generalField));
|
||||||
|
|
||||||
|
// These terms don't exist in a single field in this order on any object, but they do exist in separate fields.
|
||||||
|
$results = $context->getQuery([$generalField => 'john blue'], existingQuery: $list);
|
||||||
|
$this->assertSame(['John'], $results->column('Name'));
|
||||||
|
$results = $context->getQuery([$generalField => 'eyes sara'], existingQuery: $list);
|
||||||
|
$this->assertSame(['Hemi', 'Sara'], $results->column('Name'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGeneralSearchNoSplitTerms()
|
||||||
|
{
|
||||||
|
Config::modify()->set(ArrayData::class, 'general_search_split_terms', false);
|
||||||
|
$list = $this->getList();
|
||||||
|
$generalField = BasicSearchContext::config()->get('general_search_field_name');
|
||||||
|
$context = new BasicSearchContext(ArrayData::class);
|
||||||
|
$context->setFields($this->getSearchableFields($generalField));
|
||||||
|
|
||||||
|
// These terms don't exist in a single field in this order on any object
|
||||||
|
$results = $context->getQuery([$generalField => 'john blue'], existingQuery: $list);
|
||||||
|
$this->assertCount(0, $results);
|
||||||
|
|
||||||
|
// These terms exist in a single field, but not in this order.
|
||||||
|
$results = $context->getQuery([$generalField => 'eyes brown'], existingQuery: $list);
|
||||||
|
$this->assertCount(0, $results);
|
||||||
|
|
||||||
|
// These terms exist in a single field in this order.
|
||||||
|
$results = $context->getQuery([$generalField => 'brown eyes'], existingQuery: $list);
|
||||||
|
$this->assertSame(['Hemi'], $results->column('Name'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSpecificFieldsCanBeSkipped()
|
||||||
|
{
|
||||||
|
$general1 = $this->objFromFixture(SearchContextTest\GeneralSearch::class, 'general1');
|
||||||
|
$list = new ArrayList();
|
||||||
|
$list->merge(SearchContextTest\GeneralSearch::get());
|
||||||
|
$generalField = BasicSearchContext::config()->get('general_search_field_name');
|
||||||
|
$context = new BasicSearchContext(SearchContextTest\GeneralSearch::class);
|
||||||
|
|
||||||
|
// We're searching for a value that DOES exist in a searchable field,
|
||||||
|
// but that field is set to be skipped by general search.
|
||||||
|
$results = $context->getQuery([$generalField => $general1->ExcludeThisField], existingQuery: $list);
|
||||||
|
$this->assertNotEmpty($general1->ExcludeThisField);
|
||||||
|
$this->assertCount(0, $results);
|
||||||
|
}
|
||||||
|
}
|
28
tests/php/ORM/Search/BasicSearchContextTest.yml
Normal file
28
tests/php/ORM/Search/BasicSearchContextTest.yml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
SilverStripe\ORM\Tests\Search\SearchContextTest\GeneralSearch:
|
||||||
|
general0:
|
||||||
|
Name: General Zero
|
||||||
|
DoNotUseThisField: omitted
|
||||||
|
HairColor: blue
|
||||||
|
ExcludeThisField: excluded
|
||||||
|
ExactMatchField: Some specific value here
|
||||||
|
PartialMatchField: A partial match is allowed for this field
|
||||||
|
MatchAny1: Some match any field
|
||||||
|
MatchAny2: Another match any field
|
||||||
|
general1:
|
||||||
|
Name: General One
|
||||||
|
DoNotUseThisField: omitted
|
||||||
|
HairColor: brown
|
||||||
|
ExcludeThisField: excluded
|
||||||
|
ExactMatchField: This requires an exact match
|
||||||
|
PartialMatchField: This explicitly allows partial matches
|
||||||
|
MatchAny1: first match
|
||||||
|
MatchAny2: second match
|
||||||
|
general2:
|
||||||
|
Name: MatchNothing
|
||||||
|
DoNotUseThisField: MatchNothing
|
||||||
|
HairColor: MatchNothing
|
||||||
|
ExcludeThisField: MatchNothing
|
||||||
|
ExactMatchField: MatchNothing
|
||||||
|
PartialMatchField: MatchNothing
|
||||||
|
MatchAny1: MatchNothing
|
||||||
|
MatchAny2: MatchNothing
|
@ -18,6 +18,7 @@ use SilverStripe\ORM\Filters\EndsWithFilter;
|
|||||||
use SilverStripe\ORM\Filters\ExactMatchFilter;
|
use SilverStripe\ORM\Filters\ExactMatchFilter;
|
||||||
use SilverStripe\ORM\Filters\PartialMatchFilter;
|
use SilverStripe\ORM\Filters\PartialMatchFilter;
|
||||||
use SilverStripe\ORM\Search\SearchContext;
|
use SilverStripe\ORM\Search\SearchContext;
|
||||||
|
use SilverStripe\View\ArrayData;
|
||||||
|
|
||||||
class SearchContextTest extends SapphireTest
|
class SearchContextTest extends SapphireTest
|
||||||
{
|
{
|
||||||
@ -527,4 +528,18 @@ class SearchContextTest extends SapphireTest
|
|||||||
$results = $context->getResults(['PartialMatchField' => 'an']);
|
$results = $context->getResults(['PartialMatchField' => 'an']);
|
||||||
$this->assertCount(1, $results);
|
$this->assertCount(1, $results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetSearchFieldsThrowsException()
|
||||||
|
{
|
||||||
|
$modelClass = ArrayData::class;
|
||||||
|
$context = new SearchContext($modelClass);
|
||||||
|
|
||||||
|
$this->expectException(LogicException::class);
|
||||||
|
$this->expectExceptionMessage(
|
||||||
|
'Cannot dynamically determine search fields. Pass the fields to setFields()'
|
||||||
|
. " or implement a scaffoldSearchFields() method on {$modelClass}"
|
||||||
|
);
|
||||||
|
|
||||||
|
$context->getSearchFields();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user