'one', 2 => 'two']; $field = new DropdownField('Field', null, $source); $this->assertEquals( $source, $field->getSource() ); $this->assertEquals( $source, $field->getSource() ); $items = new ArrayList( [ [ 'ID' => 1, 'Title' => 'ichi', 'OtherField' => 'notone' ], [ 'ID' => 2, 'Title' => 'ni', 'OtherField' => 'nottwo' ], ] ); $field->setSource($items); $this->assertEquals( $field->getSource(), [ 1 => 'ichi', 2 => 'ni', ] ); $map = new Map($items, 'ID', 'OtherField'); $field->setSource($map); $this->assertEquals( $field->getSource(), [ 1 => 'notone', 2 => 'nottwo', ] ); } /** * Test different data sources */ public function testSources() { // Array $items = ['a' => 'Apple', 'b' => 'Banana', 'c' => 'Cranberry']; $field = new DropdownField('Field', null, $items); $this->assertEquals($items, $field->getSource()); // SS_List $list = new ArrayList( [ new ArrayData( [ 'ID' => 'a', 'Title' => 'Apple' ] ), new ArrayData( [ 'ID' => 'b', 'Title' => 'Banana' ] ), new ArrayData( [ 'ID' => 'c', 'Title' => 'Cranberry' ] ) ] ); $field2 = new DropdownField('Field', null, $list); $this->assertEquals($items, $field2->getSource()); $field3 = new DropdownField('Field', null, $list->map()); $this->assertEquals($items, $field3->getSource()); } public function testReadonlyField() { $field = new DropdownField('FeelingOk', 'Are you feeling ok?', [0 => 'No', 1 => 'Yes']); $field->setEmptyString('(Select one)'); $field->setValue(1); $readonlyField = $field->performReadonlyTransformation(); preg_match('/Yes/', $field->Field() ?? '', $matches); $this->assertEquals($matches[0], 'Yes'); } public function testHasEmptyDefault() { $source = [1 => 'one']; // Test getSource with empty $field = new DropdownField('Field', null, $source); $field->setHasEmptyDefault(true); $this->assertEquals( $field->getSource(), [ 1 => 'one' ] ); // Test that an empty option comes through in the markup however $options = $this->findOptionElements($field->Field()); $this->assertEquals( 2, count($options ?? []), 'Two options exist in the markup, one for the source, one for empty' ); // the default value should be first $first = array_shift($options); $attrs = $first->attributes(); $this->assertNotEquals( 1, $attrs['value'], 'First value is the not value (not the source value)' ); // Test Field Without Empty $FieldWithoutEmpty = new DropdownField('Field', null, $source); $this->assertEquals( $FieldWithoutEmpty->getSource(), [ 1 => 'one' ] ); // Test that an empty option does not comes through in the markup however $options = $this->findOptionElements($FieldWithoutEmpty->Field()); $this->assertEquals( 1, count($options ?? []), 'As hasEmptyDefault is not provided, then no default option.' ); } public function testEmpty() { $fieldName = 'TestField'; $formName = 'testForm'; // Create mock form $form = $this->createMock(Form::class); $form->method('getTemplateHelper') ->willReturn(FormTemplateHelper::singleton()); $form->method('getHTMLID') ->willReturn($formName); $source = [ 'first' => 'value', 0 => 'otherValue' ]; $field = new DropdownField($fieldName, 'Test Field', $source); $field->setForm($form); $fieldId = $field->ID(); $this->assertEquals($fieldId, sprintf('%s_%s', $formName, $fieldName)); // Check state for default value $schemaStateDefaults = $field->getSchemaStateDefaults(); $this->assertSame($fieldId, $schemaStateDefaults['id']); $this->assertSame($fieldName, $schemaStateDefaults['name']); $this->assertSame('first', $schemaStateDefaults['value']); // Check data for empty defaults $schemaDataDefaults = $field->getSchemaDataDefaults(); $this->assertSame($fieldId, $schemaDataDefaults['id']); $this->assertSame($fieldName, $schemaDataDefaults['name']); $this->assertSame('text', $schemaDataDefaults['type']); $this->assertSame('SingleSelect', $schemaDataDefaults['schemaType']); $this->assertSame(sprintf('%s_Holder', $fieldId), $schemaDataDefaults['holderId']); $this->assertSame('Test Field', $schemaDataDefaults['title']); $this->assertSame('dropdown', $schemaDataDefaults['extraClass']); $this->assertSame(null, $schemaDataDefaults['data']['emptyString']); $this->assertSame(false, $schemaDataDefaults['data']['hasEmptyDefault']); // Set an empty string of field $field->setEmptyString('(Any)'); // Check state for default value $schemaStateDefaults = $field->getSchemaStateDefaults(); $this->assertSame($fieldId, $schemaStateDefaults['id']); $this->assertSame($fieldName, $schemaStateDefaults['name']); $this->assertSame('', $schemaStateDefaults['value']); // Check data for empty defaults $schemaDataDefaults = $field->getSchemaDataDefaults(); $this->assertSame($fieldId, $schemaDataDefaults['id']); $this->assertSame($fieldName, $schemaDataDefaults['name']); $this->assertSame('text', $schemaDataDefaults['type']); $this->assertSame('SingleSelect', $schemaDataDefaults['schemaType']); $this->assertSame(sprintf('%s_Holder', $fieldId), $schemaDataDefaults['holderId']); $this->assertSame('Test Field', $schemaDataDefaults['title']); $this->assertSame('dropdown', $schemaDataDefaults['extraClass']); $this->assertSame('(Any)', $schemaDataDefaults['data']['emptyString']); $this->assertSame(true, $schemaDataDefaults['data']['hasEmptyDefault']); } public function testZeroArraySourceNotOverwrittenByEmptyString() { $source = [0=>'zero']; $field = new DropdownField('Field', null, $source); $field->setEmptyString('select...'); $this->assertEquals( $field->getSource(), [ 0 => 'zero' ] ); $options = $this->findOptionElements($field->Field()); $this->assertEquals( 2, count($options ?? []), 'Two options exist in the markup, one for the source, one for empty' ); } public function testStringZeroValueSelectedOptionBehaviour() { $field = new DropdownField( 'Field', null, [ '-1' => 'some negative', '0' => 'none', '1' => 'one', '2+' => 'two or more' ], '0' ); $selectedOptions = $this->findSelectedOptionElements($field->Field()); $this->assertEquals((string) $selectedOptions[0], 'none', 'The selected option is "none"'); $field = new DropdownField( 'Field', null, [ '-1' => 'some negative', '0' => 'none', '1' => 'one', '2+' => 'two or more' ], 0 ); $selectedOptions = $this->findSelectedOptionElements($field->Field()); $this->assertEquals((string) $selectedOptions[0], 'none', 'The selected option is "none"'); } public function testStringOneValueSelectedOptionBehaviour() { $field = new DropdownField( 'Field', null, [ '-1' => 'some negative', '0' => 'none', '1' => 'one', '2+' => 'two or more' ], '1' ); $selectedOptions = $this->findSelectedOptionElements($field->Field()); $this->assertEquals((string) $selectedOptions[0], 'one', 'The selected option is "one"'); $field = new DropdownField( 'Field', null, [ '-1' => 'some negative', '0' => 'none', '1' => 'one', '2+' => 'two or more' ], 1 ); $selectedOptions = $this->findSelectedOptionElements($field->Field()); $this->assertEquals((string) $selectedOptions[0], 'one', 'The selected option is "one"'); } public function testNumberOfSelectOptionsAvailable() { /* Create a field with a blank value */ $field = $this->createDropdownField('(Any)'); /* 3 options are available */ $this->assertEquals(count($this->findOptionElements($field->Field()) ?? []), 3, '3 options are available'); $selectedOptions = $this->findSelectedOptionElements($field->Field()); $this->assertEquals( count($selectedOptions ?? []), 1, 'We only have 1 selected option, since a dropdown can only possibly have one!' ); /* Create a field without a blank value */ $field = $this->createDropdownField(); /* 2 options are available */ $this->assertEquals(count($this->findOptionElements($field->Field()) ?? []), 2, '2 options are available'); $selectedOptions = $this->findSelectedOptionElements($field->Field()); $this->assertEquals(count($selectedOptions ?? []), 0, 'There are no selected options'); } public function testIntegerZeroValueSeelctedOptionBehaviour() { $field = $this->createDropdownField('(Any)', 0); $selectedOptions = $this->findSelectedOptionElements($field->Field()); $this->assertEquals((string) $selectedOptions[0], 'No', 'The selected option is "No"'); } public function testBlankStringValueSelectedOptionBehaviour() { $field = $this->createDropdownField('(Any)'); $selectedOptions = $this->findSelectedOptionElements($field->Field()); $this->assertEquals((string) $selectedOptions[0], '(Any)', 'The selected option is "(Any)"'); } public function testNullValueSelectedOptionBehaviour() { $field = $this->createDropdownField('(Any)', null); $selectedOptions = $this->findSelectedOptionElements($field->Field()); $this->assertEquals((string) $selectedOptions[0], '(Any)', 'The selected option is "(Any)"'); } public function testStringValueSelectedOptionBehaviour() { $field = $this->createDropdownField('(Any)', '1'); $selectedOptions = $this->findSelectedOptionElements($field->Field()); $this->assertEquals((string) $selectedOptions[0], 'Yes', 'The selected option is "Yes"'); $field->setSource( [ 'Cats' => 'Cats and Kittens', 'Dogs' => 'Dogs and Puppies' ] ); $field->setValue('Cats'); $selectedOptions = $this->findSelectedOptionElements($field->Field()); $this->assertEquals( (string) $selectedOptions[0], 'Cats and Kittens', 'The selected option is "Cats and Kittens"' ); } public function testNumberOfDisabledOptions() { /* Create a field with a blank value & set 0 & 1 to disabled */ $field = $this->createDropdownField('(Any)'); $field->setDisabledItems([0,1]); /* 3 options are available */ $this->assertEquals(count($this->findOptionElements($field->Field()) ?? []), 3, '3 options are available'); /* There are 2 disabled options */ $disabledOptions = $this->findDisabledOptionElements($field->Field()); $this->assertEquals(count($disabledOptions ?? []), 2, 'We have 2 disabled options'); /* Create a field without a blank value & set 1 to disabled, then set none to disabled (unset) */ $field = $this->createDropdownField(); $field->setDisabledItems([1]); /* 2 options are available */ $this->assertEquals(count($this->findOptionElements($field->Field()) ?? []), 2, '2 options are available'); /* get disabled items returns an array of one */ $this->assertEquals( $field->getDisabledItems(), [ 1 ] ); /* unset disabled items */ $field->setDisabledItems([]); /* There are no disabled options anymore */ $disabledOptions = $this->findDisabledOptionElements($field->Field()); $this->assertEquals(count($disabledOptions ?? []), 0, 'There are no disabled options'); } /** * The Field() method should be able to handle arrays as values in an edge case. If it couldn't handle it then * this test would trigger an array to string conversion PHP notice * * @dataProvider arrayValueProvider */ public function testDropdownWithArrayValues($value) { $field = $this->createDropdownField(); $field->setValue($value); $this->assertInstanceOf('SilverStripe\\ORM\\FieldType\\DBHTMLText', $field->Field()); $this->assertSame($value, $field->Value()); } /** * @return array */ public function arrayValueProvider() { return [ [[]], [[0]], [[123]], [['string']], ['Regression-ish test.'] ]; } /** * Create a test dropdown field, with the option to * set what source and blank value it should contain * as optional parameters. * * @param string|null $emptyString The text to display for the empty value * @param string|integer $value The default value of the field * @return DropdownField object */ public function createDropdownField($emptyString = null, $value = '') { /* Set up source, with 0 and 1 integers as the values */ $source = [ 0 => 'No', 1 => 'Yes' ]; $field = new DropdownField('Field', null, $source, $value); if ($emptyString !== null) { $field->setEmptyString($emptyString); } return $field; } /** * Find all the