improvements-2.x-dev/tests/src/Functional/ImprovementsFieldTest.php
tests/src/Functional/ImprovementsFieldTest.php
<?php
namespace Drupal\Tests\improvements\Functional;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\node\Entity\Node;
use Drupal\node\NodeTypeInterface;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\improvements\Traits\ImprovementsTestTrait;
use Drupal\Tests\node\Traits\NodeCreationTrait;
class ImprovementsFieldTest extends BrowserTestBase {
use ImprovementsTestTrait;
use NodeCreationTrait;
/**
* {@inheritDoc}
*/
protected $defaultTheme = 'stark';
/**
* {@inheritDoc}
*/
protected static $modules = [
'improvements',
'node',
'field',
'field_ui',
];
protected NodeTypeInterface $pageNodeType;
/**
* {@inheritDoc}
*/
protected function setUp(): void {
parent::setUp();
// Create "page" node type
$this->pageNodeType = $this->createContentType(['type' => 'page', 'name' => 'Page']);
}
/**
* Test ComputedMapFieldItemList class.
*
* @covers \Drupal\improvements\Plugin\Field\ComputedMapFieldItemList
*/
public function testFieldTypeComputedMap(): void {
$this->installModule('improvements_test');
$node = $this->createNode([
'title' => 'Node for test ' . __FUNCTION__,
'test_map_field' => [
'first' => 'First',
'second' => [
'foo' => 'Foo',
'bar' => 'Bar',
],
],
]);
$this->assertSame('Foo', $node->get('test_computed_map_field_single')->value);
$this->assertSame('Foo-Bar', $node->get('test_computed_map_field_multiple')->value);
$this->assertSame('Foo', $node->get('test_computed_map_field_single')->first()->value);
$this->assertSame('Foo-Bar', $node->get('test_computed_map_field_multiple')->first()->value);
$this->assertSame([0 => ['value' => 'Foo']], $node->get('test_computed_map_field_single')->getValue());
$this->assertSame([0 => ['value' => 'Foo-Bar']], $node->get('test_computed_map_field_multiple')->getValue());
$this->assertSame(['value' => 'Foo'], $node->get('test_computed_map_field_single')->first()->getValue());
$this->assertSame(['value' => 'Foo-Bar'], $node->get('test_computed_map_field_multiple')->first()->getValue());
}
/**
* Test ThirdPartyDataItem.
*
* @covers \Drupal\improvements\Plugin\Field\FieldType\ThirdPartyDataItem
*/
public function testFieldTypeThirdPartyData(): void {
$this->installModule('improvements_test');
$node = $this->createNode(['title' => 'Node for test ' . __FUNCTION__]);
$node->get('test_third_party_data')->setThirdPartyData('improvements_test', 'foo', 'bar');
$node->get('test_third_party_data')->setThirdPartyData('improvements_test', 'baz', 'qux');
$node->save();
$node = Node::load($node->id());
$this->assertSame('bar', $node->get('test_third_party_data')->getThirdPartyData('improvements_test', 'foo'));
$this->assertSame('qux', $node->get('test_third_party_data')->getThirdPartyData('improvements_test', 'baz'));
$this->assertSame(NULL, $node->get('test_third_party_data')->getThirdPartyData('improvements_test', 'bat'));
}
/**
* Test "string_textarea" widget with "string" field type.
*/
public function testFieldWidgetStringTextareaWithStringFieldType(): void {
$this->createField(
entity_type: 'node',
entity_bundle: 'page',
field_name: 'field_string',
field_type: 'string',
field_label: 'Test string field',
widget_type: 'string_textarea',
formatter_type: 'string',
);
$this->drupalLoginAsRoot();
$web_assert = $this->assertSession();
$this->drupalGet('/admin/structure/types/manage/page/form-display');
$this->dontSeeErrorMessage();
$web_assert->fieldValueEquals('fields[field_string][type]', 'string_textarea');
$this->drupalGet('/node/add/page');
$this->dontSeeErrorMessage();
$web_assert->elementExists('css', 'textarea[name="field_string[0][value]"]');
$this->submitForm([
'title[0][value]' => 'Node for ' . __FUNCTION__,
'field_string[0][value]' => 'Textarea value',
], 'Save');
$this->dontSeeErrorMessage();
$web_assert->pageTextContains('Textarea value');
}
/**
* Test field widget "multiple_string_textarea".
*
* @covers \Drupal\improvements\Plugin\Field\FieldWidget\MultipleStringTextarea
*/
public function testFieldWidgetMultipleStringTextarea(): void {
$this->createField(
entity_type: 'node',
entity_bundle: 'page',
field_name: 'field_strings',
field_type: 'string',
field_label: 'Test strings field',
storage_settings: ['cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED],
widget_type: 'multiple_string_textarea',
);
$this->drupalLoginAsRoot();
$this->drupalGet('/node/add/page');
$this->dontSeeErrorMessage();
$web_assert = $this->assertSession();
$web_assert->elementExists('css', 'textarea[name="field_strings[value]"]');
$this->submitForm([
'title[0][value]' => 'Node for test ' . __FUNCTION__,
'field_strings[value]' => "foo\nbar\nbaz",
], 'Save');
$this->dontSeeErrorMessage();
$node_id = $this->getLastAddedNodeId();
$node = Node::load($node_id);
$this->assertSame([
0 => ['value' => 'foo'],
1 => ['value' => 'bar'],
2 => ['value' => 'baz'],
], $node->get('field_strings')->getValue());
}
/**
* Test field widget "multiple_string_textfield".
*
* @covers \Drupal\improvements\Plugin\Field\FieldWidget\MultipleStringTextfield
*/
public function testFieldWidgetMultipleStringTextfield(): void {
$this->createField(
entity_type: 'node',
entity_bundle: 'page',
field_name: 'field_strings',
field_type: 'string',
field_label: 'Strings',
storage_settings: ['cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED],
widget_type: 'multiple_string_textfield',
);
$this->drupalLoginAsRoot();
$this->drupalGet('/node/add/page');
$this->dontSeeErrorMessage();
$web_assert = $this->assertSession();
$web_assert->elementExists('css', 'input[name="field_strings[value]"][type="text"]');
$this->submitForm([
'title[0][value]' => 'Node for test ' . __FUNCTION__,
'field_strings[value]' => "foo, bar, baz",
], 'Save');
$this->dontSeeErrorMessage();
$node_id = $this->getLastAddedNodeId();
$node = Node::load($node_id);
$this->assertSame([
0 => ['value' => 'foo'],
1 => ['value' => 'bar'],
2 => ['value' => 'baz'],
], $node->get('field_strings')->getValue());
}
/**
* Test ExtendedImageFormatter
*
* @covers \Drupal\improvements\Plugin\Field\FieldFormatter\ExtendedImageFormatter
*/
public function testFieldFormatterExtendedImage(): void {
$this->installModule('image');
$web_assert = $this->assertSession();
$this->createField(
entity_type: 'node',
entity_bundle: 'page',
field_name: 'field_image',
field_type: 'image',
field_label: 'Test image field',
storage_settings: ['cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED],
widget_type: 'image_image',
formatter_type: 'extended_image_formatter',
);
$this->drupalLoginAsRoot();
$this->drupalGet('/admin/structure/types/manage/page/display');
$this->dontSeeErrorMessage();
$this->openEntityDisplayComponentSettings('field_image');
$web_assert->elementTextContains('css', '.plugin-name', 'Extended image formatter');
$web_assert->fieldExists('fields[field_image][settings_edit_form][settings][image_style]');
$web_assert->fieldExists('fields[field_image][settings_edit_form][settings][first_image_style]');
$web_assert->fieldExists('fields[field_image][settings_edit_form][settings][image_link]');
$web_assert->fieldExists('fields[field_image][settings_edit_form][settings][image_link_style]');
$this->submitForm([
'fields[field_image][settings_edit_form][settings][image_style]' => 'thumbnail',
'fields[field_image][settings_edit_form][settings][first_image_style]' => 'large',
'fields[field_image][settings_edit_form][settings][image_link]' => 'file',
'fields[field_image][settings_edit_form][settings][image_link_style]' => 'medium',
], 'Save');
$this->dontSeeErrorMessage();
$web_assert->pageTextContains('Image style: thumbnail');
$first_image = $this->createFileEntity(['uri' => 'public://first-image.png']);
$second_image = $this->createFileEntity(['uri' => 'public://second-image.png']);
$node = $this->createNode([
'title' => 'Node for test ' . __FUNCTION__,
'field_image' => [
$first_image,
$second_image
],
]);
$this->drupalGetEntityPage($node);
$web_assert->responseContains('/styles/large/public/');
$web_assert->responseContains('/styles/thumbnail/public/');
}
/**
* Test formatter "image_with_mobile_alternative".
*
* @covers \Drupal\improvements\Plugin\Field\FieldFormatter\ImageWithMobileAlternativeFormatter
*/
public function testFieldFormatterImageWithMobileAlternative(): void {
$this->installModule('image', 'breakpoint', 'improvements_test');
$web_assert = $this->assertSession();
$this->drupalLoginAsRoot();
$this->createField(
entity_type: 'node',
entity_bundle: 'page',
field_name: 'field_image',
field_type: 'image',
field_label: 'Image',
widget_type: 'image_image',
formatter_type: 'image_with_mobile_alternative',
formatter_options: [
'settings' => [
'breakpoint_group' => 'improvements_test',
],
],
);
$this->createField('node', 'page', 'field_mobile_image', 'image', 'Mobile image');
$this->drupalGet('/admin/structure/types/manage/page/display');
$this->dontSeeErrorMessage();
$this->openEntityDisplayComponentSettings('field_image');
$web_assert->elementTextContains('css', '.plugin-name', 'Image with mobile alternative');
$web_assert->fieldExists('fields[field_image][settings_edit_form][settings][image_style]');
$web_assert->fieldExists('fields[field_image][settings_edit_form][settings][breakpoint_group]');
$web_assert->fieldExists('fields[field_image][settings_edit_form][settings][mobile_breakpoint]');
$web_assert->fieldExists('fields[field_image][settings_edit_form][settings][mobile_field]');
$web_assert->fieldExists('fields[field_image][settings_edit_form][settings][mobile_image_style]');
$this->submitForm([
'fields[field_image][settings_edit_form][settings][mobile_breakpoint]' => 'improvements_test.mobile',
'fields[field_image][settings_edit_form][settings][mobile_field]' => 'field_mobile_image',
], 'Save');
$this->dontSeeErrorMessage();
$web_assert->pageTextContains('Breakpoint group: improvements_test');
$web_assert->pageTextContains('Mobile breakpoint: improvements_test.mobile');
$web_assert->pageTextContains('Mobile field: field_mobile_image');
$first_image = $this->createFileEntity(['uri' => 'public://first-image.png']);
$second_image = $this->createFileEntity(['uri' => 'public://second-image.png']);
$node = $this->createNode([
'title' => 'Node for test ' . __FUNCTION__,
'field_image' => $first_image,
'field_mobile_image' => $second_image,
]);
$this->drupalGetEntityPage($node);
$web_assert->elementExists('css', 'picture');
$web_assert->elementExists('css', 'source[srcset="' . $second_image->createFileUrl() . '"][type="image/png"][media="(max-width: 640px)"]');
$web_assert->elementExists('css', 'img[src="' . $first_image->createFileUrl() . '"]');
}
/**
* Test formatter "human_readable_decimal_formatter".
*
* @covers \Drupal\improvements\Plugin\Field\FieldFormatter\HumanReadableDecimalFormatter
*/
public function testFieldFormatterHumanReadableDecimal(): void {
$field_decimal_storage_settings = [
'settings' => [
'precision' => 10,
'scale' => 2,
]
];
$this->createField(
entity_type: 'node',
entity_bundle: 'page',
field_name: 'field_decimal',
field_type: 'decimal',
field_label: 'Test decimal field',
storage_settings: $field_decimal_storage_settings,
formatter_type: 'human_readable_decimal_formatter',
);
$this->drupalLoginAsRoot();
$this->drupalGet('/admin/structure/types/manage/page/display');
$this->dontSeeErrorMessage();
$web_assert = $this->assertSession();
$web_assert->elementExists('css', 'select[name="fields[field_decimal][type]"] option[value="human_readable_decimal_formatter"][selected]');
$this->openEntityDisplayComponentSettings('field_decimal');
$web_assert->elementTextContains('css', '.plugin-name', 'Human-readable decimal formatter');
$web_assert->fieldExists('fields[field_decimal][settings_edit_form][settings][thousand_separator]');
$web_assert->fieldExists('fields[field_decimal][settings_edit_form][settings][prefix_suffix]');
$node = $this->createNode([
'title' => 'Node for test ' . __FUNCTION__,
'field_decimal' => 0.10,
]);
$this->drupalGetEntityPage($node);
$web_assert->elementTextContains('css', 'article', '0.1');
}
/**
* Test field formatter "string_list_formatter".
*
* @covers \Drupal\improvements\Plugin\Field\FieldFormatter\StringListFormatter
*/
public function testFieldFormatterStringList(): void {
$this->createField(
entity_type: 'node',
entity_bundle: 'page',
field_name: 'field_strings',
field_type: 'string',
field_label: 'Strings',
storage_settings: ['cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED],
formatter_type: 'string_list_formatter',
);
$this->drupalLoginAsRoot();
$this->drupalGet('/admin/structure/types/manage/page/display');
$this->dontSeeErrorMessage();
$web_assert = $this->assertSession();
$web_assert->fieldValueEquals('fields[field_strings][type]', 'string_list_formatter');
$this->openEntityDisplayComponentSettings('field_strings');
$web_assert->fieldExists('fields[field_strings][settings_edit_form][settings][list_class]');
$list_class = 'list-test-class';
$this->submitForm([
'fields[field_strings][settings_edit_form][settings][list_class]' => $list_class,
], 'Save');
$this->dontSeeErrorMessage();
$web_assert->pageTextContains('List css class: ' . $list_class);
$node = $this->createNode([
'title' => 'Node for ' . __FUNCTION__,
'field_strings' => [
'foo',
'bar',
],
]);
$this->drupalGetEntityPage($node);
$this->dontSeeErrorMessage();
$web_assert->elementTextContains('css', 'ul.' . $list_class . ' li:nth-child(1)', 'foo');
$web_assert->elementTextContains('css', 'ul.' . $list_class . ' li:nth-child(2)', 'bar');
}
/**
* Test field formatter "text_rows_list_formatter".
*
* @covers \Drupal\improvements\Plugin\Field\FieldFormatter\TextRowsListFormatter
*/
public function testFieldFormatterTextRowsList(): void {
$this->createField(
entity_type: 'node',
entity_bundle: 'page',
field_name: 'field_text',
field_type: 'string_long',
field_label: 'Text',
formatter_type: 'text_rows_list_formatter',
);
$this->drupalLoginAsRoot();
$this->drupalGet('/admin/structure/types/manage/page/display');
$this->dontSeeErrorMessage();
$web_assert = $this->assertSession();
$web_assert->fieldValueEquals('fields[field_text][type]', 'text_rows_list_formatter');
$this->openEntityDisplayComponentSettings('field_text');
$web_assert->fieldExists('fields[field_text][settings_edit_form][settings][list_class]');
$list_class = 'list-test-class';
$this->submitForm([
'fields[field_text][settings_edit_form][settings][list_class]' => $list_class,
], 'Save');
$this->dontSeeErrorMessage();
$web_assert->pageTextContains('List css class: ' . $list_class);
$node = $this->createNode([
'title' => 'Node for ' . __FUNCTION__,
'field_text' => "foo\nbar\nbaz",
]);
$this->drupalGetEntityPage($node);
$this->dontSeeErrorMessage();
$web_assert->elementTextContains('css', 'ul.' . $list_class . ' li:nth-child(1)', 'foo');
$web_assert->elementTextContains('css', 'ul.' . $list_class . ' li:nth-child(2)', 'bar');
}
/**
* Test field formatter "text_without_escaping".
*
* @covers \Drupal\improvements\Plugin\Field\FieldFormatter\TextWithoutEscapingFormatter
*/
public function testFieldFormatterTextWithoutEscaping(): void {
$this->createField(
entity_type: 'node',
entity_bundle: 'page',
field_name: 'field_string',
field_type: 'string',
field_label: 'String',
formatter_type: 'text_without_escaping',
);
$this->drupalLoginAsRoot();
$this->drupalGet('/admin/structure/types/manage/page/display');
$this->dontSeeErrorMessage();
$web_assert = $this->assertSession();
$web_assert->elementExists('css', 'select[name="fields[field_string][type]"] option[value="text_without_escaping"][selected]');
$node = $this->createNode([
'title' => 'Node for test ' . __FUNCTION__,
'field_string' => 'foo <b class="test-bar-class">bar</b> baz',
]);
$this->drupalGetEntityPage($node);
$this->dontSeeErrorMessage();
$web_assert->elementExists('css', '.test-bar-class');
}
}
