2017-10-26 02:04:30 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace SilverStripe\Forms\Tests;
|
|
|
|
|
|
|
|
use SilverStripe\Assets\File;
|
|
|
|
use SilverStripe\Dev\SapphireTest;
|
2018-11-23 03:17:17 +01:00
|
|
|
use SilverStripe\Forms\Form;
|
|
|
|
use SilverStripe\Forms\FormTemplateHelper;
|
2017-10-26 02:04:30 +02:00
|
|
|
use SilverStripe\Forms\TreeMultiselectField;
|
2019-01-24 15:45:38 +01:00
|
|
|
use SilverStripe\ORM\Tests\HierarchyTest\TestObject;
|
|
|
|
use SilverStripe\View\SSViewer;
|
2017-10-26 02:04:30 +02:00
|
|
|
|
|
|
|
class TreeMultiselectFieldTest extends SapphireTest
|
|
|
|
{
|
|
|
|
protected static $fixture_file = 'TreeDropdownFieldTest.yml';
|
|
|
|
|
2019-01-24 15:45:38 +01:00
|
|
|
protected static $extra_dataobjects = [
|
|
|
|
TestObject::class,
|
|
|
|
];
|
|
|
|
|
2018-11-23 03:17:17 +01:00
|
|
|
protected $formId = 'TheFormID';
|
|
|
|
protected $fieldName = 'TestTree';
|
|
|
|
|
2018-11-29 00:13:56 +01:00
|
|
|
/**
|
|
|
|
* Mock object of a generic form
|
|
|
|
*
|
|
|
|
* @var Form
|
|
|
|
*/
|
|
|
|
protected $form;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Instance of the TreeMultiselectField
|
|
|
|
*
|
|
|
|
* @var TreeMultiselectField
|
|
|
|
*/
|
|
|
|
protected $field;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The File objects of folders loaded from the fixture
|
|
|
|
*
|
|
|
|
* @var File[]
|
|
|
|
*/
|
|
|
|
protected $folders;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The array of folder ids
|
|
|
|
*
|
|
|
|
* @var int[]
|
|
|
|
*/
|
|
|
|
protected $folderIds;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Concatenated folder ids for use as a value for the field
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $fieldValue;
|
|
|
|
|
2018-11-28 21:55:28 +01:00
|
|
|
protected function setUp()
|
2018-11-23 03:17:17 +01:00
|
|
|
{
|
|
|
|
parent::setUp();
|
|
|
|
|
2019-01-24 15:45:38 +01:00
|
|
|
// Don't let other themes interfere with these tests
|
|
|
|
SSViewer::set_themes([]);
|
|
|
|
|
2018-11-23 03:17:17 +01:00
|
|
|
$this->form = $this->buildFormMock();
|
|
|
|
$this->field = $this->buildField($this->form);
|
|
|
|
$this->folders = $this->loadFolders();
|
|
|
|
|
|
|
|
$this->folderIds = array_map(
|
|
|
|
static function ($f) {
|
|
|
|
return $f->ID;
|
|
|
|
},
|
|
|
|
$this->folders
|
|
|
|
);
|
|
|
|
$this->fieldValue = implode(',', $this->folderIds);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Build a new mock object of a Form
|
|
|
|
*
|
|
|
|
* @return Form
|
|
|
|
*/
|
|
|
|
protected function buildFormMock()
|
|
|
|
{
|
|
|
|
$form = $this->createMock(Form::class);
|
|
|
|
|
|
|
|
$form->method('getTemplateHelper')
|
|
|
|
->willReturn(FormTemplateHelper::singleton());
|
|
|
|
|
|
|
|
$form->method('getHTMLID')
|
|
|
|
->willReturn($this->formId);
|
|
|
|
|
|
|
|
return $form;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Build a new instance of TreeMultiselectField
|
|
|
|
*
|
|
|
|
* @param Form $form The field form
|
|
|
|
*
|
|
|
|
* @return TreeMultiselectField
|
|
|
|
*/
|
|
|
|
protected function buildField(Form $form)
|
2018-11-20 02:04:12 +01:00
|
|
|
{
|
2018-11-23 03:17:17 +01:00
|
|
|
$field = new TreeMultiselectField($this->fieldName, 'Test tree', File::class);
|
|
|
|
$field->setForm($form);
|
2018-11-20 02:04:12 +01:00
|
|
|
|
2018-11-23 03:17:17 +01:00
|
|
|
return $field;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Load several files from the fixtures and return them in an array
|
|
|
|
*
|
|
|
|
* @return File[]
|
|
|
|
*/
|
|
|
|
protected function loadFolders()
|
|
|
|
{
|
2018-11-20 02:04:12 +01:00
|
|
|
$asdf = $this->objFromFixture(File::class, 'asdf');
|
|
|
|
$subfolderfile1 = $this->objFromFixture(File::class, 'subfolderfile1');
|
|
|
|
|
2018-11-23 03:17:17 +01:00
|
|
|
return [$asdf, $subfolderfile1];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test the TreeMultiselectField behaviour with no selected values
|
|
|
|
*/
|
|
|
|
public function testEmpty()
|
|
|
|
{
|
|
|
|
$field = $this->field;
|
|
|
|
|
|
|
|
$fieldId = $field->ID();
|
|
|
|
$this->assertEquals($fieldId, sprintf('%s_%s', $this->formId, $this->fieldName));
|
|
|
|
|
2018-11-20 02:04:12 +01:00
|
|
|
$schemaStateDefaults = $field->getSchemaStateDefaults();
|
2018-11-23 03:17:17 +01:00
|
|
|
$this->assertArraySubset(
|
|
|
|
[
|
|
|
|
'id' => $fieldId,
|
|
|
|
'name' => $this->fieldName,
|
|
|
|
'value' => 'unchanged'
|
|
|
|
],
|
|
|
|
$schemaStateDefaults,
|
|
|
|
true
|
|
|
|
);
|
2018-11-20 02:04:12 +01:00
|
|
|
|
2018-11-23 03:17:17 +01:00
|
|
|
$schemaDataDefaults = $field->getSchemaDataDefaults();
|
|
|
|
$this->assertArraySubset(
|
|
|
|
[
|
|
|
|
'id' => $fieldId,
|
|
|
|
'name' => $this->fieldName,
|
|
|
|
'type' => 'text',
|
|
|
|
'schemaType' => 'SingleSelect',
|
|
|
|
'component' => 'TreeDropdownField',
|
|
|
|
'holderId' => sprintf('%s_Holder', $fieldId),
|
|
|
|
'title' => 'Test tree',
|
|
|
|
'extraClass' => 'treemultiselect multiple searchable',
|
|
|
|
'data' => [
|
|
|
|
'urlTree' => 'field/TestTree/tree',
|
|
|
|
'showSearch' => true,
|
2019-04-17 03:29:54 +02:00
|
|
|
'emptyString' => '(Search or choose File)',
|
2018-11-23 03:17:17 +01:00
|
|
|
'hasEmptyDefault' => false,
|
|
|
|
'multiple' => true
|
|
|
|
]
|
|
|
|
],
|
|
|
|
$schemaDataDefaults,
|
|
|
|
true
|
2018-11-20 02:04:12 +01:00
|
|
|
);
|
2018-11-23 03:17:17 +01:00
|
|
|
|
|
|
|
$items = $field->getItems();
|
|
|
|
$this->assertCount(0, $items, 'there must be no items selected');
|
|
|
|
|
|
|
|
$html = $field->Field();
|
|
|
|
$this->assertContains($field->ID(), $html);
|
|
|
|
$this->assertContains('unchanged', $html);
|
2018-11-20 02:04:12 +01:00
|
|
|
}
|
|
|
|
|
2018-11-23 03:17:17 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Test the field with some values set
|
|
|
|
*/
|
|
|
|
public function testChanged()
|
2017-10-26 02:04:30 +02:00
|
|
|
{
|
2018-11-23 03:17:17 +01:00
|
|
|
$field = $this->field;
|
2018-11-20 02:04:12 +01:00
|
|
|
|
2018-11-23 03:17:17 +01:00
|
|
|
$field->setValue($this->fieldValue);
|
2018-11-20 02:04:12 +01:00
|
|
|
|
2018-11-23 03:17:17 +01:00
|
|
|
$schemaStateDefaults = $field->getSchemaStateDefaults();
|
|
|
|
$this->assertArraySubset(
|
|
|
|
[
|
|
|
|
'id' => $field->ID(),
|
|
|
|
'name' => 'TestTree',
|
|
|
|
'value' => $this->folderIds
|
|
|
|
],
|
|
|
|
$schemaStateDefaults,
|
|
|
|
true
|
|
|
|
);
|
|
|
|
|
|
|
|
$items = $field->getItems();
|
|
|
|
$this->assertCount(2, $items, 'there must be exactly 2 items selected');
|
|
|
|
|
|
|
|
$html = $field->Field();
|
|
|
|
$this->assertContains($field->ID(), $html);
|
|
|
|
$this->assertContains($this->fieldValue, $html);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test empty field in readonly mode
|
|
|
|
*/
|
|
|
|
public function testEmptyReadonly()
|
|
|
|
{
|
|
|
|
$field = $this->field->performReadonlyTransformation();
|
2017-10-26 02:04:30 +02:00
|
|
|
|
2018-11-20 02:04:12 +01:00
|
|
|
$schemaStateDefaults = $field->getSchemaStateDefaults();
|
2018-11-23 03:17:17 +01:00
|
|
|
$this->assertArraySubset(
|
|
|
|
[
|
|
|
|
'id' => $field->ID(),
|
|
|
|
'name' => 'TestTree',
|
|
|
|
'value' => 'unchanged'
|
|
|
|
],
|
|
|
|
$schemaStateDefaults,
|
|
|
|
true
|
|
|
|
);
|
|
|
|
|
|
|
|
$schemaDataDefaults = $field->getSchemaDataDefaults();
|
|
|
|
$this->assertArraySubset(
|
|
|
|
[
|
|
|
|
'id' => $field->ID(),
|
|
|
|
'name' => $this->fieldName,
|
|
|
|
'type' => 'text',
|
|
|
|
'schemaType' => 'SingleSelect',
|
|
|
|
'component' => 'TreeDropdownField',
|
|
|
|
'holderId' => sprintf('%s_Holder', $field->ID()),
|
|
|
|
'title' => 'Test tree',
|
|
|
|
'extraClass' => 'treemultiselectfield_readonly multiple searchable',
|
|
|
|
'data' => [
|
|
|
|
'urlTree' => 'field/TestTree/tree',
|
|
|
|
'showSearch' => true,
|
2019-04-17 03:29:54 +02:00
|
|
|
'emptyString' => '(Search or choose File)',
|
2018-11-23 03:17:17 +01:00
|
|
|
'hasEmptyDefault' => false,
|
|
|
|
'multiple' => true
|
|
|
|
]
|
|
|
|
],
|
|
|
|
$schemaDataDefaults,
|
|
|
|
true
|
|
|
|
);
|
2018-11-20 02:04:12 +01:00
|
|
|
|
2018-11-22 00:11:18 +01:00
|
|
|
$items = $field->getItems();
|
2018-11-23 03:17:17 +01:00
|
|
|
$this->assertCount(0, $items, 'there must be 0 selected items');
|
|
|
|
|
|
|
|
$html = $field->Field();
|
|
|
|
$this->assertContains($field->ID(), $html);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test changed field in readonly mode
|
|
|
|
*/
|
|
|
|
public function testChangedReadonly()
|
|
|
|
{
|
|
|
|
$field = $this->field;
|
|
|
|
$field->setValue($this->fieldValue);
|
|
|
|
$field = $field->performReadonlyTransformation();
|
|
|
|
|
|
|
|
$schemaStateDefaults = $field->getSchemaStateDefaults();
|
|
|
|
$this->assertArraySubset(
|
|
|
|
[
|
|
|
|
'id' => $field->ID(),
|
|
|
|
'name' => 'TestTree',
|
|
|
|
'value' => $this->folderIds
|
|
|
|
],
|
|
|
|
$schemaStateDefaults,
|
|
|
|
true
|
|
|
|
);
|
|
|
|
|
|
|
|
$schemaDataDefaults = $field->getSchemaDataDefaults();
|
|
|
|
$this->assertArraySubset(
|
|
|
|
[
|
|
|
|
'id' => $field->ID(),
|
|
|
|
'name' => $this->fieldName,
|
|
|
|
'type' => 'text',
|
|
|
|
'schemaType' => 'SingleSelect',
|
|
|
|
'component' => 'TreeDropdownField',
|
|
|
|
'holderId' => sprintf('%s_Holder', $field->ID()),
|
|
|
|
'title' => 'Test tree',
|
|
|
|
'extraClass' => 'treemultiselectfield_readonly multiple searchable',
|
|
|
|
'data' => [
|
|
|
|
'urlTree' => 'field/TestTree/tree',
|
|
|
|
'showSearch' => true,
|
2019-04-17 03:29:54 +02:00
|
|
|
'emptyString' => '(Search or choose File)',
|
2018-11-23 03:17:17 +01:00
|
|
|
'hasEmptyDefault' => false,
|
|
|
|
'multiple' => true
|
|
|
|
]
|
|
|
|
],
|
|
|
|
$schemaDataDefaults,
|
|
|
|
true
|
2017-10-26 02:04:30 +02:00
|
|
|
);
|
2018-11-23 03:17:17 +01:00
|
|
|
|
|
|
|
$items = $field->getItems();
|
|
|
|
$this->assertCount(2, $items, 'there must be exactly 2 selected items');
|
|
|
|
|
|
|
|
$html = $field->Field();
|
|
|
|
$this->assertContains($field->ID(), $html);
|
|
|
|
$this->assertContains($this->fieldValue, $html);
|
2017-10-26 02:04:30 +02:00
|
|
|
}
|
2020-09-11 01:52:36 +02:00
|
|
|
|
|
|
|
public function testGetItems()
|
|
|
|
{
|
|
|
|
// Default items scaffolded from 'unchanged' value (empty)
|
|
|
|
$field = $this->field;
|
|
|
|
$this->assertListEquals(
|
|
|
|
[],
|
|
|
|
$field->getItems()
|
|
|
|
);
|
|
|
|
|
|
|
|
$expectedItem = array_map(
|
|
|
|
function ($folder) {
|
|
|
|
return [
|
|
|
|
'Filename' => $folder->Filename,
|
|
|
|
];
|
|
|
|
},
|
|
|
|
$this->loadFolders()
|
|
|
|
);
|
|
|
|
|
|
|
|
// Set list of items by array of ids
|
|
|
|
$field->setValue($this->folderIds);
|
|
|
|
$this->assertListEquals(
|
|
|
|
$expectedItem,
|
|
|
|
$field->getItems()
|
|
|
|
);
|
|
|
|
|
|
|
|
// Set list of items by comma separated ids
|
|
|
|
$field->setValue($this->fieldValue);
|
|
|
|
$this->assertListEquals(
|
|
|
|
$expectedItem,
|
|
|
|
$field->getItems()
|
|
|
|
);
|
|
|
|
|
|
|
|
// Handle legacy empty value (form submits 'unchanged')
|
|
|
|
$field->setValue('unchanged');
|
|
|
|
$this->assertListEquals(
|
|
|
|
[],
|
|
|
|
$field->getItems()
|
|
|
|
);
|
|
|
|
}
|
2017-10-26 02:04:30 +02:00
|
|
|
}
|