Update Composer, update everything
This commit is contained in:
parent
ea3e94409f
commit
dda5c284b6
19527 changed files with 1135420 additions and 351004 deletions
26
web/core/modules/field/tests/fixtures/update/drupal-8.remove_handler_submit_setting-2715589.php
vendored
Normal file
26
web/core/modules/field/tests/fixtures/update/drupal-8.remove_handler_submit_setting-2715589.php
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Provides necessary database additions for testing
|
||||
* field_post_update_remove_handler_submit_setting()
|
||||
*/
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
$config = unserialize($connection->select('config', 'c')
|
||||
->fields('c', ['data'])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'field.field.node.article.field_tags')
|
||||
->execute()
|
||||
->fetchField());
|
||||
|
||||
$config['settings']['handler_submit'] = 'Change handler';
|
||||
|
||||
$connection->update('config')
|
||||
->fields(['data' => serialize($config)])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'field.field.node.article.field_tags')
|
||||
->execute();
|
203
web/core/modules/field/tests/fixtures/update/drupal-8.update_deleted_field_definitions-2931436.php
vendored
Normal file
203
web/core/modules/field/tests/fixtures/update/drupal-8.update_deleted_field_definitions-2931436.php
vendored
Normal file
|
@ -0,0 +1,203 @@
|
|||
<?php
|
||||
// @codingStandardsIgnoreFile
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains SQL necessary to add a deleted field to the node entity type.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
// Add the field schema data and the deleted field definitions.
|
||||
$connection->insert('key_value')
|
||||
->fields([
|
||||
'collection',
|
||||
'name',
|
||||
'value',
|
||||
])
|
||||
->values([
|
||||
'collection' => 'entity.storage_schema.sql',
|
||||
'name' => 'node.field_schema_data.field_test',
|
||||
'value' => 'a:2:{s:16:"node__field_test";a:4:{s:11:"description";s:39:"Data storage for node field field_test.";s:6:"fields";a:7:{s:6:"bundle";a:5:{s:4:"type";s:13:"varchar_ascii";s:6:"length";i:128;s:8:"not null";b:1;s:7:"default";s:0:"";s:11:"description";s:88:"The field instance bundle to which this row belongs, used when deleting a field instance";}s:7:"deleted";a:5:{s:4:"type";s:3:"int";s:4:"size";s:4:"tiny";s:8:"not null";b:1;s:7:"default";i:0;s:11:"description";s:60:"A boolean indicating whether this data item has been deleted";}s:9:"entity_id";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:8:"not null";b:1;s:11:"description";s:38:"The entity id this data is attached to";}s:11:"revision_id";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:8:"not null";b:1;s:11:"description";s:47:"The entity revision id this data is attached to";}s:8:"langcode";a:5:{s:4:"type";s:13:"varchar_ascii";s:6:"length";i:32;s:8:"not null";b:1;s:7:"default";s:0:"";s:11:"description";s:37:"The language code for this data item.";}s:5:"delta";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:8:"not null";b:1;s:11:"description";s:67:"The sequence number for this data item, used for multi-value fields";}s:16:"field_test_value";a:3:{s:4:"type";s:7:"varchar";s:6:"length";i:254;s:8:"not null";b:1;}}s:11:"primary key";a:4:{i:0;s:9:"entity_id";i:1;s:7:"deleted";i:2;s:5:"delta";i:3;s:8:"langcode";}s:7:"indexes";a:2:{s:6:"bundle";a:1:{i:0;s:6:"bundle";}s:11:"revision_id";a:1:{i:0;s:11:"revision_id";}}}s:25:"node_revision__field_test";a:4:{s:11:"description";s:51:"Revision archive storage for node field field_test.";s:6:"fields";a:7:{s:6:"bundle";a:5:{s:4:"type";s:13:"varchar_ascii";s:6:"length";i:128;s:8:"not null";b:1;s:7:"default";s:0:"";s:11:"description";s:88:"The field instance bundle to which this row belongs, used when deleting a field instance";}s:7:"deleted";a:5:{s:4:"type";s:3:"int";s:4:"size";s:4:"tiny";s:8:"not null";b:1;s:7:"default";i:0;s:11:"description";s:60:"A boolean indicating whether this data item has been deleted";}s:9:"entity_id";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:8:"not null";b:1;s:11:"description";s:38:"The entity id this data is attached to";}s:11:"revision_id";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:8:"not null";b:1;s:11:"description";s:47:"The entity revision id this data is attached to";}s:8:"langcode";a:5:{s:4:"type";s:13:"varchar_ascii";s:6:"length";i:32;s:8:"not null";b:1;s:7:"default";s:0:"";s:11:"description";s:37:"The language code for this data item.";}s:5:"delta";a:4:{s:4:"type";s:3:"int";s:8:"unsigned";b:1;s:8:"not null";b:1;s:11:"description";s:67:"The sequence number for this data item, used for multi-value fields";}s:16:"field_test_value";a:3:{s:4:"type";s:7:"varchar";s:6:"length";i:254;s:8:"not null";b:1;}}s:11:"primary key";a:5:{i:0;s:9:"entity_id";i:1;s:11:"revision_id";i:2;s:7:"deleted";i:3;s:5:"delta";i:4;s:8:"langcode";}s:7:"indexes";a:2:{s:6:"bundle";a:1:{i:0;s:6:"bundle";}s:11:"revision_id";a:1:{i:0;s:11:"revision_id";}}}}',
|
||||
])
|
||||
->values([
|
||||
'collection' => 'state',
|
||||
'name' => 'field.field.deleted',
|
||||
'value' => 'a:1:{s:36:"5d0d9870-560b-46c4-b838-0dcded0502dd";a:18:{s:4:"uuid";s:36:"5d0d9870-560b-46c4-b838-0dcded0502dd";s:8:"langcode";s:2:"en";s:6:"status";b:1;s:12:"dependencies";a:1:{s:6:"config";a:2:{i:0;s:29:"field.storage.node.field_test";i:1;s:17:"node.type.article";}}s:2:"id";s:23:"node.article.field_test";s:10:"field_name";s:10:"field_test";s:11:"entity_type";s:4:"node";s:6:"bundle";s:7:"article";s:5:"label";s:4:"Test";s:11:"description";s:0:"";s:8:"required";b:0;s:12:"translatable";b:0;s:13:"default_value";a:0:{}s:22:"default_value_callback";s:0:"";s:8:"settings";a:0:{}s:10:"field_type";s:5:"email";s:7:"deleted";b:1;s:18:"field_storage_uuid";s:36:"ce93d7c2-1da7-4a2c-9e6d-b4925e3b129f";}}',
|
||||
])
|
||||
->values([
|
||||
'collection' => 'state',
|
||||
'name' => 'field.storage.deleted',
|
||||
'value' => 'a:1:{s:36:"ce93d7c2-1da7-4a2c-9e6d-b4925e3b129f";a:18:{s:4:"uuid";s:36:"ce93d7c2-1da7-4a2c-9e6d-b4925e3b129f";s:8:"langcode";s:2:"en";s:6:"status";b:1;s:12:"dependencies";a:1:{s:6:"module";a:1:{i:0;s:4:"node";}}s:2:"id";s:15:"node.field_test";s:10:"field_name";s:10:"field_test";s:11:"entity_type";s:4:"node";s:4:"type";s:5:"email";s:8:"settings";a:0:{}s:6:"module";s:4:"core";s:6:"locked";b:0;s:11:"cardinality";i:1;s:12:"translatable";b:1;s:7:"indexes";a:0:{}s:22:"persist_with_no_fields";b:0;s:14:"custom_storage";b:0;s:7:"deleted";b:1;s:7:"bundles";a:0:{}}}',
|
||||
])
|
||||
->execute();
|
||||
|
||||
// Create and populate the deleted field tables.
|
||||
// @see \Drupal\Core\Entity\Sql\DefaultTableMapping::getDedicatedDataTableName()
|
||||
$deleted_field_data_table_name = "field_deleted_data_" . substr(hash('sha256', 'ce93d7c2-1da7-4a2c-9e6d-b4925e3b129f'), 0, 10);
|
||||
$connection->schema()->createTable($deleted_field_data_table_name, array(
|
||||
'fields' => array(
|
||||
'bundle' => array(
|
||||
'type' => 'varchar_ascii',
|
||||
'not null' => TRUE,
|
||||
'length' => '128',
|
||||
'default' => '',
|
||||
),
|
||||
'deleted' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'size' => 'tiny',
|
||||
'default' => '0',
|
||||
),
|
||||
'entity_id' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'size' => 'normal',
|
||||
'unsigned' => TRUE,
|
||||
),
|
||||
'revision_id' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'size' => 'normal',
|
||||
'unsigned' => TRUE,
|
||||
),
|
||||
'langcode' => array(
|
||||
'type' => 'varchar_ascii',
|
||||
'not null' => TRUE,
|
||||
'length' => '32',
|
||||
'default' => '',
|
||||
),
|
||||
'delta' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'size' => 'normal',
|
||||
'unsigned' => TRUE,
|
||||
),
|
||||
'field_test_value' => array(
|
||||
'type' => 'varchar',
|
||||
'not null' => TRUE,
|
||||
'length' => '254',
|
||||
),
|
||||
),
|
||||
'primary key' => array(
|
||||
'entity_id',
|
||||
'deleted',
|
||||
'delta',
|
||||
'langcode',
|
||||
),
|
||||
'indexes' => array(
|
||||
'bundle' => array(
|
||||
'bundle',
|
||||
),
|
||||
'revision_id' => array(
|
||||
'revision_id',
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
$connection->insert($deleted_field_data_table_name)
|
||||
->fields(array(
|
||||
'bundle',
|
||||
'deleted',
|
||||
'entity_id',
|
||||
'revision_id',
|
||||
'langcode',
|
||||
'delta',
|
||||
'field_test_value',
|
||||
))
|
||||
->values(array(
|
||||
'bundle' => 'article',
|
||||
'deleted' => '1',
|
||||
'entity_id' => '1',
|
||||
'revision_id' => '1',
|
||||
'langcode' => 'en',
|
||||
'delta' => '0',
|
||||
'field_test_value' => 'test@test.com',
|
||||
))
|
||||
->execute();
|
||||
|
||||
// @see \Drupal\Core\Entity\Sql\DefaultTableMapping::getDedicatedDataTableName()
|
||||
$deleted_field_revision_table_name = "field_deleted_revision_" . substr(hash('sha256', 'ce93d7c2-1da7-4a2c-9e6d-b4925e3b129f'), 0, 10);
|
||||
$connection->schema()->createTable($deleted_field_revision_table_name, array(
|
||||
'fields' => array(
|
||||
'bundle' => array(
|
||||
'type' => 'varchar_ascii',
|
||||
'not null' => TRUE,
|
||||
'length' => '128',
|
||||
'default' => '',
|
||||
),
|
||||
'deleted' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'size' => 'tiny',
|
||||
'default' => '0',
|
||||
),
|
||||
'entity_id' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'size' => 'normal',
|
||||
'unsigned' => TRUE,
|
||||
),
|
||||
'revision_id' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'size' => 'normal',
|
||||
'unsigned' => TRUE,
|
||||
),
|
||||
'langcode' => array(
|
||||
'type' => 'varchar_ascii',
|
||||
'not null' => TRUE,
|
||||
'length' => '32',
|
||||
'default' => '',
|
||||
),
|
||||
'delta' => array(
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
'size' => 'normal',
|
||||
'unsigned' => TRUE,
|
||||
),
|
||||
'field_test_value' => array(
|
||||
'type' => 'varchar',
|
||||
'not null' => TRUE,
|
||||
'length' => '254',
|
||||
),
|
||||
),
|
||||
'primary key' => array(
|
||||
'entity_id',
|
||||
'revision_id',
|
||||
'deleted',
|
||||
'delta',
|
||||
'langcode',
|
||||
),
|
||||
'indexes' => array(
|
||||
'bundle' => array(
|
||||
'bundle',
|
||||
),
|
||||
'revision_id' => array(
|
||||
'revision_id',
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
$connection->insert($deleted_field_revision_table_name)
|
||||
->fields(array(
|
||||
'bundle',
|
||||
'deleted',
|
||||
'entity_id',
|
||||
'revision_id',
|
||||
'langcode',
|
||||
'delta',
|
||||
'field_test_value',
|
||||
))
|
||||
->values(array(
|
||||
'bundle' => 'article',
|
||||
'deleted' => '1',
|
||||
'entity_id' => '1',
|
||||
'revision_id' => '1',
|
||||
'langcode' => 'en',
|
||||
'delta' => '0',
|
||||
'field_test_value' => 'test@test.com',
|
||||
))
|
||||
->execute();
|
|
@ -66,7 +66,7 @@ $connection->update('key_value')
|
|||
->condition('collection', 'entity.definitions.installed')
|
||||
->condition('name', 'node.field_storage_definitions')
|
||||
->fields([
|
||||
'value' => serialize($installed)
|
||||
'value' => serialize($installed),
|
||||
])
|
||||
->execute();
|
||||
|
||||
|
|
|
@ -5,4 +5,4 @@ core: 8.x
|
|||
package: Testing
|
||||
version: VERSION
|
||||
dependencies:
|
||||
- text
|
||||
- drupal:text
|
||||
|
|
|
@ -55,6 +55,18 @@ field.widget.settings.test_field_widget_multiple:
|
|||
type: string
|
||||
label: 'Test setting'
|
||||
|
||||
field.widget.settings.test_field_widget_multiple_single_value:
|
||||
type: mapping
|
||||
label: 'Test multiple field widget settings: single values'
|
||||
mapping:
|
||||
test_widget_setting_multiple:
|
||||
type: string
|
||||
label: 'Test setting'
|
||||
|
||||
field.widget.settings.test_field_widget_multilingual:
|
||||
type: field.widget.settings.test_field_widget
|
||||
label: 'Test multiple field widget settings: multilingual'
|
||||
|
||||
field.widget.third_party.color:
|
||||
type: mapping
|
||||
label: 'Field test entity display color module third party settings'
|
||||
|
|
|
@ -19,6 +19,13 @@ use Drupal\field\FieldStorageConfigInterface;
|
|||
function field_test_field_widget_info_alter(&$info) {
|
||||
$info['test_field_widget_multiple']['field_types'][] = 'test_field';
|
||||
$info['test_field_widget_multiple']['field_types'][] = 'test_field_with_preconfigured_options';
|
||||
// Add extra widget when needed for tests.
|
||||
// @see \Drupal\field\Tests\FormTest::widgetAlterTest().
|
||||
if ($alter_info = \Drupal::state()->get("field_test.widget_alter_test")) {
|
||||
if ($alter_info['widget'] === 'test_field_widget_multiple_single_value') {
|
||||
$info['test_field_widget_multiple_single_value']['field_types'][] = 'test_field';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,4 +5,4 @@ core: 8.x
|
|||
package: Testing
|
||||
version: VERSION
|
||||
dependencies:
|
||||
- entity_test
|
||||
- drupal:entity_test
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element;
|
||||
use Drupal\field\FieldStorageConfigInterface;
|
||||
|
||||
require_once __DIR__ . '/field_test.entity.inc';
|
||||
|
@ -100,20 +101,54 @@ function field_test_entity_display_build_alter(&$output, $context) {
|
|||
* Implements hook_field_widget_form_alter().
|
||||
*/
|
||||
function field_test_field_widget_form_alter(&$element, FormStateInterface $form_state, $context) {
|
||||
$field_definition = $context['items']->getFieldDefinition();
|
||||
switch ($field_definition->getName()) {
|
||||
case 'alter_test_text':
|
||||
drupal_set_message('Field size: ' . $context['widget']->getSetting('size'));
|
||||
break;
|
||||
|
||||
case 'alter_test_options':
|
||||
drupal_set_message('Widget type: ' . $context['widget']->getPluginId());
|
||||
break;
|
||||
}
|
||||
// Set a message if this is for the form displayed to set default value for
|
||||
// the field.
|
||||
if ($context['default']) {
|
||||
drupal_set_message('From hook_field_widget_form_alter(): Default form is true.');
|
||||
\Drupal::messenger()
|
||||
->addStatus('From hook_field_widget_form_alter(): Default form is true.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_widget_multivalue_form_alter().
|
||||
*/
|
||||
function field_test_field_widget_multivalue_form_alter(array &$elements, FormStateInterface $form_state, array $context) {
|
||||
_field_test_alter_widget("hook_field_widget_multivalue_form_alter", $elements, $form_state, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_widget_multivalue_WIDGET_TYPE_form_alter().
|
||||
*/
|
||||
function field_test_field_widget_multivalue_test_field_widget_multiple_form_alter(array &$elements, FormStateInterface $form_state, array $context) {
|
||||
_field_test_alter_widget("hook_field_widget_multivalue_WIDGET_TYPE_form_alter", $elements, $form_state, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_widget_multivalue_WIDGET_TYPE_form_alter().
|
||||
*/
|
||||
function field_test_field_widget_multivalue_test_field_widget_multiple_single_value_form_alter(array &$elements, FormStateInterface $form_state, array $context) {
|
||||
_field_test_alter_widget("hook_field_widget_multivalue_WIDGET_TYPE_form_alter", $elements, $form_state, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up alterations for widget alter tests.
|
||||
*
|
||||
* @see \Drupal\field\Tests\FormTest::widgetAlterTest()
|
||||
*/
|
||||
function _field_test_alter_widget($hook, array &$elements, FormStateInterface $form_state, array $context) {
|
||||
|
||||
// Set a message if this is for the form displayed to set default value for
|
||||
// the field.
|
||||
if ($context['default']) {
|
||||
\Drupal::messenger()->addStatus("From $hook(): Default form is true.");
|
||||
}
|
||||
$alter_info = \Drupal::state()->get("field_test.widget_alter_test");
|
||||
$name = $context['items']->getFieldDefinition()->getName();
|
||||
if (!empty($alter_info) && $hook === $alter_info['hook'] && $name === $alter_info['field_name']) {
|
||||
$elements['#prefix'] = "From $hook(): prefix on $name parent element.";
|
||||
foreach (Element::children($elements) as $delta => $element) {
|
||||
$elements[$delta]['#suffix'] = "From $hook(): suffix on $name child element.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,7 +163,6 @@ function field_test_query_efq_table_prefixing_test_alter(&$query) {
|
|||
$query->join('entity_test', 'et2', '%alias.id = entity_test.id');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements hook_query_TAG_alter() for tag 'efq_metadata_test'.
|
||||
*
|
||||
|
@ -151,15 +185,18 @@ function field_test_entity_extra_field_info_alter(&$info) {
|
|||
* Implements hook_entity_bundle_field_info_alter().
|
||||
*/
|
||||
function field_test_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
|
||||
if (($field_name = \Drupal::state()->get('field_test_set_constraint', FALSE)) && $entity_type->id() == 'entity_test' && $bundle == 'entity_test' && !empty($fields[$field_name])) {
|
||||
if (($field_name = \Drupal::state()->get('field_test_constraint', FALSE)) && $entity_type->id() == 'entity_test' && $bundle == 'entity_test' && !empty($fields[$field_name])) {
|
||||
// Set a property constraint using
|
||||
// \Drupal\Core\Field\FieldConfigInterface::setPropertyConstraints().
|
||||
$fields[$field_name]->setPropertyConstraints('value', [
|
||||
'Range' => [
|
||||
'min' => 0,
|
||||
'max' => 32,
|
||||
'TestField' => [
|
||||
'value' => -2,
|
||||
'message' => t('%name does not accept the value @value.', ['%name' => $field_name, '@value' => -2]),
|
||||
],
|
||||
]);
|
||||
}
|
||||
if (($field_name = \Drupal::state()->get('field_test_add_constraint', FALSE)) && $entity_type->id() == 'entity_test' && $bundle == 'entity_test' && !empty($fields[$field_name])) {
|
||||
|
||||
// Add a property constraint using
|
||||
// \Drupal\Core\Field\FieldConfigInterface::addPropertyConstraints().
|
||||
$fields[$field_name]->addPropertyConstraints('value', [
|
||||
'Range' => [
|
||||
'min' => 0,
|
||||
|
@ -168,3 +205,14 @@ function field_test_entity_bundle_field_info_alter(&$fields, EntityTypeInterface
|
|||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_ui_preconfigured_options_alter().
|
||||
*/
|
||||
function field_test_field_ui_preconfigured_options_alter(array &$options, $field_type) {
|
||||
if ($field_type === 'test_field_with_preconfigured_options') {
|
||||
$options['custom_options']['entity_view_display']['settings'] = [
|
||||
'test_formatter_setting_multiple' => 'altered dummy test string',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test;
|
||||
|
||||
/**
|
||||
* Helper class for \Drupal\Tests\field\Functional\FieldDefaultValueCallbackTest.
|
||||
*/
|
||||
class FieldDefaultValueCallbackProvider {
|
||||
|
||||
/**
|
||||
* Helper callback calculating a default value.
|
||||
*/
|
||||
public static function calculateDefaultValue() {
|
||||
return [['value' => 'Calculated default value']];
|
||||
}
|
||||
|
||||
}
|
|
@ -10,6 +10,8 @@ use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
|||
|
||||
/**
|
||||
* Provides a form for field_test routes.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class NestedEntityTestForm extends FormBase {
|
||||
|
||||
|
@ -40,14 +42,14 @@ class NestedEntityTestForm extends FormBase {
|
|||
'#tree' => TRUE,
|
||||
'#parents' => ['entity_2'],
|
||||
'#weight' => 50,
|
||||
'#attributes' => ['class' => ['entity-2']]
|
||||
'#attributes' => ['class' => ['entity-2']],
|
||||
];
|
||||
|
||||
$form_display_2->buildForm($entity_2, $form['entity_2'], $form_state);
|
||||
|
||||
if ($entity_2 instanceof EntityChangedInterface) {
|
||||
// Changed must be sent to the client, for later overwrite error checking.
|
||||
// @see Drupal\field\Tests\NestedFormTest::testNestedEntityFormEntityLevelValidation()
|
||||
// @see \Drupal\Tests\field\Functional\NestedFormTest::testNestedEntityFormEntityLevelValidation()
|
||||
$form['entity_2']['changed'] = [
|
||||
'#type' => 'hidden',
|
||||
'#default_value' => $entity_1->getChangedTime(),
|
||||
|
@ -80,7 +82,7 @@ class NestedEntityTestForm extends FormBase {
|
|||
// Extract the values of fields that are not rendered through widgets, by
|
||||
// simply copying from top-level form values. This leaves the fields that
|
||||
// are not being edited within this form untouched.
|
||||
// @see Drupal\field\Tests\NestedFormTest::testNestedEntityFormEntityLevelValidation()
|
||||
// @see \Drupal\Tests\field\Functional\NestedFormTest::testNestedEntityFormEntityLevelValidation()
|
||||
foreach ($form_state->getValues()['entity_2'] as $name => $values) {
|
||||
if ($entity_2->hasField($name) && !isset($extracted[$name])) {
|
||||
$entity_2->set($name, $values);
|
||||
|
@ -90,7 +92,7 @@ class NestedEntityTestForm extends FormBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc]
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
/** @var \Drupal\Core\Entity\EntityInterface $entity_1 */
|
||||
|
@ -101,7 +103,7 @@ class NestedEntityTestForm extends FormBase {
|
|||
$entity_2 = $form_state->get('entity_2');
|
||||
$entity_2->save();
|
||||
|
||||
drupal_set_message($this->t('test_entities @id_1 and @id_2 have been updated.', ['@id_1' => $entity_1->id(), '@id_2' => $entity_2->id()]));
|
||||
$this->messenger()->addStatus($this->t('test_entities @id_1 and @id_2 have been updated.', ['@id_1' => $entity_1->id(), '@id_2' => $entity_2->id()]));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FormatterBase;
|
||||
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'field_test_applicable' formatter.
|
||||
*
|
||||
|
|
|
@ -120,7 +120,7 @@ class TestItem extends FieldItemBase {
|
|||
'TestField' => [
|
||||
'value' => -1,
|
||||
'message' => t('%name does not accept the value @value.', ['%name' => $this->getFieldDefinition()->getLabel(), '@value' => -1]),
|
||||
]
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ namespace Drupal\field_test\Plugin\Field\FieldType;
|
|||
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Defines the 'test_field_with_dependencies' entity field item.
|
||||
*
|
||||
|
|
|
@ -29,7 +29,7 @@ class TestItemWithPreconfiguredOptions extends TestItem implements Preconfigured
|
|||
'field_storage_config' => [
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
'settings' => [
|
||||
'test_field_storage_setting' => 'preconfigured_storage_setting'
|
||||
'test_field_storage_setting' => 'preconfigured_storage_setting',
|
||||
],
|
||||
],
|
||||
'field_config' => [
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldWidget;
|
||||
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'test_field_widget_multilingual' widget.
|
||||
*
|
||||
* @FieldWidget(
|
||||
* id = "test_field_widget_multilingual",
|
||||
* label = @Translation("Test widget - multilingual"),
|
||||
* field_types = {
|
||||
* "test_field",
|
||||
* },
|
||||
* )
|
||||
*/
|
||||
class TestFieldWidgetMultilingual extends TestFieldWidget {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function form(FieldItemListInterface $items, array &$form, FormStateInterface $form_state, $get_delta = NULL) {
|
||||
$elements = parent::form($items, $form, $form_state, $get_delta);
|
||||
$elements['#multilingual'] = TRUE;
|
||||
return $elements;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\field_test\Plugin\Field\FieldWidget;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'test_field_widget_multiple' widget.
|
||||
*
|
||||
* The 'field_types' entry is left empty, and is populated through
|
||||
* hook_field_widget_info_alter().
|
||||
*
|
||||
* @see field_test_field_widget_info_alter()
|
||||
*
|
||||
* @FieldWidget(
|
||||
* id = "test_field_widget_multiple_single_value",
|
||||
* label = @Translation("Test widget - multiple - single value"),
|
||||
* multiple_values = FALSE,
|
||||
* weight = 10
|
||||
* )
|
||||
*/
|
||||
class TestFieldWidgetMultipleSingleValues extends TestFieldWidgetMultiple {
|
||||
|
||||
}
|
|
@ -5,4 +5,4 @@ core: 8.x
|
|||
package: Testing
|
||||
version: VERSION
|
||||
dependencies:
|
||||
- field
|
||||
- drupal:field
|
||||
|
|
|
@ -5,4 +5,4 @@ package: Testing
|
|||
version: VERSION
|
||||
core: 8.x
|
||||
dependencies:
|
||||
- views
|
||||
- drupal:views
|
||||
|
|
|
@ -5,5 +5,5 @@ core: 8.x
|
|||
package: Testing
|
||||
version: VERSION
|
||||
dependencies:
|
||||
- entity_test
|
||||
- field_test
|
||||
- drupal:entity_test
|
||||
- drupal:field_test
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- field.storage.entity_test.timestamp
|
||||
id: entity_test.entity_test.timestamp
|
||||
field_name: timestamp
|
||||
entity_type: entity_test
|
||||
bundle: entity_test
|
||||
label: 'Time stamp'
|
||||
description: ''
|
||||
required: false
|
||||
translatable: false
|
||||
default_value:
|
||||
-
|
||||
value: 1514847537
|
||||
default_value_callback: ''
|
||||
settings: { }
|
||||
field_type: timestamp
|
|
@ -0,0 +1,17 @@
|
|||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- entity_test
|
||||
id: node.timestamp
|
||||
field_name: timestamp
|
||||
entity_type: entity_test
|
||||
type: timestamp
|
||||
settings: { }
|
||||
module: core
|
||||
locked: false
|
||||
cardinality: 1
|
||||
translatable: true
|
||||
indexes: { }
|
||||
persist_with_no_fields: false
|
||||
custom_storage: false
|
|
@ -0,0 +1,9 @@
|
|||
name: 'Field Timestamp Test'
|
||||
type: module
|
||||
description: 'Support module for the Timestamp field item test.'
|
||||
core: 8.x
|
||||
package: Testing
|
||||
version: VERSION
|
||||
dependencies:
|
||||
- drupal:entity_test
|
||||
- drupal:field
|
|
@ -0,0 +1,242 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Boolean;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests boolean field functionality.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class BooleanFieldTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = [
|
||||
'entity_test',
|
||||
'field_ui',
|
||||
'options',
|
||||
'field_test_boolean_access_denied',
|
||||
];
|
||||
|
||||
/**
|
||||
* A field to use in this test class.
|
||||
*
|
||||
* @var \Drupal\field\Entity\FieldStorageConfig
|
||||
*/
|
||||
protected $fieldStorage;
|
||||
|
||||
/**
|
||||
* The field used in this test class.
|
||||
*
|
||||
* @var \Drupal\field\Entity\FieldConfig
|
||||
*/
|
||||
protected $field;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->drupalLogin($this->drupalCreateUser([
|
||||
'view test entity',
|
||||
'administer entity_test content',
|
||||
'administer entity_test form display',
|
||||
'administer entity_test fields',
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests boolean field.
|
||||
*/
|
||||
public function testBooleanField() {
|
||||
$on = $this->randomMachineName();
|
||||
$off = $this->randomMachineName();
|
||||
$label = $this->randomMachineName();
|
||||
|
||||
// Create a field with settings to validate.
|
||||
$field_name = mb_strtolower($this->randomMachineName());
|
||||
$this->fieldStorage = FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'boolean',
|
||||
]);
|
||||
$this->fieldStorage->save();
|
||||
$this->field = FieldConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
'label' => $label,
|
||||
'required' => TRUE,
|
||||
'settings' => [
|
||||
'on_label' => $on,
|
||||
'off_label' => $off,
|
||||
],
|
||||
]);
|
||||
$this->field->save();
|
||||
|
||||
// Create a form display for the default form mode.
|
||||
entity_get_form_display('entity_test', 'entity_test', 'default')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'boolean_checkbox',
|
||||
])
|
||||
->save();
|
||||
// Create a display for the full view mode.
|
||||
entity_get_display('entity_test', 'entity_test', 'full')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'boolean',
|
||||
])
|
||||
->save();
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet('entity_test/add');
|
||||
$this->assertFieldByName("{$field_name}[value]", '', 'Widget found.');
|
||||
$this->assertText($this->field->label(), 'Uses field label by default.');
|
||||
$this->assertNoRaw($on, 'Does not use the "On" label.');
|
||||
|
||||
// Submit and ensure it is accepted.
|
||||
$edit = [
|
||||
"{$field_name}[value]" => 1,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', ['@id' => $id]));
|
||||
|
||||
// Verify that boolean value is displayed.
|
||||
$entity = EntityTest::load($id);
|
||||
$this->drupalGet($entity->toUrl());
|
||||
$this->assertRaw('<div class="field__item">' . $on . '</div>');
|
||||
|
||||
// Test with "On" label option.
|
||||
entity_get_form_display('entity_test', 'entity_test', 'default')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'boolean_checkbox',
|
||||
'settings' => [
|
||||
'display_label' => FALSE,
|
||||
],
|
||||
])
|
||||
->save();
|
||||
|
||||
$this->drupalGet('entity_test/add');
|
||||
$this->assertFieldByName("{$field_name}[value]", '', 'Widget found.');
|
||||
$this->assertRaw($on);
|
||||
$this->assertNoText($this->field->label());
|
||||
|
||||
// Test if we can change the on label.
|
||||
$on = $this->randomMachineName();
|
||||
$edit = [
|
||||
'settings[on_label]' => $on,
|
||||
];
|
||||
$this->drupalPostForm('entity_test/structure/entity_test/fields/entity_test.entity_test.' . $field_name, $edit, t('Save settings'));
|
||||
// Check if we see the updated labels in the creation form.
|
||||
$this->drupalGet('entity_test/add');
|
||||
$this->assertRaw($on);
|
||||
|
||||
// Go to the form display page and check if the default settings works as
|
||||
// expected.
|
||||
$fieldEditUrl = 'entity_test/structure/entity_test/form-display';
|
||||
$this->drupalGet($fieldEditUrl);
|
||||
|
||||
// Click on the widget settings button to open the widget settings form.
|
||||
$this->drupalPostForm(NULL, [], $field_name . "_settings_edit");
|
||||
|
||||
$this->assertText(
|
||||
'Use field label instead of the "On" label as the label.',
|
||||
t('Display setting checkbox available.')
|
||||
);
|
||||
|
||||
// Enable setting.
|
||||
$edit = ['fields[' . $field_name . '][settings_edit_form][settings][display_label]' => 1];
|
||||
$this->drupalPostForm(NULL, $edit, $field_name . "_plugin_settings_update");
|
||||
$this->drupalPostForm(NULL, NULL, 'Save');
|
||||
|
||||
// Go again to the form display page and check if the setting
|
||||
// is stored and has the expected effect.
|
||||
$this->drupalGet($fieldEditUrl);
|
||||
$this->assertText('Use field label: Yes', 'Checking the display settings checkbox updated the value.');
|
||||
|
||||
$this->drupalPostForm(NULL, [], $field_name . "_settings_edit");
|
||||
$this->assertText(
|
||||
'Use field label instead of the "On" label as the label.',
|
||||
t('Display setting checkbox is available')
|
||||
);
|
||||
$this->getSession()->getPage()->hasCheckedField('fields[' . $field_name . '][settings_edit_form][settings][display_label]');
|
||||
|
||||
// Test the boolean field settings.
|
||||
$this->drupalGet('entity_test/structure/entity_test/fields/entity_test.entity_test.' . $field_name);
|
||||
$this->assertFieldById('edit-settings-on-label', $on);
|
||||
$this->assertFieldById('edit-settings-off-label', $off);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test field access.
|
||||
*/
|
||||
public function testFormAccess() {
|
||||
$on = 'boolean_on';
|
||||
$off = 'boolean_off';
|
||||
$label = 'boolean_label';
|
||||
$field_name = 'boolean_name';
|
||||
$this->fieldStorage = FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'boolean',
|
||||
]);
|
||||
$this->fieldStorage->save();
|
||||
$this->field = FieldConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
'label' => $label,
|
||||
'settings' => [
|
||||
'on_label' => $on,
|
||||
'off_label' => $off,
|
||||
],
|
||||
]);
|
||||
$this->field->save();
|
||||
|
||||
// Create a form display for the default form mode.
|
||||
entity_get_form_display('entity_test', 'entity_test', 'default')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'boolean_checkbox',
|
||||
])
|
||||
->save();
|
||||
|
||||
// Create a display for the full view mode.
|
||||
entity_get_display('entity_test', 'entity_test', 'full')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'boolean',
|
||||
])
|
||||
->save();
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet('entity_test/add');
|
||||
$this->assertFieldByName("{$field_name}[value]");
|
||||
|
||||
// Should be posted OK.
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', ['@id' => $id]));
|
||||
|
||||
// Tell the test module to disable access to the field.
|
||||
\Drupal::state()->set('field.test_boolean_field_access_field', $field_name);
|
||||
$this->drupalGet('entity_test/add');
|
||||
// Field should not be there anymore.
|
||||
$this->assertNoFieldByName("{$field_name}[value]");
|
||||
// Should still be able to post the form.
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', ['@id' => $id]));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Boolean;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the Boolean field formatter settings.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class BooleanFormatterSettingsTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['field', 'field_ui', 'text', 'node', 'user'];
|
||||
|
||||
/**
|
||||
* The name of the entity bundle that is created in the test.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $bundle;
|
||||
|
||||
/**
|
||||
* The name of the Boolean field to use for testing.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldName;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create a content type. Use Node because it has Field UI pages that work.
|
||||
$type_name = mb_strtolower($this->randomMachineName(8)) . '_test';
|
||||
$type = $this->drupalCreateContentType(['name' => $type_name, 'type' => $type_name]);
|
||||
$this->bundle = $type->id();
|
||||
|
||||
$admin_user = $this->drupalCreateUser(['access content', 'administer content types', 'administer node fields', 'administer node display', 'bypass node access', 'administer nodes']);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
$this->fieldName = mb_strtolower($this->randomMachineName(8));
|
||||
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => $this->fieldName,
|
||||
'entity_type' => 'node',
|
||||
'type' => 'boolean',
|
||||
]);
|
||||
$field_storage->save();
|
||||
|
||||
$instance = FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => $this->bundle,
|
||||
'label' => $this->randomMachineName(),
|
||||
]);
|
||||
$instance->save();
|
||||
|
||||
$display = entity_get_display('node', $this->bundle, 'default')
|
||||
->setComponent($this->fieldName, [
|
||||
'type' => 'boolean',
|
||||
'settings' => [],
|
||||
]);
|
||||
$display->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the formatter settings page for the Boolean formatter.
|
||||
*/
|
||||
public function testBooleanFormatterSettings() {
|
||||
// List the options we expect to see on the settings form. Omit the one
|
||||
// with the Unicode check/x characters, which does not appear to work
|
||||
// well in WebTestBase.
|
||||
$options = [
|
||||
'Yes / No',
|
||||
'True / False',
|
||||
'On / Off',
|
||||
'Enabled / Disabled',
|
||||
'1 / 0',
|
||||
'Custom',
|
||||
];
|
||||
|
||||
// For several different values of the field settings, test that the
|
||||
// options, including default, are shown correctly.
|
||||
$settings = [
|
||||
['Yes', 'No'],
|
||||
['On', 'Off'],
|
||||
['TRUE', 'FALSE'],
|
||||
];
|
||||
|
||||
$assert_session = $this->assertSession();
|
||||
foreach ($settings as $values) {
|
||||
// Set up the field settings.
|
||||
$this->drupalGet('admin/structure/types/manage/' . $this->bundle . '/fields/node.' . $this->bundle . '.' . $this->fieldName);
|
||||
$this->drupalPostForm(NULL, [
|
||||
'settings[on_label]' => $values[0],
|
||||
'settings[off_label]' => $values[1],
|
||||
], 'Save settings');
|
||||
|
||||
// Open the Manage Display page and trigger the field settings form.
|
||||
$this->drupalGet('admin/structure/types/manage/' . $this->bundle . '/display');
|
||||
$this->drupalPostForm(NULL, [], $this->fieldName . '_settings_edit');
|
||||
|
||||
// Test that the settings options are present in the correct format.
|
||||
foreach ($options as $string) {
|
||||
$assert_session->pageTextContains($string);
|
||||
}
|
||||
$assert_session->pageTextContains(t('Field settings (@on_label / @off_label)', ['@on_label' => $values[0], '@off_label' => $values[1]]));
|
||||
|
||||
// Test that the settings summary are present in the correct format.
|
||||
$this->drupalGet('admin/structure/types/manage/' . $this->bundle . '/display');
|
||||
$result = $this->xpath('//div[contains(@class, :class) and contains(text(), :text)]', [
|
||||
':class' => 'field-plugin-summary',
|
||||
':text' => (string) t('Display: @true_label / @false_label', ['@true_label' => $values[0], '@false_label' => $values[1]]),
|
||||
]);
|
||||
$this->assertEqual(count($result), 1, "Boolean formatter settings summary exist.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Email;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests email field functionality.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class EmailFieldTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node', 'entity_test', 'field_ui'];
|
||||
|
||||
/**
|
||||
* A field storage to use in this test class.
|
||||
*
|
||||
* @var \Drupal\field\Entity\FieldStorageConfig
|
||||
*/
|
||||
protected $fieldStorage;
|
||||
|
||||
/**
|
||||
* The field used in this test class.
|
||||
*
|
||||
* @var \Drupal\field\Entity\FieldConfig
|
||||
*/
|
||||
protected $field;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->drupalLogin($this->drupalCreateUser([
|
||||
'view test entity',
|
||||
'administer entity_test content',
|
||||
'administer content types',
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests email field.
|
||||
*/
|
||||
public function testEmailField() {
|
||||
// Create a field with settings to validate.
|
||||
$field_name = mb_strtolower($this->randomMachineName());
|
||||
$this->fieldStorage = FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'email',
|
||||
]);
|
||||
$this->fieldStorage->save();
|
||||
$this->field = FieldConfig::create([
|
||||
'field_storage' => $this->fieldStorage,
|
||||
'bundle' => 'entity_test',
|
||||
]);
|
||||
$this->field->save();
|
||||
|
||||
// Create a form display for the default form mode.
|
||||
entity_get_form_display('entity_test', 'entity_test', 'default')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'email_default',
|
||||
'settings' => [
|
||||
'placeholder' => 'example@example.com',
|
||||
],
|
||||
])
|
||||
->save();
|
||||
// Create a display for the full view mode.
|
||||
entity_get_display('entity_test', 'entity_test', 'full')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'email_mailto',
|
||||
])
|
||||
->save();
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet('entity_test/add');
|
||||
$this->assertFieldByName("{$field_name}[0][value]", '', 'Widget found.');
|
||||
$this->assertRaw('placeholder="example@example.com"');
|
||||
|
||||
// Submit a valid email address and ensure it is accepted.
|
||||
$value = 'test@example.com';
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $value,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', ['@id' => $id]));
|
||||
$this->assertRaw($value);
|
||||
|
||||
// Verify that a mailto link is displayed.
|
||||
$entity = EntityTest::load($id);
|
||||
$display = entity_get_display($entity->getEntityTypeId(), $entity->bundle(), 'full');
|
||||
$content = $display->build($entity);
|
||||
$rendered_content = (string) \Drupal::service('renderer')->renderRoot($content);
|
||||
$this->assertContains('href="mailto:test@example.com"', $rendered_content);
|
||||
}
|
||||
|
||||
}
|
|
@ -2,11 +2,10 @@
|
|||
|
||||
namespace Drupal\Tests\field\Functional\EntityReference;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
@ -145,7 +144,7 @@ class EntityReferenceAutoCreateTest extends BrowserTestBase {
|
|||
/** @var \Drupal\taxonomy\Entity\Vocabulary[] $vocabularies */
|
||||
$vocabularies = [];
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$vid = Unicode::strtolower($this->randomMachineName());
|
||||
$vid = mb_strtolower($this->randomMachineName());
|
||||
$vocabularies[$i] = Vocabulary::create([
|
||||
'name' => $this->randomMachineName(),
|
||||
'vid' => $vid,
|
||||
|
@ -156,7 +155,7 @@ class EntityReferenceAutoCreateTest extends BrowserTestBase {
|
|||
// Create a taxonomy term entity reference field that saves the auto-created
|
||||
// taxonomy terms in the second vocabulary from the two that were configured
|
||||
// as targets.
|
||||
$field_name = Unicode::strtolower($this->randomMachineName());
|
||||
$field_name = mb_strtolower($this->randomMachineName());
|
||||
$handler_settings = [
|
||||
'target_bundles' => [
|
||||
$vocabularies[0]->id() => $vocabularies[0]->id(),
|
||||
|
@ -213,17 +212,17 @@ class EntityReferenceAutoCreateTest extends BrowserTestBase {
|
|||
// a way to catch and assert user-triggered errors.
|
||||
|
||||
// Test the case when the field config settings are inconsistent.
|
||||
//unset($handler_settings['auto_create_bundle']);
|
||||
//$field_config->setSetting('handler_settings', $handler_settings);
|
||||
//$field_config->save();
|
||||
// unset($handler_settings['auto_create_bundle']);
|
||||
// $field_config->setSetting('handler_settings', $handler_settings);
|
||||
// $field_config->save();
|
||||
//
|
||||
//$this->drupalGet('node/add/' . $this->referencingType);
|
||||
//$error_message = sprintf(
|
||||
// $this->drupalGet('node/add/' . $this->referencingType);
|
||||
// $error_message = sprintf(
|
||||
// "Create referenced entities if they don't already exist option is enabled but a specific destination bundle is not set. You should re-visit and fix the settings of the '%s' (%s) field.",
|
||||
// $field_config->getLabel(),
|
||||
// $field_config->getName()
|
||||
//);
|
||||
//$this->assertErrorLogged($error_message);
|
||||
// );
|
||||
// $this->assertErrorLogged($error_message);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Drupal\Tests\field\Functional\EntityReference;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Tests\SchemaCheckTestTrait;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
@ -51,7 +50,7 @@ class EntityReferenceFieldDefaultValueTest extends BrowserTestBase {
|
|||
// Create a node to be referenced.
|
||||
$referenced_node = $this->drupalCreateNode(['type' => 'referenced_content']);
|
||||
|
||||
$field_name = Unicode::strtolower($this->randomMachineName());
|
||||
$field_name = mb_strtolower($this->randomMachineName());
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'node',
|
||||
|
@ -114,7 +113,7 @@ class EntityReferenceFieldDefaultValueTest extends BrowserTestBase {
|
|||
$referenced_node_type = $this->drupalCreateContentType(['type' => 'referenced_config_to_delete']);
|
||||
$referenced_node_type2 = $this->drupalCreateContentType(['type' => 'referenced_config_to_preserve']);
|
||||
|
||||
$field_name = Unicode::strtolower($this->randomMachineName());
|
||||
$field_name = mb_strtolower($this->randomMachineName());
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'node',
|
||||
|
|
|
@ -302,7 +302,6 @@ class EntityReferenceFieldTranslatedReferenceViewTest extends BrowserTestBase {
|
|||
return $node;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the referenced entity.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\EntityReference;
|
||||
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\TestFileCreationTrait;
|
||||
|
||||
/**
|
||||
* Tests an autocomplete widget with file upload.
|
||||
*
|
||||
* @group entity_reference
|
||||
*/
|
||||
class EntityReferenceFileUploadTest extends BrowserTestBase {
|
||||
|
||||
use TestFileCreationTrait;
|
||||
|
||||
public static $modules = ['entity_reference', 'node', 'file'];
|
||||
|
||||
/**
|
||||
* The name of a content type that will reference $referencedType.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $referencingType;
|
||||
|
||||
/**
|
||||
* The name of a content type that will be referenced by $referencingType.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $referencedType;
|
||||
|
||||
/**
|
||||
* Node id.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $nodeId;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create "referencing" and "referenced" node types.
|
||||
$referencing = $this->drupalCreateContentType();
|
||||
$this->referencingType = $referencing->id();
|
||||
|
||||
$referenced = $this->drupalCreateContentType();
|
||||
$this->referencedType = $referenced->id();
|
||||
$this->nodeId = $this->drupalCreateNode(['type' => $referenced->id()])->id();
|
||||
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => 'test_field',
|
||||
'entity_type' => 'node',
|
||||
'translatable' => FALSE,
|
||||
'entity_types' => [],
|
||||
'settings' => [
|
||||
'target_type' => 'node',
|
||||
],
|
||||
'type' => 'entity_reference',
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
])->save();
|
||||
|
||||
FieldConfig::create([
|
||||
'label' => 'Entity reference field',
|
||||
'field_name' => 'test_field',
|
||||
'entity_type' => 'node',
|
||||
'required' => TRUE,
|
||||
'bundle' => $referencing->id(),
|
||||
'settings' => [
|
||||
'handler' => 'default',
|
||||
'handler_settings' => [
|
||||
// Reference a single vocabulary.
|
||||
'target_bundles' => [
|
||||
$referenced->id(),
|
||||
],
|
||||
],
|
||||
],
|
||||
])->save();
|
||||
|
||||
// Create a file field.
|
||||
$file_field_name = 'file_field';
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => $file_field_name,
|
||||
'entity_type' => 'node',
|
||||
'type' => 'file',
|
||||
]);
|
||||
$field_storage->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => 'node',
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => $referencing->id(),
|
||||
'label' => $this->randomMachineName() . '_label',
|
||||
])->save();
|
||||
|
||||
entity_get_display('node', $referencing->id(), 'default')
|
||||
->setComponent('test_field')
|
||||
->setComponent($file_field_name)
|
||||
->save();
|
||||
entity_get_form_display('node', $referencing->id(), 'default')
|
||||
->setComponent('test_field', [
|
||||
'type' => 'entity_reference_autocomplete',
|
||||
])
|
||||
->setComponent($file_field_name, [
|
||||
'type' => 'file_generic',
|
||||
])
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the autocomplete input element does not cause ajax fatal.
|
||||
*/
|
||||
public function testFileUpload() {
|
||||
$user1 = $this->drupalCreateUser(['access content', "create $this->referencingType content"]);
|
||||
$this->drupalLogin($user1);
|
||||
|
||||
$test_file = current($this->getTestFiles('text'));
|
||||
$edit['files[file_field_0]'] = \Drupal::service('file_system')->realpath($test_file->uri);
|
||||
$this->drupalPostForm('node/add/' . $this->referencingType, $edit, 'Upload');
|
||||
$this->assertResponse(200);
|
||||
$edit = [
|
||||
'title[0][value]' => $this->randomMachineName(),
|
||||
'test_field[0][target_id]' => $this->nodeId,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, 'Save');
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
}
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
namespace Drupal\Tests\field\Functional\EntityReference;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\config\Tests\AssertConfigEntityImportTrait;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\Tests\config\Traits\AssertConfigEntityImportTrait;
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
||||
|
||||
/**
|
||||
* Tests various Entity reference UI components.
|
||||
|
@ -149,7 +149,7 @@ class EntityReferenceIntegrationTest extends BrowserTestBase {
|
|||
// Ensure the configuration has the expected dependency on the entity that
|
||||
// is being used a default value.
|
||||
$field = FieldConfig::loadByName($this->entityType, $this->bundle, $this->fieldName);
|
||||
$this->assertTrue(in_array($referenced_entities[0]->getConfigDependencyName(), $field->getDependencies()[$key]), SafeMarkup::format('Expected @type dependency @name found', ['@type' => $key, '@name' => $referenced_entities[0]->getConfigDependencyName()]));
|
||||
$this->assertTrue(in_array($referenced_entities[0]->getConfigDependencyName(), $field->getDependencies()[$key]), new FormattableMarkup('Expected @type dependency @name found', ['@type' => $key, '@name' => $referenced_entities[0]->getConfigDependencyName()]));
|
||||
// Ensure that the field can be imported without change even after the
|
||||
// default value deleted.
|
||||
$referenced_entities[0]->delete();
|
||||
|
@ -163,7 +163,7 @@ class EntityReferenceIntegrationTest extends BrowserTestBase {
|
|||
$field = FieldConfig::loadByName($this->entityType, $this->bundle, $this->fieldName);
|
||||
$field->save();
|
||||
$dependencies = $field->getDependencies();
|
||||
$this->assertFalse(isset($dependencies[$key]) && in_array($referenced_entities[0]->getConfigDependencyName(), $dependencies[$key]), SafeMarkup::format('@type dependency @name does not exist.', ['@type' => $key, '@name' => $referenced_entities[0]->getConfigDependencyName()]));
|
||||
$this->assertFalse(isset($dependencies[$key]) && in_array($referenced_entities[0]->getConfigDependencyName(), $dependencies[$key]), new FormattableMarkup('@type dependency @name does not exist.', ['@type' => $key, '@name' => $referenced_entities[0]->getConfigDependencyName()]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,9 +197,10 @@ class EntityReferenceIntegrationTest extends BrowserTestBase {
|
|||
* An array of entity objects.
|
||||
*/
|
||||
protected function getTestEntities() {
|
||||
$config_entity_1 = entity_create('config_test', ['id' => $this->randomMachineName(), 'label' => $this->randomMachineName()]);
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('config_test');
|
||||
$config_entity_1 = $storage->create(['id' => $this->randomMachineName(), 'label' => $this->randomMachineName()]);
|
||||
$config_entity_1->save();
|
||||
$config_entity_2 = entity_create('config_test', ['id' => $this->randomMachineName(), 'label' => $this->randomMachineName()]);
|
||||
$config_entity_2 = $storage->create(['id' => $this->randomMachineName(), 'label' => $this->randomMachineName()]);
|
||||
$config_entity_2->save();
|
||||
|
||||
$content_entity_1 = EntityTest::create(['name' => $this->randomMachineName()]);
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Drupal\Tests\field\Functional\EntityReference;
|
|||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Core\Entity\Entity\EntityViewDisplay;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
||||
|
||||
/**
|
||||
* Tests possible XSS security issues in entity references.
|
||||
|
@ -60,9 +60,9 @@ class EntityReferenceXSSTest extends BrowserTestBase {
|
|||
|
||||
$edit = [
|
||||
'title[0][value]' => $this->randomString(),
|
||||
'entity_reference_test' => $referenced_node->id()
|
||||
'entity_reference_test' => $referenced_node->id(),
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, 'Save and publish');
|
||||
$this->drupalPostForm(NULL, $edit, 'Save');
|
||||
$this->assertEscaped($referenced_node->getTitle());
|
||||
|
||||
// Test the options_buttons type.
|
||||
|
|
|
@ -127,7 +127,7 @@ class SelectionTest extends BrowserTestBase {
|
|||
'table' => 'users_field_data',
|
||||
'field' => 'uid',
|
||||
'relationship' => 'test_relationship',
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
// Set view to distinct so only one row per node is returned.
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the default value callback.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class FieldDefaultValueCallbackTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node', 'field_test', 'field_ui'];
|
||||
|
||||
/**
|
||||
* The field name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $fieldName;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->fieldName = 'field_test';
|
||||
|
||||
// Create Article node types.
|
||||
if ($this->profile != 'standard') {
|
||||
$this->drupalCreateContentType([
|
||||
'type' => 'article',
|
||||
'name' => 'Article',
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function testDefaultValueCallbackForm() {
|
||||
// Create a field and storage for checking.
|
||||
/** @var \Drupal\field\Entity\FieldStorageConfig $field_storage */
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $this->fieldName,
|
||||
'entity_type' => 'node',
|
||||
'type' => 'text',
|
||||
])->save();
|
||||
/** @var \Drupal\field\Entity\FieldConfig $field_config */
|
||||
$field_config = FieldConfig::create([
|
||||
'entity_type' => 'node',
|
||||
'field_name' => $this->fieldName,
|
||||
'bundle' => 'article',
|
||||
]);
|
||||
$field_config->save();
|
||||
|
||||
$this->drupalLogin($this->rootUser);
|
||||
|
||||
// Check that the default field form is visible when no callback is set.
|
||||
$this->drupalGet('/admin/structure/types/manage/article/fields/node.article.field_test');
|
||||
$this->assertFieldByName('default_value_input[field_test][0][value]', NULL, 'The default field form is visible.');
|
||||
|
||||
// Set a different field value, it should be on the field.
|
||||
$default_value = $this->randomString();
|
||||
$field_config->setDefaultValue([['value' => $default_value]])->save();
|
||||
$this->drupalGet('/admin/structure/types/manage/article/fields/node.article.field_test');
|
||||
$this->assertFieldByName('default_value_input[field_test][0][value]', $default_value, 'The default field form is visible.');
|
||||
|
||||
// Set a different field value to the field directly, instead of an array.
|
||||
$default_value = $this->randomString();
|
||||
$field_config->setDefaultValue($default_value)->save();
|
||||
$this->drupalGet('/admin/structure/types/manage/article/fields/node.article.field_test');
|
||||
$this->assertFieldByName('default_value_input[field_test][0][value]', $default_value, 'The default field form is visible.');
|
||||
|
||||
// Set a default value callback instead, and the default field form should
|
||||
// not be visible.
|
||||
$field_config->setDefaultValueCallback('\Drupal\field_test\FieldDefaultValueCallbackProvider::calculateDefaultValue')->save();
|
||||
$this->drupalGet('/admin/structure/types/manage/article/fields/node.article.field_test');
|
||||
$this->assertNoFieldByName('default_value_input[field_test][0][value]', 'Calculated default value', 'The default field form is not visible when a callback is defined.');
|
||||
}
|
||||
|
||||
}
|
|
@ -14,7 +14,7 @@ class FieldHelpTest extends BrowserTestBase {
|
|||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array.
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['field', 'help'];
|
||||
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Delete field storages and fields during config synchronization and uninstall
|
||||
* module that provides the field type through the UI.
|
||||
*
|
||||
* @group field
|
||||
* @see \Drupal\field\ConfigImporterFieldPurger
|
||||
* @see field_config_import_steps_alter()
|
||||
* @see field_form_config_admin_import_form_alter()
|
||||
*/
|
||||
class FieldImportDeleteUninstallUiTest extends FieldTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['entity_test', 'telephone', 'config', 'filter', 'datetime'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->drupalLogin($this->drupalCreateUser(['synchronize configuration']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests deleting field storages and fields as part of config import.
|
||||
*/
|
||||
public function testImportDeleteUninstall() {
|
||||
// Create a telephone field.
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => 'field_tel',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'telephone',
|
||||
]);
|
||||
$field_storage->save();
|
||||
FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'entity_test',
|
||||
])->save();
|
||||
|
||||
// Create a text field.
|
||||
$date_field_storage = FieldStorageConfig::create([
|
||||
'field_name' => 'field_date',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'datetime',
|
||||
]);
|
||||
$date_field_storage->save();
|
||||
FieldConfig::create([
|
||||
'field_storage' => $date_field_storage,
|
||||
'bundle' => 'entity_test',
|
||||
])->save();
|
||||
|
||||
// Create an entity which has values for the telephone and text field.
|
||||
$entity = EntityTest::create();
|
||||
$value = '+0123456789';
|
||||
$entity->field_tel = $value;
|
||||
$entity->field_date = time();
|
||||
$entity->name->value = $this->randomMachineName();
|
||||
$entity->save();
|
||||
|
||||
// Delete the text field before exporting configuration so that we can test
|
||||
// that deleted fields that are provided by modules that will be uninstalled
|
||||
// are also purged and that the UI message includes such fields.
|
||||
$date_field_storage->delete();
|
||||
|
||||
// Verify entity has been created properly.
|
||||
$id = $entity->id();
|
||||
$entity = EntityTest::load($id);
|
||||
$this->assertEqual($entity->field_tel->value, $value);
|
||||
$this->assertEqual($entity->field_tel[0]->value, $value);
|
||||
|
||||
$active = $this->container->get('config.storage');
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$this->copyConfig($active, $sync);
|
||||
|
||||
// Stage uninstall of the Telephone module.
|
||||
$core_extension = $this->config('core.extension')->get();
|
||||
unset($core_extension['module']['telephone']);
|
||||
$sync->write('core.extension', $core_extension);
|
||||
|
||||
// Stage the field deletion
|
||||
$sync->delete('field.storage.entity_test.field_tel');
|
||||
$sync->delete('field.field.entity_test.entity_test.field_tel');
|
||||
$this->drupalGet('admin/config/development/configuration');
|
||||
// Test that the message for one field being purged during a configuration
|
||||
// synchronization is correct.
|
||||
$this->assertText('This synchronization will delete data from the field entity_test.field_tel.');
|
||||
|
||||
// Stage an uninstall of the datetime module to test the message for
|
||||
// multiple fields.
|
||||
unset($core_extension['module']['datetime']);
|
||||
$sync->write('core.extension', $core_extension);
|
||||
|
||||
$this->drupalGet('admin/config/development/configuration');
|
||||
$this->assertText('This synchronization will delete data from the fields: entity_test.field_tel, entity_test.field_date.');
|
||||
|
||||
// This will purge all the data, delete the field and uninstall the
|
||||
// Telephone and Text modules.
|
||||
$this->drupalPostForm(NULL, [], t('Import all'));
|
||||
$this->assertNoText('Field data will be deleted by this synchronization.');
|
||||
$this->rebuildContainer();
|
||||
$this->assertFalse(\Drupal::moduleHandler()->moduleExists('telephone'));
|
||||
$this->assertFalse(\Drupal::entityManager()->loadEntityByUuid('field_storage_config', $field_storage->uuid()), 'The telephone field has been deleted by the configuration synchronization');
|
||||
$deleted_storages = \Drupal::state()->get('field.storage.deleted') ?: [];
|
||||
$this->assertFalse(isset($deleted_storages[$field_storage->uuid()]), 'Telephone field has been completed removed from the system.');
|
||||
$this->assertFalse(isset($deleted_storages[$field_storage->uuid()]), 'Text field has been completed removed from the system.');
|
||||
}
|
||||
|
||||
}
|
|
@ -33,7 +33,7 @@ abstract class FieldTestBase extends BrowserTestBase {
|
|||
*
|
||||
* This function only checks a single column in the field values.
|
||||
*
|
||||
* @param EntityInterface $entity
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity to test.
|
||||
* @param $field_name
|
||||
* The name of the field to test
|
||||
|
|
700
web/core/modules/field/tests/src/Functional/FormTest.php
Normal file
700
web/core/modules/field/tests/src/Functional/FormTest.php
Normal file
|
@ -0,0 +1,700 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\Form\FormState;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\entity_test\Entity\EntityTestBaseFieldDisplay;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Tests field form handling.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class FormTest extends FieldTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* Locale is installed so that TranslatableMarkup actually does something.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node', 'field_test', 'options', 'entity_test', 'locale'];
|
||||
|
||||
/**
|
||||
* An array of values defining a field single.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldStorageSingle;
|
||||
|
||||
/**
|
||||
* An array of values defining a field multiple.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldStorageMultiple;
|
||||
|
||||
/**
|
||||
* An array of values defining a field with unlimited cardinality.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldStorageUnlimited;
|
||||
|
||||
/**
|
||||
* An array of values defining a field.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $field;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$web_user = $this->drupalCreateUser(['view test entity', 'administer entity_test content']);
|
||||
$this->drupalLogin($web_user);
|
||||
|
||||
$this->fieldStorageSingle = [
|
||||
'field_name' => 'field_single',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
];
|
||||
$this->fieldStorageMultiple = [
|
||||
'field_name' => 'field_multiple',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
'cardinality' => 4,
|
||||
];
|
||||
$this->fieldStorageUnlimited = [
|
||||
'field_name' => 'field_unlimited',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
];
|
||||
|
||||
$this->field = [
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
'label' => $this->randomMachineName() . '_label',
|
||||
'description' => '[site:name]_description',
|
||||
'weight' => mt_rand(0, 127),
|
||||
'settings' => [
|
||||
'test_field_setting' => $this->randomMachineName(),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function testFieldFormSingle() {
|
||||
$field_storage = $this->fieldStorageSingle;
|
||||
$field_name = $field_storage['field_name'];
|
||||
$this->field['field_name'] = $field_name;
|
||||
FieldStorageConfig::create($field_storage)->save();
|
||||
FieldConfig::create($this->field)->save();
|
||||
entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
|
||||
->setComponent($field_name)
|
||||
->save();
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet('entity_test/add');
|
||||
|
||||
// Create token value expected for description.
|
||||
$token_description = Html::escape($this->config('system.site')->get('name')) . '_description';
|
||||
$this->assertText($token_description, 'Token replacement for description is displayed');
|
||||
$this->assertFieldByName("{$field_name}[0][value]", '', 'Widget is displayed');
|
||||
$this->assertNoField("{$field_name}[1][value]", 'No extraneous widget is displayed');
|
||||
|
||||
// Check that hook_field_widget_form_alter() does not believe this is the
|
||||
// default value form.
|
||||
$this->assertNoText('From hook_field_widget_form_alter(): Default form is true.', 'Not default value form in hook_field_widget_form_alter().');
|
||||
// Check that hook_field_widget_form_alter() does not believe this is the
|
||||
// default value form.
|
||||
$this->assertNoText('From hook_field_widget_multivalue_form_alter(): Default form is true.', 'Not default value form in hook_field_widget_form_alter().');
|
||||
|
||||
// Submit with invalid value (field-level validation).
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => -1,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertRaw(t('%name does not accept the value -1.', ['%name' => $this->field['label']]), 'Field validation fails with invalid input.');
|
||||
// TODO : check that the correct field is flagged for error.
|
||||
|
||||
// Create an entity
|
||||
$value = mt_rand(1, 127);
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $value,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', ['@id' => $id]), 'Entity was created');
|
||||
$entity = EntityTest::load($id);
|
||||
$this->assertEqual($entity->{$field_name}->value, $value, 'Field value was saved');
|
||||
|
||||
// Display edit form.
|
||||
$this->drupalGet('entity_test/manage/' . $id . '/edit');
|
||||
$this->assertFieldByName("{$field_name}[0][value]", $value, 'Widget is displayed with the correct default value');
|
||||
$this->assertNoField("{$field_name}[1][value]", 'No extraneous widget is displayed');
|
||||
|
||||
// Update the entity.
|
||||
$value = mt_rand(1, 127);
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $value,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertText(t('entity_test @id has been updated.', ['@id' => $id]), 'Entity was updated');
|
||||
$this->container->get('entity.manager')->getStorage('entity_test')->resetCache([$id]);
|
||||
$entity = EntityTest::load($id);
|
||||
$this->assertEqual($entity->{$field_name}->value, $value, 'Field value was updated');
|
||||
|
||||
// Empty the field.
|
||||
$value = '';
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $value,
|
||||
];
|
||||
$this->drupalPostForm('entity_test/manage/' . $id . '/edit', $edit, t('Save'));
|
||||
$this->assertText(t('entity_test @id has been updated.', ['@id' => $id]), 'Entity was updated');
|
||||
$this->container->get('entity.manager')->getStorage('entity_test')->resetCache([$id]);
|
||||
$entity = EntityTest::load($id);
|
||||
$this->assertTrue($entity->{$field_name}->isEmpty(), 'Field was emptied');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests field widget default values on entity forms.
|
||||
*/
|
||||
public function testFieldFormDefaultValue() {
|
||||
$field_storage = $this->fieldStorageSingle;
|
||||
$field_name = $field_storage['field_name'];
|
||||
$this->field['field_name'] = $field_name;
|
||||
$default = rand(1, 127);
|
||||
$this->field['default_value'] = [['value' => $default]];
|
||||
FieldStorageConfig::create($field_storage)->save();
|
||||
FieldConfig::create($this->field)->save();
|
||||
entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
|
||||
->setComponent($field_name)
|
||||
->save();
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet('entity_test/add');
|
||||
// Test that the default value is displayed correctly.
|
||||
$this->assertFieldByXpath("//input[@name='{$field_name}[0][value]' and @value='$default']");
|
||||
|
||||
// Try to submit an empty value.
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => '',
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', ['@id' => $id]), 'Entity was created.');
|
||||
$entity = EntityTest::load($id);
|
||||
$this->assertTrue($entity->{$field_name}->isEmpty(), 'Field is now empty.');
|
||||
}
|
||||
|
||||
public function testFieldFormSingleRequired() {
|
||||
$field_storage = $this->fieldStorageSingle;
|
||||
$field_name = $field_storage['field_name'];
|
||||
$this->field['field_name'] = $field_name;
|
||||
$this->field['required'] = TRUE;
|
||||
FieldStorageConfig::create($field_storage)->save();
|
||||
FieldConfig::create($this->field)->save();
|
||||
entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
|
||||
->setComponent($field_name)
|
||||
->save();
|
||||
|
||||
// Submit with missing required value.
|
||||
$edit = [];
|
||||
$this->drupalPostForm('entity_test/add', $edit, t('Save'));
|
||||
$this->assertRaw(t('@name field is required.', ['@name' => $this->field['label']]), 'Required field with no value fails validation');
|
||||
|
||||
// Create an entity
|
||||
$value = mt_rand(1, 127);
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $value,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', ['@id' => $id]), 'Entity was created');
|
||||
$entity = EntityTest::load($id);
|
||||
$this->assertEqual($entity->{$field_name}->value, $value, 'Field value was saved');
|
||||
|
||||
// Edit with missing required value.
|
||||
$value = '';
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $value,
|
||||
];
|
||||
$this->drupalPostForm('entity_test/manage/' . $id . '/edit', $edit, t('Save'));
|
||||
$this->assertRaw(t('@name field is required.', ['@name' => $this->field['label']]), 'Required field with no value fails validation');
|
||||
}
|
||||
|
||||
public function testFieldFormUnlimited() {
|
||||
$field_storage = $this->fieldStorageUnlimited;
|
||||
$field_name = $field_storage['field_name'];
|
||||
$this->field['field_name'] = $field_name;
|
||||
FieldStorageConfig::create($field_storage)->save();
|
||||
FieldConfig::create($this->field)->save();
|
||||
entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
|
||||
->setComponent($field_name)
|
||||
->save();
|
||||
|
||||
// Display creation form -> 1 widget.
|
||||
$this->drupalGet('entity_test/add');
|
||||
$this->assertFieldByName("{$field_name}[0][value]", '', 'Widget 1 is displayed');
|
||||
$this->assertNoField("{$field_name}[1][value]", 'No extraneous widget is displayed');
|
||||
|
||||
// Check if aria-describedby attribute is placed on multiple value widgets.
|
||||
$elements = $this->xpath('//table[@id="field-unlimited-values" and @aria-describedby="edit-field-unlimited--description"]');
|
||||
$this->assertTrue(isset($elements[0]), t('aria-describedby attribute is properly placed on multiple value widgets.'));
|
||||
|
||||
// Press 'add more' button -> 2 widgets.
|
||||
$this->drupalPostForm(NULL, [], t('Add another item'));
|
||||
$this->assertFieldByName("{$field_name}[0][value]", '', 'Widget 1 is displayed');
|
||||
$this->assertFieldByName("{$field_name}[1][value]", '', 'New widget is displayed');
|
||||
$this->assertNoField("{$field_name}[2][value]", 'No extraneous widget is displayed');
|
||||
// TODO : check that non-field inputs are preserved ('title'), etc.
|
||||
|
||||
// Yet another time so that we can play with more values -> 3 widgets.
|
||||
$this->drupalPostForm(NULL, [], t('Add another item'));
|
||||
|
||||
// Prepare values and weights.
|
||||
$count = 3;
|
||||
$delta_range = $count - 1;
|
||||
$values = $weights = $pattern = $expected_values = [];
|
||||
$edit = [];
|
||||
for ($delta = 0; $delta <= $delta_range; $delta++) {
|
||||
// Assign unique random values and weights.
|
||||
do {
|
||||
$value = mt_rand(1, 127);
|
||||
} while (in_array($value, $values));
|
||||
do {
|
||||
$weight = mt_rand(-$delta_range, $delta_range);
|
||||
} while (in_array($weight, $weights));
|
||||
$edit["{$field_name}[$delta][value]"] = $value;
|
||||
$edit["{$field_name}[$delta][_weight]"] = $weight;
|
||||
// We'll need three slightly different formats to check the values.
|
||||
$values[$delta] = $value;
|
||||
$weights[$delta] = $weight;
|
||||
$field_values[$weight]['value'] = (string) $value;
|
||||
$pattern[$weight] = "<input [^>]*value=\"$value\" [^>]*";
|
||||
}
|
||||
|
||||
// Press 'add more' button -> 4 widgets
|
||||
$this->drupalPostForm(NULL, $edit, t('Add another item'));
|
||||
for ($delta = 0; $delta <= $delta_range; $delta++) {
|
||||
$this->assertFieldByName("{$field_name}[$delta][value]", $values[$delta], "Widget $delta is displayed and has the right value");
|
||||
$this->assertFieldByName("{$field_name}[$delta][_weight]", $weights[$delta], "Widget $delta has the right weight");
|
||||
}
|
||||
ksort($pattern);
|
||||
$pattern = implode('.*', array_values($pattern));
|
||||
$this->assertPattern("|$pattern|s", 'Widgets are displayed in the correct order');
|
||||
$this->assertFieldByName("{$field_name}[$delta][value]", '', "New widget is displayed");
|
||||
$this->assertFieldByName("{$field_name}[$delta][_weight]", $delta, "New widget has the right weight");
|
||||
$this->assertNoField("{$field_name}[" . ($delta + 1) . '][value]', 'No extraneous widget is displayed');
|
||||
|
||||
// Submit the form and create the entity.
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', ['@id' => $id]), 'Entity was created');
|
||||
$entity = EntityTest::load($id);
|
||||
ksort($field_values);
|
||||
$field_values = array_values($field_values);
|
||||
$this->assertIdentical($entity->{$field_name}->getValue(), $field_values, 'Field values were saved in the correct order');
|
||||
|
||||
// Display edit form: check that the expected number of widgets is
|
||||
// displayed, with correct values change values, reorder, leave an empty
|
||||
// value in the middle.
|
||||
// Submit: check that the entity is updated with correct values
|
||||
// Re-submit: check that the field can be emptied.
|
||||
|
||||
// Test with several multiple fields in a form
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the position of the required label.
|
||||
*/
|
||||
public function testFieldFormUnlimitedRequired() {
|
||||
$field_name = $this->fieldStorageUnlimited['field_name'];
|
||||
$this->field['field_name'] = $field_name;
|
||||
$this->field['required'] = TRUE;
|
||||
FieldStorageConfig::create($this->fieldStorageUnlimited)->save();
|
||||
FieldConfig::create($this->field)->save();
|
||||
entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
|
||||
->setComponent($field_name)
|
||||
->save();
|
||||
|
||||
// Display creation form -> 1 widget.
|
||||
$this->drupalGet('entity_test/add');
|
||||
// Check that the Required symbol is present for the multifield label.
|
||||
$element = $this->xpath('//h4[contains(@class, "label") and contains(@class, "js-form-required") and contains(text(), :value)]', [':value' => $this->field['label']]);
|
||||
$this->assertTrue(isset($element[0]), 'Required symbol added field label.');
|
||||
// Check that the label of the field input is visually hidden and contains
|
||||
// the field title and an indication of the delta for a11y.
|
||||
$element = $this->xpath('//label[@for=:for and contains(@class, "visually-hidden") and contains(text(), :value)]', [':for' => 'edit-field-unlimited-0-value', ':value' => $this->field['label'] . ' (value 1)']);
|
||||
$this->assertTrue(isset($element[0]), 'Required symbol not added for field input.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests widget handling of multiple required radios.
|
||||
*/
|
||||
public function testFieldFormMultivalueWithRequiredRadio() {
|
||||
// Create a multivalue test field.
|
||||
$field_storage = $this->fieldStorageUnlimited;
|
||||
$field_name = $field_storage['field_name'];
|
||||
$this->field['field_name'] = $field_name;
|
||||
FieldStorageConfig::create($field_storage)->save();
|
||||
FieldConfig::create($this->field)->save();
|
||||
entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
|
||||
->setComponent($field_name)
|
||||
->save();
|
||||
|
||||
// Add a required radio field.
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => 'required_radio_test',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'list_string',
|
||||
'settings' => [
|
||||
'allowed_values' => ['yes' => 'yes', 'no' => 'no'],
|
||||
],
|
||||
])->save();
|
||||
$field = [
|
||||
'field_name' => 'required_radio_test',
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
'required' => TRUE,
|
||||
];
|
||||
FieldConfig::create($field)->save();
|
||||
entity_get_form_display($field['entity_type'], $field['bundle'], 'default')
|
||||
->setComponent($field['field_name'], [
|
||||
'type' => 'options_buttons',
|
||||
])
|
||||
->save();
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet('entity_test/add');
|
||||
|
||||
// Press the 'Add more' button.
|
||||
$this->drupalPostForm(NULL, [], t('Add another item'));
|
||||
|
||||
// Verify that no error is thrown by the radio element.
|
||||
$this->assertNoFieldByXpath('//div[contains(@class, "error")]', FALSE, 'No error message is displayed.');
|
||||
|
||||
// Verify that the widget is added.
|
||||
$this->assertFieldByName("{$field_name}[0][value]", '', 'Widget 1 is displayed');
|
||||
$this->assertFieldByName("{$field_name}[1][value]", '', 'New widget is displayed');
|
||||
$this->assertNoField("{$field_name}[2][value]", 'No extraneous widget is displayed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests widgets handling multiple values.
|
||||
*/
|
||||
public function testFieldFormMultipleWidget() {
|
||||
// Create a field with fixed cardinality, configure the form to use a
|
||||
// "multiple" widget.
|
||||
$field_storage = $this->fieldStorageMultiple;
|
||||
$field_name = $field_storage['field_name'];
|
||||
$this->field['field_name'] = $field_name;
|
||||
FieldStorageConfig::create($field_storage)->save();
|
||||
FieldConfig::create($this->field)->save();
|
||||
entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'test_field_widget_multiple',
|
||||
])
|
||||
->save();
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet('entity_test/add');
|
||||
$this->assertFieldByName($field_name, '', 'Widget is displayed.');
|
||||
|
||||
// Create entity with three values.
|
||||
$edit = [
|
||||
$field_name => '1, 2, 3',
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
|
||||
// Check that the values were saved.
|
||||
$entity_init = EntityTest::load($id);
|
||||
$this->assertFieldValues($entity_init, $field_name, [1, 2, 3]);
|
||||
|
||||
// Display the form, check that the values are correctly filled in.
|
||||
$this->drupalGet('entity_test/manage/' . $id . '/edit');
|
||||
$this->assertFieldByName($field_name, '1, 2, 3', 'Widget is displayed.');
|
||||
|
||||
// Submit the form with more values than the field accepts.
|
||||
$edit = [$field_name => '1, 2, 3, 4, 5'];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertRaw('this field cannot hold more than 4 values', 'Form validation failed.');
|
||||
// Check that the field values were not submitted.
|
||||
$this->assertFieldValues($entity_init, $field_name, [1, 2, 3]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests fields with no 'edit' access.
|
||||
*/
|
||||
public function testFieldFormAccess() {
|
||||
$entity_type = 'entity_test_rev';
|
||||
// Create a "regular" field.
|
||||
$field_storage = $this->fieldStorageSingle;
|
||||
$field_storage['entity_type'] = $entity_type;
|
||||
$field_name = $field_storage['field_name'];
|
||||
$field = $this->field;
|
||||
$field['field_name'] = $field_name;
|
||||
$field['entity_type'] = $entity_type;
|
||||
$field['bundle'] = $entity_type;
|
||||
FieldStorageConfig::create($field_storage)->save();
|
||||
FieldConfig::create($field)->save();
|
||||
entity_get_form_display($entity_type, $entity_type, 'default')
|
||||
->setComponent($field_name)
|
||||
->save();
|
||||
|
||||
// Create a field with no edit access. See
|
||||
// field_test_entity_field_access().
|
||||
$field_storage_no_access = [
|
||||
'field_name' => 'field_no_edit_access',
|
||||
'entity_type' => $entity_type,
|
||||
'type' => 'test_field',
|
||||
];
|
||||
$field_name_no_access = $field_storage_no_access['field_name'];
|
||||
$field_no_access = [
|
||||
'field_name' => $field_name_no_access,
|
||||
'entity_type' => $entity_type,
|
||||
'bundle' => $entity_type,
|
||||
'default_value' => [0 => ['value' => 99]],
|
||||
];
|
||||
FieldStorageConfig::create($field_storage_no_access)->save();
|
||||
FieldConfig::create($field_no_access)->save();
|
||||
entity_get_form_display($field_no_access['entity_type'], $field_no_access['bundle'], 'default')
|
||||
->setComponent($field_name_no_access)
|
||||
->save();
|
||||
|
||||
// Test that the form structure includes full information for each delta
|
||||
// apart from #access.
|
||||
$entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->create(['id' => 0, 'revision_id' => 0]);
|
||||
|
||||
$display = entity_get_form_display($entity_type, $entity_type, 'default');
|
||||
$form = [];
|
||||
$form_state = new FormState();
|
||||
$display->buildForm($entity, $form, $form_state);
|
||||
|
||||
$this->assertFalse($form[$field_name_no_access]['#access'], 'Field #access is FALSE for the field without edit access.');
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet($entity_type . '/add');
|
||||
$this->assertNoFieldByName("{$field_name_no_access}[0][value]", '', 'Widget is not displayed if field access is denied.');
|
||||
|
||||
// Create entity.
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => 1,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
preg_match("|$entity_type/manage/(\d+)|", $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
|
||||
// Check that the default value was saved.
|
||||
$storage = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type);
|
||||
$entity = $storage->load($id);
|
||||
$this->assertEqual($entity->$field_name_no_access->value, 99, 'Default value was saved for the field with no edit access.');
|
||||
$this->assertEqual($entity->$field_name->value, 1, 'Entered value vas saved for the field with edit access.');
|
||||
|
||||
// Create a new revision.
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => 2,
|
||||
'revision' => TRUE,
|
||||
];
|
||||
$this->drupalPostForm($entity_type . '/manage/' . $id . '/edit', $edit, t('Save'));
|
||||
|
||||
// Check that the new revision has the expected values.
|
||||
$storage->resetCache([$id]);
|
||||
$entity = $storage->load($id);
|
||||
$this->assertEqual($entity->$field_name_no_access->value, 99, 'New revision has the expected value for the field with no edit access.');
|
||||
$this->assertEqual($entity->$field_name->value, 2, 'New revision has the expected value for the field with edit access.');
|
||||
|
||||
// Check that the revision is also saved in the revisions table.
|
||||
$entity = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type)
|
||||
->loadRevision($entity->getRevisionId());
|
||||
$this->assertEqual($entity->$field_name_no_access->value, 99, 'New revision has the expected value for the field with no edit access.');
|
||||
$this->assertEqual($entity->$field_name->value, 2, 'New revision has the expected value for the field with edit access.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests hiding a field in a form.
|
||||
*/
|
||||
public function testHiddenField() {
|
||||
$entity_type = 'entity_test_rev';
|
||||
$field_storage = $this->fieldStorageSingle;
|
||||
$field_storage['entity_type'] = $entity_type;
|
||||
$field_name = $field_storage['field_name'];
|
||||
$this->field['field_name'] = $field_name;
|
||||
$this->field['default_value'] = [0 => ['value' => 99]];
|
||||
$this->field['entity_type'] = $entity_type;
|
||||
$this->field['bundle'] = $entity_type;
|
||||
FieldStorageConfig::create($field_storage)->save();
|
||||
$this->field = FieldConfig::create($this->field);
|
||||
$this->field->save();
|
||||
// We explicitly do not assign a widget in a form display, so the field
|
||||
// stays hidden in forms.
|
||||
|
||||
// Display the entity creation form.
|
||||
$this->drupalGet($entity_type . '/add');
|
||||
|
||||
// Create an entity and test that the default value is assigned correctly to
|
||||
// the field that uses the hidden widget.
|
||||
$this->assertNoField("{$field_name}[0][value]", 'The field does not appear in the form');
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
preg_match('|' . $entity_type . '/manage/(\d+)|', $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test_rev @id has been created.', ['@id' => $id]), 'Entity was created');
|
||||
$storage = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type);
|
||||
|
||||
$entity = $storage->load($id);
|
||||
$this->assertEqual($entity->{$field_name}->value, 99, 'Default value was saved');
|
||||
|
||||
// Update the field to remove the default value, and switch to the default
|
||||
// widget.
|
||||
$this->field->setDefaultValue([]);
|
||||
$this->field->save();
|
||||
entity_get_form_display($entity_type, $this->field->getTargetBundle(), 'default')
|
||||
->setComponent($this->field->getName(), [
|
||||
'type' => 'test_field_widget',
|
||||
])
|
||||
->save();
|
||||
|
||||
// Display edit form.
|
||||
$this->drupalGet($entity_type . '/manage/' . $id . '/edit');
|
||||
$this->assertFieldByName("{$field_name}[0][value]", 99, 'Widget is displayed with the correct default value');
|
||||
|
||||
// Update the entity.
|
||||
$value = mt_rand(1, 127);
|
||||
$edit = ["{$field_name}[0][value]" => $value];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertText(t('entity_test_rev @id has been updated.', ['@id' => $id]), 'Entity was updated');
|
||||
$storage->resetCache([$id]);
|
||||
$entity = $storage->load($id);
|
||||
$this->assertEqual($entity->{$field_name}->value, $value, 'Field value was updated');
|
||||
|
||||
// Set the field back to hidden.
|
||||
entity_get_form_display($entity_type, $this->field->getTargetBundle(), 'default')
|
||||
->removeComponent($this->field->getName())
|
||||
->save();
|
||||
|
||||
// Create a new revision.
|
||||
$edit = ['revision' => TRUE];
|
||||
$this->drupalPostForm($entity_type . '/manage/' . $id . '/edit', $edit, t('Save'));
|
||||
|
||||
// Check that the expected value has been carried over to the new revision.
|
||||
$storage->resetCache([$id]);
|
||||
$entity = $storage->load($id);
|
||||
$this->assertEqual($entity->{$field_name}->value, $value, 'New revision has the expected value for the field with the Hidden widget');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the form display of the label for multi-value fields.
|
||||
*/
|
||||
public function testLabelOnMultiValueFields() {
|
||||
$user = $this->drupalCreateUser(['administer entity_test content']);
|
||||
$this->drupalLogin($user);
|
||||
|
||||
FieldStorageConfig::create([
|
||||
'entity_type' => 'entity_test_base_field_display',
|
||||
'field_name' => 'foo',
|
||||
'type' => 'text',
|
||||
'cardinality' => FieldStorageConfig::CARDINALITY_UNLIMITED,
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'entity_type' => 'entity_test_base_field_display',
|
||||
'bundle' => 'bar',
|
||||
'field_name' => 'foo',
|
||||
// Set a dangerous label to test XSS filtering.
|
||||
'label' => "<script>alert('a configurable field');</script>",
|
||||
])->save();
|
||||
EntityFormDisplay::create([
|
||||
'targetEntityType' => 'entity_test_base_field_display',
|
||||
'bundle' => 'bar',
|
||||
'mode' => 'default',
|
||||
])->setComponent('foo', ['type' => 'text_textfield'])->enable()->save();
|
||||
|
||||
$entity = EntityTestBaseFieldDisplay::create(['type' => 'bar']);
|
||||
$entity->save();
|
||||
|
||||
$this->drupalGet('entity_test_base_field_display/manage/' . $entity->id());
|
||||
$this->assertResponse(200);
|
||||
$this->assertText('A field with multiple values');
|
||||
// Test if labels were XSS filtered.
|
||||
$this->assertEscaped("<script>alert('a configurable field');</script>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests hook_field_widget_multivalue_form_alter().
|
||||
*/
|
||||
public function testFieldFormMultipleWidgetAlter() {
|
||||
$this->widgetAlterTest('hook_field_widget_multivalue_form_alter', 'test_field_widget_multiple');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests hook_field_widget_multivalue_form_alter() with single value elements.
|
||||
*/
|
||||
public function testFieldFormMultipleWidgetAlterSingleValues() {
|
||||
$this->widgetAlterTest('hook_field_widget_multivalue_form_alter', 'test_field_widget_multiple_single_value');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests hook_field_widget_multivalue_WIDGET_TYPE_form_alter().
|
||||
*/
|
||||
public function testFieldFormMultipleWidgetTypeAlter() {
|
||||
$this->widgetAlterTest('hook_field_widget_multivalue_WIDGET_TYPE_form_alter', 'test_field_widget_multiple');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests hook_field_widget_multivalue_WIDGET_TYPE_form_alter() with single value elements.
|
||||
*/
|
||||
public function testFieldFormMultipleWidgetTypeAlterSingleValues() {
|
||||
$this->widgetAlterTest('hook_field_widget_multivalue_WIDGET_TYPE_form_alter', 'test_field_widget_multiple_single_value');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests widget alter hooks for a given hook name.
|
||||
*/
|
||||
protected function widgetAlterTest($hook, $widget) {
|
||||
// Create a field with fixed cardinality, configure the form to use a
|
||||
// "multiple" widget.
|
||||
$field_storage = $this->fieldStorageMultiple;
|
||||
$field_name = $field_storage['field_name'];
|
||||
$this->field['field_name'] = $field_name;
|
||||
FieldStorageConfig::create($field_storage)->save();
|
||||
FieldConfig::create($this->field)->save();
|
||||
|
||||
// Set a flag in state so that the hook implementations will run.
|
||||
\Drupal::state()->set("field_test.widget_alter_test", [
|
||||
'hook' => $hook,
|
||||
'field_name' => $field_name,
|
||||
'widget' => $widget,
|
||||
]);
|
||||
entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
|
||||
->setComponent($field_name, [
|
||||
'type' => $widget,
|
||||
])
|
||||
->save();
|
||||
|
||||
$this->drupalGet('entity_test/add');
|
||||
$this->assertUniqueText("From $hook(): prefix on $field_name parent element.");
|
||||
if ($widget === 'test_field_widget_multiple_single_value') {
|
||||
$suffix_text = "From $hook(): suffix on $field_name child element.";
|
||||
$this->assertEqual($field_storage['cardinality'], substr_count($this->getTextContent(), $suffix_text), "'$suffix_text' was found {$field_storage['cardinality']} times using widget $widget");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\field\Functional\Rest\FieldConfigResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class FieldConfigHalJsonAnonTest extends FieldConfigResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\field\Functional\Rest\FieldConfigResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class FieldConfigHalJsonBasicAuthTest extends FieldConfigResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal', 'basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\field\Functional\Rest\FieldConfigResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class FieldConfigHalJsonCookieTest extends FieldConfigResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\field\Functional\Rest\FieldStorageConfigResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class FieldStorageConfigHalJsonAnonTest extends FieldStorageConfigResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\field\Functional\Rest\FieldStorageConfigResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class FieldStorageConfigHalJsonBasicAuthTest extends FieldStorageConfigResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal', 'basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\field\Functional\Rest\FieldStorageConfigResourceTestBase;
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class FieldStorageConfigHalJsonCookieTest extends FieldStorageConfigResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
197
web/core/modules/field/tests/src/Functional/NestedFormTest.php
Normal file
197
web/core/modules/field/tests/src/Functional/NestedFormTest.php
Normal file
|
@ -0,0 +1,197 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional;
|
||||
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Tests field elements in nested forms.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class NestedFormTest extends FieldTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['field_test', 'entity_test'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$web_user = $this->drupalCreateUser(['view test entity', 'administer entity_test content']);
|
||||
$this->drupalLogin($web_user);
|
||||
|
||||
$this->fieldStorageSingle = [
|
||||
'field_name' => 'field_single',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
];
|
||||
$this->fieldStorageUnlimited = [
|
||||
'field_name' => 'field_unlimited',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
];
|
||||
|
||||
$this->field = [
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
'label' => $this->randomMachineName() . '_label',
|
||||
'description' => '[site:name]_description',
|
||||
'weight' => mt_rand(0, 127),
|
||||
'settings' => [
|
||||
'test_field_setting' => $this->randomMachineName(),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Field API form integration within a subform.
|
||||
*/
|
||||
public function testNestedFieldForm() {
|
||||
// Add two fields on the 'entity_test'
|
||||
FieldStorageConfig::create($this->fieldStorageSingle)->save();
|
||||
FieldStorageConfig::create($this->fieldStorageUnlimited)->save();
|
||||
$this->field['field_name'] = 'field_single';
|
||||
$this->field['label'] = 'Single field';
|
||||
FieldConfig::create($this->field)->save();
|
||||
entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
|
||||
->setComponent($this->field['field_name'])
|
||||
->save();
|
||||
$this->field['field_name'] = 'field_unlimited';
|
||||
$this->field['label'] = 'Unlimited field';
|
||||
FieldConfig::create($this->field)->save();
|
||||
entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
|
||||
->setComponent($this->field['field_name'])
|
||||
->save();
|
||||
|
||||
// Create two entities.
|
||||
$entity_type = 'entity_test';
|
||||
$storage = $this->container->get('entity_type.manager')
|
||||
->getStorage($entity_type);
|
||||
|
||||
$entity_1 = $storage->create(['id' => 1]);
|
||||
$entity_1->enforceIsNew();
|
||||
$entity_1->field_single->value = 0;
|
||||
$entity_1->field_unlimited->value = 1;
|
||||
$entity_1->save();
|
||||
|
||||
$entity_2 = $storage->create(['id' => 2]);
|
||||
$entity_2->enforceIsNew();
|
||||
$entity_2->field_single->value = 10;
|
||||
$entity_2->field_unlimited->value = 11;
|
||||
$entity_2->save();
|
||||
|
||||
// Display the 'combined form'.
|
||||
$this->drupalGet('test-entity/nested/1/2');
|
||||
$this->assertFieldByName('field_single[0][value]', 0, 'Entity 1: field_single value appears correctly is the form.');
|
||||
$this->assertFieldByName('field_unlimited[0][value]', 1, 'Entity 1: field_unlimited value 0 appears correctly is the form.');
|
||||
$this->assertFieldByName('entity_2[field_single][0][value]', 10, 'Entity 2: field_single value appears correctly is the form.');
|
||||
$this->assertFieldByName('entity_2[field_unlimited][0][value]', 11, 'Entity 2: field_unlimited value 0 appears correctly is the form.');
|
||||
|
||||
// Submit the form and check that the entities are updated accordingly.
|
||||
$edit = [
|
||||
'field_single[0][value]' => 1,
|
||||
'field_unlimited[0][value]' => 2,
|
||||
'field_unlimited[1][value]' => 3,
|
||||
'entity_2[field_single][0][value]' => 11,
|
||||
'entity_2[field_unlimited][0][value]' => 12,
|
||||
'entity_2[field_unlimited][1][value]' => 13,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$entity_1 = $storage->load(1);
|
||||
$entity_2 = $storage->load(2);
|
||||
$this->assertFieldValues($entity_1, 'field_single', [1]);
|
||||
$this->assertFieldValues($entity_1, 'field_unlimited', [2, 3]);
|
||||
$this->assertFieldValues($entity_2, 'field_single', [11]);
|
||||
$this->assertFieldValues($entity_2, 'field_unlimited', [12, 13]);
|
||||
|
||||
// Submit invalid values and check that errors are reported on the
|
||||
// correct widgets.
|
||||
$edit = [
|
||||
'field_unlimited[1][value]' => -1,
|
||||
];
|
||||
$this->drupalPostForm('test-entity/nested/1/2', $edit, t('Save'));
|
||||
$this->assertRaw(t('%label does not accept the value -1', ['%label' => 'Unlimited field']), 'Entity 1: the field validation error was reported.');
|
||||
$error_field = $this->xpath('//input[@id=:id and contains(@class, "error")]', [':id' => 'edit-field-unlimited-1-value']);
|
||||
$this->assertTrue($error_field, 'Entity 1: the error was flagged on the correct element.');
|
||||
$edit = [
|
||||
'entity_2[field_unlimited][1][value]' => -1,
|
||||
];
|
||||
$this->drupalPostForm('test-entity/nested/1/2', $edit, t('Save'));
|
||||
$this->assertRaw(t('%label does not accept the value -1', ['%label' => 'Unlimited field']), 'Entity 2: the field validation error was reported.');
|
||||
$error_field = $this->xpath('//input[@id=:id and contains(@class, "error")]', [':id' => 'edit-entity-2-field-unlimited-1-value']);
|
||||
$this->assertTrue($error_field, 'Entity 2: the error was flagged on the correct element.');
|
||||
|
||||
// Test that reordering works on both entities.
|
||||
$edit = [
|
||||
'field_unlimited[0][_weight]' => 0,
|
||||
'field_unlimited[1][_weight]' => -1,
|
||||
'entity_2[field_unlimited][0][_weight]' => 0,
|
||||
'entity_2[field_unlimited][1][_weight]' => -1,
|
||||
];
|
||||
$this->drupalPostForm('test-entity/nested/1/2', $edit, t('Save'));
|
||||
$this->assertFieldValues($entity_1, 'field_unlimited', [3, 2]);
|
||||
$this->assertFieldValues($entity_2, 'field_unlimited', [13, 12]);
|
||||
|
||||
// Test the 'add more' buttons.
|
||||
// 'Add more' button in the first entity:
|
||||
$this->drupalGet('test-entity/nested/1/2');
|
||||
$this->drupalPostForm(NULL, [], 'field_unlimited_add_more');
|
||||
$this->assertFieldByName('field_unlimited[0][value]', 3, 'Entity 1: field_unlimited value 0 appears correctly is the form.');
|
||||
$this->assertFieldByName('field_unlimited[1][value]', 2, 'Entity 1: field_unlimited value 1 appears correctly is the form.');
|
||||
$this->assertFieldByName('field_unlimited[2][value]', '', 'Entity 1: field_unlimited value 2 appears correctly is the form.');
|
||||
$this->assertFieldByName('field_unlimited[3][value]', '', 'Entity 1: an empty widget was added for field_unlimited value 3.');
|
||||
// 'Add more' button in the first entity (changing field values):
|
||||
$edit = [
|
||||
'entity_2[field_unlimited][0][value]' => 13,
|
||||
'entity_2[field_unlimited][1][value]' => 14,
|
||||
'entity_2[field_unlimited][2][value]' => 15,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, 'entity_2_field_unlimited_add_more');
|
||||
$this->assertFieldByName('entity_2[field_unlimited][0][value]', 13, 'Entity 2: field_unlimited value 0 appears correctly is the form.');
|
||||
$this->assertFieldByName('entity_2[field_unlimited][1][value]', 14, 'Entity 2: field_unlimited value 1 appears correctly is the form.');
|
||||
$this->assertFieldByName('entity_2[field_unlimited][2][value]', 15, 'Entity 2: field_unlimited value 2 appears correctly is the form.');
|
||||
$this->assertFieldByName('entity_2[field_unlimited][3][value]', '', 'Entity 2: an empty widget was added for field_unlimited value 3.');
|
||||
// Save the form and check values are saved correctly.
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
$this->assertFieldValues($entity_1, 'field_unlimited', [3, 2]);
|
||||
$this->assertFieldValues($entity_2, 'field_unlimited', [13, 14, 15]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests entity level validation within subforms.
|
||||
*/
|
||||
public function testNestedEntityFormEntityLevelValidation() {
|
||||
// Create two entities.
|
||||
$storage = $this->container->get('entity_type.manager')
|
||||
->getStorage('entity_test_constraints');
|
||||
|
||||
$entity_1 = $storage->create();
|
||||
$entity_1->save();
|
||||
|
||||
$entity_2 = $storage->create();
|
||||
$entity_2->save();
|
||||
|
||||
$page = $this->getSession()->getPage();
|
||||
$assert_session = $this->assertSession();
|
||||
|
||||
// Display the 'combined form'.
|
||||
$this->drupalGet("test-entity-constraints/nested/{$entity_1->id()}/{$entity_2->id()}");
|
||||
$assert_session->hiddenFieldValueEquals('entity_2[changed]', REQUEST_TIME);
|
||||
|
||||
// Submit the form and check that the entities are updated accordingly.
|
||||
$assert_session->hiddenFieldExists('entity_2[changed]')
|
||||
->setValue(REQUEST_TIME - 86400);
|
||||
$page->pressButton(t('Save'));
|
||||
|
||||
$elements = $this->cssSelect('.entity-2.error');
|
||||
$this->assertEqual(1, count($elements), 'The whole nested entity form has been correctly flagged with an error class.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,429 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Number;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the creation of numeric fields.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class NumberFieldTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node', 'entity_test', 'field_ui'];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->drupalLogin($this->drupalCreateUser([
|
||||
'view test entity',
|
||||
'administer entity_test content',
|
||||
'administer content types',
|
||||
'administer node fields',
|
||||
'administer node display',
|
||||
'bypass node access',
|
||||
'administer entity_test fields',
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test decimal field.
|
||||
*/
|
||||
public function testNumberDecimalField() {
|
||||
// Create a field with settings to validate.
|
||||
$field_name = mb_strtolower($this->randomMachineName());
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'decimal',
|
||||
'settings' => ['precision' => 8, 'scale' => 4],
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
])->save();
|
||||
|
||||
entity_get_form_display('entity_test', 'entity_test', 'default')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'number',
|
||||
'settings' => [
|
||||
'placeholder' => '0.00',
|
||||
],
|
||||
])
|
||||
->save();
|
||||
entity_get_display('entity_test', 'entity_test', 'default')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'number_decimal',
|
||||
])
|
||||
->save();
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet('entity_test/add');
|
||||
$this->assertFieldByName("{$field_name}[0][value]", '', 'Widget is displayed');
|
||||
$this->assertRaw('placeholder="0.00"');
|
||||
|
||||
// Submit a signed decimal value within the allowed precision and scale.
|
||||
$value = '-1234.5678';
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $value,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', ['@id' => $id]), 'Entity was created');
|
||||
$this->assertRaw($value, 'Value is displayed.');
|
||||
|
||||
// Try to create entries with more than one decimal separator; assert fail.
|
||||
$wrong_entries = [
|
||||
'3.14.159',
|
||||
'0..45469',
|
||||
'..4589',
|
||||
'6.459.52',
|
||||
'6.3..25',
|
||||
];
|
||||
|
||||
foreach ($wrong_entries as $wrong_entry) {
|
||||
$this->drupalGet('entity_test/add');
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $wrong_entry,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertRaw(t('%name must be a number.', ['%name' => $field_name]), 'Correctly failed to save decimal value with more than one decimal point.');
|
||||
}
|
||||
|
||||
// Try to create entries with minus sign not in the first position.
|
||||
$wrong_entries = [
|
||||
'3-3',
|
||||
'4-',
|
||||
'1.3-',
|
||||
'1.2-4',
|
||||
'-10-10',
|
||||
];
|
||||
|
||||
foreach ($wrong_entries as $wrong_entry) {
|
||||
$this->drupalGet('entity_test/add');
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $wrong_entry,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertRaw(t('%name must be a number.', ['%name' => $field_name]), 'Correctly failed to save decimal value with minus sign in the wrong position.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test integer field.
|
||||
*/
|
||||
public function testNumberIntegerField() {
|
||||
$minimum = rand(-4000, -2000);
|
||||
$maximum = rand(2000, 4000);
|
||||
|
||||
// Create a field with settings to validate.
|
||||
$field_name = mb_strtolower($this->randomMachineName());
|
||||
$storage = FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'integer',
|
||||
]);
|
||||
$storage->save();
|
||||
|
||||
FieldConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
'settings' => [
|
||||
'min' => $minimum,
|
||||
'max' => $maximum,
|
||||
'prefix' => 'ThePrefix',
|
||||
],
|
||||
])->save();
|
||||
|
||||
entity_get_form_display('entity_test', 'entity_test', 'default')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'number',
|
||||
'settings' => [
|
||||
'placeholder' => '4',
|
||||
],
|
||||
])
|
||||
->save();
|
||||
entity_get_display('entity_test', 'entity_test', 'default')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'number_integer',
|
||||
'settings' => [
|
||||
'prefix_suffix' => FALSE,
|
||||
],
|
||||
])
|
||||
->save();
|
||||
|
||||
// Check the storage schema.
|
||||
$expected = [
|
||||
'columns' => [
|
||||
'value' => [
|
||||
'type' => 'int',
|
||||
'unsigned' => '',
|
||||
'size' => 'normal',
|
||||
],
|
||||
],
|
||||
'unique keys' => [],
|
||||
'indexes' => [],
|
||||
'foreign keys' => [],
|
||||
];
|
||||
$this->assertEqual($storage->getSchema(), $expected);
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet('entity_test/add');
|
||||
$this->assertFieldByName("{$field_name}[0][value]", '', 'Widget is displayed');
|
||||
$this->assertRaw('placeholder="4"');
|
||||
|
||||
// Submit a valid integer
|
||||
$value = rand($minimum, $maximum);
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $value,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', ['@id' => $id]), 'Entity was created');
|
||||
|
||||
// Try to set a value below the minimum value
|
||||
$this->drupalGet('entity_test/add');
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $minimum - 1,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertRaw(t('%name must be higher than or equal to %minimum.', ['%name' => $field_name, '%minimum' => $minimum]), 'Correctly failed to save integer value less than minimum allowed value.');
|
||||
|
||||
// Try to set a decimal value
|
||||
$this->drupalGet('entity_test/add');
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => 1.5,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertRaw(t('%name is not a valid number.', ['%name' => $field_name]), 'Correctly failed to save decimal value to integer field.');
|
||||
|
||||
// Try to set a value above the maximum value
|
||||
$this->drupalGet('entity_test/add');
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $maximum + 1,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertRaw(t('%name must be lower than or equal to %maximum.', ['%name' => $field_name, '%maximum' => $maximum]), 'Correctly failed to save integer value greater than maximum allowed value.');
|
||||
|
||||
// Try to set a wrong integer value.
|
||||
$this->drupalGet('entity_test/add');
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => '20-40',
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertRaw(t('%name must be a number.', ['%name' => $field_name]), 'Correctly failed to save wrong integer value.');
|
||||
|
||||
// Test with valid entries.
|
||||
$valid_entries = [
|
||||
'-1234',
|
||||
'0',
|
||||
'1234',
|
||||
];
|
||||
|
||||
foreach ($valid_entries as $valid_entry) {
|
||||
$this->drupalGet('entity_test/add');
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $valid_entry,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', ['@id' => $id]), 'Entity was created');
|
||||
$this->assertRaw($valid_entry, 'Value is displayed.');
|
||||
$this->assertNoFieldByXpath('//div[@content="' . $valid_entry . '"]', NULL, 'The "content" attribute is not present since the Prefix is not being displayed');
|
||||
}
|
||||
|
||||
// Test for the content attribute when a Prefix is displayed. Presumably this also tests for the attribute when a Suffix is displayed.
|
||||
entity_get_display('entity_test', 'entity_test', 'default')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'number_integer',
|
||||
'settings' => [
|
||||
'prefix_suffix' => TRUE,
|
||||
],
|
||||
])
|
||||
->save();
|
||||
$integer_value = '123';
|
||||
$this->drupalGet('entity_test/add');
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $integer_value,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', ['@id' => $id]), 'Entity was created');
|
||||
$this->drupalGet('entity_test/' . $id);
|
||||
$this->assertFieldByXPath('//div[@content="' . $integer_value . '"]', 'ThePrefix' . $integer_value, 'The "content" attribute has been set to the value of the field, and the prefix is being displayed.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test float field.
|
||||
*/
|
||||
public function testNumberFloatField() {
|
||||
// Create a field with settings to validate.
|
||||
$field_name = mb_strtolower($this->randomMachineName());
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'float',
|
||||
])->save();
|
||||
|
||||
FieldConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
])->save();
|
||||
|
||||
entity_get_form_display('entity_test', 'entity_test', 'default')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'number',
|
||||
'settings' => [
|
||||
'placeholder' => '0.00',
|
||||
],
|
||||
])
|
||||
->save();
|
||||
|
||||
entity_get_display('entity_test', 'entity_test', 'default')
|
||||
->setComponent($field_name, [
|
||||
'type' => 'number_decimal',
|
||||
])
|
||||
->save();
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet('entity_test/add');
|
||||
$this->assertFieldByName("{$field_name}[0][value]", '', 'Widget is displayed');
|
||||
$this->assertRaw('placeholder="0.00"');
|
||||
|
||||
// Submit a signed decimal value within the allowed precision and scale.
|
||||
$value = '-1234.5678';
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $value,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', ['@id' => $id]), 'Entity was created');
|
||||
|
||||
// Ensure that the 'number_decimal' formatter displays the number with the
|
||||
// expected rounding.
|
||||
$this->drupalGet('entity_test/' . $id);
|
||||
$this->assertRaw(round($value, 2));
|
||||
|
||||
// Try to create entries with more than one decimal separator; assert fail.
|
||||
$wrong_entries = [
|
||||
'3.14.159',
|
||||
'0..45469',
|
||||
'..4589',
|
||||
'6.459.52',
|
||||
'6.3..25',
|
||||
];
|
||||
|
||||
foreach ($wrong_entries as $wrong_entry) {
|
||||
$this->drupalGet('entity_test/add');
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $wrong_entry,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertRaw(t('%name must be a number.', ['%name' => $field_name]), 'Correctly failed to save float value with more than one decimal point.');
|
||||
}
|
||||
|
||||
// Try to create entries with minus sign not in the first position.
|
||||
$wrong_entries = [
|
||||
'3-3',
|
||||
'4-',
|
||||
'1.3-',
|
||||
'1.2-4',
|
||||
'-10-10',
|
||||
];
|
||||
|
||||
foreach ($wrong_entries as $wrong_entry) {
|
||||
$this->drupalGet('entity_test/add');
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $wrong_entry,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertRaw(t('%name must be a number.', ['%name' => $field_name]), 'Correctly failed to save float value with minus sign in the wrong position.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests setting the minimum value of a float field through the interface.
|
||||
*/
|
||||
public function testCreateNumberFloatField() {
|
||||
// Create a float field.
|
||||
$field_name = mb_strtolower($this->randomMachineName());
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'float',
|
||||
])->save();
|
||||
|
||||
$field = FieldConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
]);
|
||||
$field->save();
|
||||
|
||||
// Set the minimum value to a float value.
|
||||
$this->assertSetMinimumValue($field, 0.0001);
|
||||
// Set the minimum value to an integer value.
|
||||
$this->assertSetMinimumValue($field, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests setting the minimum value of a decimal field through the interface.
|
||||
*/
|
||||
public function testCreateNumberDecimalField() {
|
||||
// Create a decimal field.
|
||||
$field_name = mb_strtolower($this->randomMachineName());
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'decimal',
|
||||
])->save();
|
||||
|
||||
$field = FieldConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
]);
|
||||
$field->save();
|
||||
|
||||
// Set the minimum value to a decimal value.
|
||||
$this->assertSetMinimumValue($field, 0.1);
|
||||
// Set the minimum value to an integer value.
|
||||
$this->assertSetMinimumValue($field, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to set the minimum value of a field.
|
||||
*/
|
||||
public function assertSetMinimumValue($field, $minimum_value) {
|
||||
$field_configuration_url = 'entity_test/structure/entity_test/fields/entity_test.entity_test.' . $field->getName();
|
||||
|
||||
// Set the minimum value.
|
||||
$edit = [
|
||||
'settings[min]' => $minimum_value,
|
||||
];
|
||||
$this->drupalPostForm($field_configuration_url, $edit, t('Save settings'));
|
||||
// Check if an error message is shown.
|
||||
$this->assertNoRaw(t('%name is not a valid number.', ['%name' => t('Minimum')]), 'Saved ' . gettype($minimum_value) . ' value as minimal value on a ' . $field->getType() . ' field');
|
||||
// Check if a success message is shown.
|
||||
$this->assertRaw(t('Saved %label configuration.', ['%label' => $field->getLabel()]));
|
||||
// Check if the minimum value was actually set.
|
||||
$this->drupalGet($field_configuration_url);
|
||||
$this->assertFieldById('edit-settings-min', $minimum_value, 'Minimal ' . gettype($minimum_value) . ' value was set on a ' . $field->getType() . ' field.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class FieldConfigJsonAnonTest extends FieldConfigResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class FieldConfigJsonBasicAuthTest extends FieldConfigResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class FieldConfigJsonCookieTest extends FieldConfigResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Rest;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
|
||||
|
||||
abstract class FieldConfigResourceTestBase extends EntityResourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['field', 'node'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $entityTypeId = 'field_config';
|
||||
|
||||
/**
|
||||
* @var \Drupal\field\FieldConfigInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpAuthorization($method) {
|
||||
$this->grantPermissionsToTestedRole(['administer node fields']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createEntity() {
|
||||
$camelids = NodeType::create([
|
||||
'name' => 'Camelids',
|
||||
'type' => 'camelids',
|
||||
]);
|
||||
$camelids->save();
|
||||
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => 'field_llama',
|
||||
'entity_type' => 'node',
|
||||
'type' => 'text',
|
||||
]);
|
||||
$field_storage->save();
|
||||
|
||||
$entity = FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'camelids',
|
||||
]);
|
||||
$entity->save();
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedNormalizedEntity() {
|
||||
return [
|
||||
'bundle' => 'camelids',
|
||||
'default_value' => [],
|
||||
'default_value_callback' => '',
|
||||
'dependencies' => [
|
||||
'config' => [
|
||||
'field.storage.node.field_llama',
|
||||
'node.type.camelids',
|
||||
],
|
||||
'module' => [
|
||||
'text',
|
||||
],
|
||||
],
|
||||
'description' => '',
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'field_llama',
|
||||
'field_type' => 'text',
|
||||
'id' => 'node.camelids.field_llama',
|
||||
'label' => 'field_llama',
|
||||
'langcode' => 'en',
|
||||
'required' => FALSE,
|
||||
'settings' => [],
|
||||
'status' => TRUE,
|
||||
'translatable' => TRUE,
|
||||
'uuid' => $this->entity->uuid(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNormalizedPostEntity() {
|
||||
// @todo Update in https://www.drupal.org/node/2300677.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedCacheContexts() {
|
||||
return [
|
||||
'user.permissions',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedUnauthorizedAccessMessage($method) {
|
||||
if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
|
||||
return parent::getExpectedUnauthorizedAccessMessage($method);
|
||||
}
|
||||
|
||||
return "The 'administer node fields' permission is required.";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class FieldConfigXmlAnonTest extends FieldConfigResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class FieldConfigXmlBasicAuthTest extends FieldConfigResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class FieldConfigXmlCookieTest extends FieldConfigResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class FieldStorageConfigJsonAnonTest extends FieldStorageConfigResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class FieldStorageConfigJsonBasicAuthTest extends FieldStorageConfigResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class FieldStorageConfigJsonCookieTest extends FieldStorageConfigResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Rest;
|
||||
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
|
||||
|
||||
abstract class FieldStorageConfigResourceTestBase extends EntityResourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $entityTypeId = 'field_storage_config';
|
||||
|
||||
/**
|
||||
* @var \Drupal\field\FieldConfigStorage
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpAuthorization($method) {
|
||||
$this->grantPermissionsToTestedRole(['administer node fields']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createEntity() {
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => 'true_llama',
|
||||
'entity_type' => 'node',
|
||||
'type' => 'boolean',
|
||||
]);
|
||||
$field_storage->save();
|
||||
return $field_storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedNormalizedEntity() {
|
||||
return [
|
||||
'cardinality' => 1,
|
||||
'custom_storage' => FALSE,
|
||||
'dependencies' => [
|
||||
'module' => ['node'],
|
||||
],
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'true_llama',
|
||||
'id' => 'node.true_llama',
|
||||
'indexes' => [],
|
||||
'langcode' => 'en',
|
||||
'locked' => FALSE,
|
||||
'module' => 'core',
|
||||
'persist_with_no_fields' => FALSE,
|
||||
'settings' => [],
|
||||
'status' => TRUE,
|
||||
'translatable' => TRUE,
|
||||
'type' => 'boolean',
|
||||
'uuid' => $this->entity->uuid(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNormalizedPostEntity() {
|
||||
// @todo Update in https://www.drupal.org/node/2300677.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedUnauthorizedAccessMessage($method) {
|
||||
if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
|
||||
return parent::getExpectedUnauthorizedAccessMessage($method);
|
||||
}
|
||||
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
return "The 'administer node fields' permission is required.";
|
||||
|
||||
default:
|
||||
return parent::getExpectedUnauthorizedAccessMessage($method);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedCacheContexts() {
|
||||
return [
|
||||
'user.permissions',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class FieldStorageConfigXmlAnonTest extends FieldStorageConfigResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class FieldStorageConfigXmlBasicAuthTest extends FieldStorageConfigResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class FieldStorageConfigXmlCookieTest extends FieldStorageConfigResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\String;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests the creation of string fields.
|
||||
*
|
||||
* @group text
|
||||
*/
|
||||
class StringFieldTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['entity_test', 'file'];
|
||||
|
||||
/**
|
||||
* A user without any special permissions.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $webUser;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->webUser = $this->drupalCreateUser(['view test entity', 'administer entity_test content', 'access content']);
|
||||
$this->drupalLogin($this->webUser);
|
||||
}
|
||||
|
||||
// Test fields.
|
||||
|
||||
/**
|
||||
* Test widgets.
|
||||
*/
|
||||
public function testTextfieldWidgets() {
|
||||
$this->_testTextfieldWidgets('string', 'string_textfield');
|
||||
$this->_testTextfieldWidgets('string_long', 'string_textarea');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for testTextfieldWidgets().
|
||||
*/
|
||||
public function _testTextfieldWidgets($field_type, $widget_type) {
|
||||
// Create a field.
|
||||
$field_name = mb_strtolower($this->randomMachineName());
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => $field_type,
|
||||
]);
|
||||
$field_storage->save();
|
||||
FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'entity_test',
|
||||
'label' => $this->randomMachineName() . '_label',
|
||||
])->save();
|
||||
entity_get_form_display('entity_test', 'entity_test', 'default')
|
||||
->setComponent($field_name, [
|
||||
'type' => $widget_type,
|
||||
'settings' => [
|
||||
'placeholder' => 'A placeholder on ' . $widget_type,
|
||||
],
|
||||
])
|
||||
->save();
|
||||
entity_get_display('entity_test', 'entity_test', 'full')
|
||||
->setComponent($field_name)
|
||||
->save();
|
||||
|
||||
// Display creation form.
|
||||
$this->drupalGet('entity_test/add');
|
||||
$this->assertFieldByName("{$field_name}[0][value]", '', 'Widget is displayed');
|
||||
$this->assertNoFieldByName("{$field_name}[0][format]", '1', 'Format selector is not displayed');
|
||||
$this->assertRaw(format_string('placeholder="A placeholder on @widget_type"', ['@widget_type' => $widget_type]));
|
||||
|
||||
// Submit with some value.
|
||||
$value = $this->randomMachineName();
|
||||
$edit = [
|
||||
"{$field_name}[0][value]" => $value,
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match);
|
||||
$id = $match[1];
|
||||
$this->assertText(t('entity_test @id has been created.', ['@id' => $id]), 'Entity was created');
|
||||
|
||||
// Display the entity.
|
||||
$entity = EntityTest::load($id);
|
||||
$display = entity_get_display($entity->getEntityTypeId(), $entity->bundle(), 'full');
|
||||
$content = $display->build($entity);
|
||||
$rendered_entity = \Drupal::service('renderer')->renderRoot($content);
|
||||
$this->assertContains($value, (string) $rendered_entity);
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Drupal\Tests\field\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
|
@ -52,7 +51,7 @@ class TranslationWebTest extends FieldTestBase {
|
|||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->fieldName = Unicode::strtolower($this->randomMachineName() . '_field_name');
|
||||
$this->fieldName = mb_strtolower($this->randomMachineName() . '_field_name');
|
||||
|
||||
$field_storage = [
|
||||
'field_name' => $this->fieldName,
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Update;
|
||||
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
|
||||
/**
|
||||
* Tests the update for the 'size' setting of the 'email_default' field widget.
|
||||
*
|
||||
* @group field
|
||||
* @group legacy
|
||||
*/
|
||||
class EmailWidgetSizeSettingUpdateTest extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
|
||||
__DIR__ . '/../../../fixtures/update/drupal-8.email_widget_size_setting-2578741.php',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests field_post_update_email_widget_size_setting().
|
||||
*
|
||||
* @see field_post_update_email_widget_size_setting()
|
||||
*/
|
||||
public function testFieldPostUpdateEmailWidgetSizeSetting() {
|
||||
$configFactory = $this->container->get('config.factory');
|
||||
|
||||
// Load the 'node.article.default' entity form display and check that the
|
||||
// widget for 'field_email_2578741' does not have a 'size' setting.
|
||||
/** @var \Drupal\Core\Config\Config $config */
|
||||
$config = $configFactory->get('core.entity_form_display.node.article.default');
|
||||
$settings = $config->get('content.field_email_2578741.settings');
|
||||
$this->assertTrue(!isset($settings['size']), 'The size setting does not exist prior to running the update functions.');
|
||||
|
||||
// Run updates.
|
||||
$this->runUpdates();
|
||||
|
||||
// Reload the config and check that the 'size' setting has been populated.
|
||||
$config = $configFactory->get('core.entity_form_display.node.article.default');
|
||||
$settings = $config->get('content.field_email_2578741.settings');
|
||||
$this->assertEqual($settings['size'], 60, 'The size setting exists and it has the correct default value.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Update;
|
||||
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
|
||||
/**
|
||||
* Tests the update for the entity reference 'handler' setting.
|
||||
*
|
||||
* @group field
|
||||
* @group legacy
|
||||
*/
|
||||
class EntityReferenceHandlerSettingUpdateTest extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests field_post_update_entity_reference_handler_setting().
|
||||
*
|
||||
* @see field_post_update_entity_reference_handler_setting()
|
||||
*/
|
||||
public function testFieldPostUpdateERHandlerSetting() {
|
||||
$configFactory = $this->container->get('config.factory');
|
||||
|
||||
// Load the 'node.article.field_image' field config, and check that its
|
||||
// 'handler' setting is wrong.
|
||||
/** @var \Drupal\Core\Config\Config */
|
||||
$config = $configFactory->get('field.field.node.article.field_image');
|
||||
$settings = $config->get('settings');
|
||||
$this->assertEqual($settings['handler'], 'default:node');
|
||||
|
||||
// Run updates.
|
||||
$this->runUpdates();
|
||||
|
||||
// Reload the config, and check that the 'handler' setting has been fixed.
|
||||
$config = $configFactory->get('field.field.node.article.field_image');
|
||||
$settings = $config->get('settings');
|
||||
$this->assertEqual($settings['handler'], 'default:file');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,272 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Update;
|
||||
|
||||
use Drupal\Core\Config\Config;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\Tests\Traits\Core\CronRunTrait;
|
||||
|
||||
/**
|
||||
* Tests that field settings are properly updated during database updates.
|
||||
*
|
||||
* @group field
|
||||
* @group legacy
|
||||
*/
|
||||
class FieldUpdateTest extends UpdatePathTestBase {
|
||||
|
||||
use CronRunTrait;
|
||||
|
||||
/**
|
||||
* The config factory service.
|
||||
*
|
||||
* @var \Drupal\Core\Config\ConfigFactoryInterface
|
||||
*/
|
||||
protected $configFactory;
|
||||
|
||||
/**
|
||||
* The database connection.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $database;
|
||||
|
||||
/**
|
||||
* The key-value collection for tracking installed storage schema.
|
||||
*
|
||||
* @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface
|
||||
*/
|
||||
protected $installedStorageSchema;
|
||||
|
||||
/**
|
||||
* The state service.
|
||||
*
|
||||
* @var \Drupal\Core\State\StateInterface
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* The deleted fields repository.
|
||||
*
|
||||
* @var \Drupal\Core\Field\DeletedFieldsRepositoryInterface
|
||||
*/
|
||||
protected $deletedFieldsRepository;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->configFactory = $this->container->get('config.factory');
|
||||
$this->database = $this->container->get('database');
|
||||
$this->installedStorageSchema = $this->container->get('keyvalue')->get('entity.storage_schema.sql');
|
||||
$this->state = $this->container->get('state');
|
||||
$this->deletedFieldsRepository = $this->container->get('entity_field.deleted_fields_repository');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
|
||||
__DIR__ . '/../../../fixtures/update/drupal-8.views_entity_reference_plugins-2429191.php',
|
||||
__DIR__ . '/../../../fixtures/update/drupal-8.remove_handler_submit_setting-2715589.php',
|
||||
__DIR__ . '/../../../fixtures/update/drupal-8.update_deleted_field_definitions-2931436.php',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests field_update_8001().
|
||||
*
|
||||
* @see field_update_8001()
|
||||
*/
|
||||
public function testFieldUpdate8001() {
|
||||
// Load the 'node.field_image' field storage config, and check that is has
|
||||
// a 'target_bundle' setting.
|
||||
$config = $this->configFactory->get('field.storage.node.field_image');
|
||||
$settings = $config->get('settings');
|
||||
$this->assertTrue(array_key_exists('target_bundle', $settings));
|
||||
|
||||
// Run updates.
|
||||
$this->runUpdates();
|
||||
|
||||
// Reload the config, and check that the 'target_bundle' setting has been
|
||||
// removed.
|
||||
$config = $this->configFactory->get('field.storage.node.field_image');
|
||||
$settings = $config->get('settings');
|
||||
$this->assertFalse(array_key_exists('target_bundle', $settings));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests field_update_8002().
|
||||
*
|
||||
* @see field_update_8002()
|
||||
*/
|
||||
public function testFieldUpdate8002() {
|
||||
// Check that 'entity_reference' is the provider and a dependency of the
|
||||
// test field storage .
|
||||
$field_storage = $this->configFactory->get('field.storage.node.field_ref_views_select_2429191');
|
||||
$this->assertIdentical($field_storage->get('module'), 'entity_reference');
|
||||
$this->assertEntityRefDependency($field_storage, TRUE);
|
||||
|
||||
// Check that 'entity_reference' is a dependency of the test field.
|
||||
$field = $this->configFactory->get('field.field.node.article.field_ref_views_select_2429191');
|
||||
$this->assertEntityRefDependency($field, TRUE);
|
||||
|
||||
// Check that 'entity_reference' is a dependency of the test view.
|
||||
$view = $this->configFactory->get('views.view.entity_reference_plugins_2429191');
|
||||
$this->assertEntityRefDependency($view, TRUE);
|
||||
|
||||
// Run updates.
|
||||
$this->runUpdates();
|
||||
|
||||
// Check that 'entity_reference' is no longer a dependency of the test field
|
||||
// and view.
|
||||
$field_storage = $this->configFactory->get('field.storage.node.field_ref_views_select_2429191');
|
||||
$this->assertIdentical($field_storage->get('module'), 'core');
|
||||
$this->assertEntityRefDependency($field_storage, FALSE);
|
||||
$field = $this->configFactory->get('field.field.node.article.field_ref_views_select_2429191');
|
||||
$this->assertEntityRefDependency($field, FALSE);
|
||||
$view = $this->configFactory->get('views.view.entity_reference_plugins_2429191');
|
||||
$this->assertEntityRefDependency($view, FALSE);
|
||||
|
||||
// Check that field selection, based on the view, still works. It only
|
||||
// selects nodes whose title contains 'foo'.
|
||||
$node_1 = Node::create(['type' => 'article', 'title' => 'foobar']);
|
||||
$node_1->save();
|
||||
$node_2 = Node::create(['type' => 'article', 'title' => 'barbaz']);
|
||||
$node_2->save();
|
||||
$field = FieldConfig::load('node.article.field_ref_views_select_2429191');
|
||||
$selection = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($field);
|
||||
$referencable = $selection->getReferenceableEntities();
|
||||
$this->assertEqual(array_keys($referencable['article']), [$node_1->id()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests field_update_8003().
|
||||
*
|
||||
* @see field_update_8003()
|
||||
*/
|
||||
public function testFieldUpdate8003() {
|
||||
// Run updates.
|
||||
$this->runUpdates();
|
||||
|
||||
// Check that the new 'auto_create_bundle' setting is populated correctly.
|
||||
$field = $this->configFactory->get('field.field.node.article.field_ref_autocreate_2412569');
|
||||
$handler_settings = $field->get('settings.handler_settings');
|
||||
|
||||
$expected_target_bundles = ['tags' => 'tags', 'test' => 'test'];
|
||||
$this->assertEqual($handler_settings['target_bundles'], $expected_target_bundles);
|
||||
|
||||
$this->assertTrue($handler_settings['auto_create']);
|
||||
$this->assertEqual($handler_settings['auto_create_bundle'], 'tags');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests field_update_8500().
|
||||
*
|
||||
* @see field_update_8500()
|
||||
*/
|
||||
public function testFieldUpdate8500() {
|
||||
$field_name = 'field_test';
|
||||
$field_uuid = '5d0d9870-560b-46c4-b838-0dcded0502dd';
|
||||
$field_storage_uuid = 'ce93d7c2-1da7-4a2c-9e6d-b4925e3b129f';
|
||||
|
||||
// Check that we have pre-existing entries for 'field.field.deleted' and
|
||||
// 'field.storage.deleted'.
|
||||
$deleted_fields = $this->state->get('field.field.deleted');
|
||||
$this->assertCount(1, $deleted_fields);
|
||||
$this->assertArrayHasKey($field_uuid, $deleted_fields);
|
||||
|
||||
$deleted_field_storages = $this->state->get('field.storage.deleted');
|
||||
$this->assertCount(1, $deleted_field_storages);
|
||||
$this->assertArrayHasKey($field_storage_uuid, $deleted_field_storages);
|
||||
|
||||
// Ensure that cron does not run automatically after running the updates.
|
||||
$this->state->set('system.cron_last', REQUEST_TIME + 100);
|
||||
|
||||
// Run updates.
|
||||
$this->runUpdates();
|
||||
|
||||
// Now that we can use the API, check that the "delete fields" state entries
|
||||
// have been converted to proper field definition objects.
|
||||
$deleted_fields = $this->deletedFieldsRepository->getFieldDefinitions();
|
||||
|
||||
$this->assertCount(1, $deleted_fields);
|
||||
$this->assertArrayHasKey($field_uuid, $deleted_fields);
|
||||
$this->assertTrue($deleted_fields[$field_uuid] instanceof FieldDefinitionInterface);
|
||||
$this->assertEquals($field_name, $deleted_fields[$field_uuid]->getName());
|
||||
|
||||
$deleted_field_storages = $this->deletedFieldsRepository->getFieldStorageDefinitions();
|
||||
$this->assertCount(1, $deleted_field_storages);
|
||||
$this->assertArrayHasKey($field_storage_uuid, $deleted_field_storages);
|
||||
$this->assertTrue($deleted_field_storages[$field_storage_uuid] instanceof FieldStorageDefinitionInterface);
|
||||
$this->assertEquals($field_name, $deleted_field_storages[$field_storage_uuid]->getName());
|
||||
|
||||
// Check that the installed storage schema still exists.
|
||||
$this->assertNotNull($this->installedStorageSchema->get("node.field_schema_data.$field_name"));
|
||||
|
||||
// Check that the deleted field tables exist.
|
||||
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
|
||||
$table_mapping = \Drupal::entityTypeManager()->getStorage('node')->getTableMapping();
|
||||
|
||||
$deleted_field_data_table_name = $table_mapping->getDedicatedDataTableName($deleted_field_storages[$field_storage_uuid], TRUE);
|
||||
$this->assertTrue($this->database->schema()->tableExists($deleted_field_data_table_name));
|
||||
$deleted_field_revision_table_name = $table_mapping->getDedicatedRevisionTableName($deleted_field_storages[$field_storage_uuid], TRUE);
|
||||
$this->assertTrue($this->database->schema()->tableExists($deleted_field_revision_table_name));
|
||||
|
||||
// Run cron and repeat the checks above.
|
||||
$this->cronRun();
|
||||
|
||||
$deleted_fields = $this->deletedFieldsRepository->getFieldDefinitions();
|
||||
$this->assertCount(0, $deleted_fields);
|
||||
|
||||
$deleted_field_storages = $this->deletedFieldsRepository->getFieldStorageDefinitions();
|
||||
$this->assertCount(0, $deleted_field_storages);
|
||||
|
||||
// Check that the installed storage schema has been deleted.
|
||||
$this->assertNull($this->installedStorageSchema->get("node.field_schema_data.$field_name"));
|
||||
|
||||
// Check that the deleted field tables have been deleted.
|
||||
$this->assertFalse($this->database->schema()->tableExists($deleted_field_data_table_name));
|
||||
$this->assertFalse($this->database->schema()->tableExists($deleted_field_revision_table_name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a config depends on 'entity_reference' or not
|
||||
*
|
||||
* @param \Drupal\Core\Config\Config $config
|
||||
* The config to test.
|
||||
* @param bool $present
|
||||
* TRUE to test that entity_reference is present, FALSE to test that it is
|
||||
* absent.
|
||||
*/
|
||||
protected function assertEntityRefDependency(Config $config, $present) {
|
||||
$dependencies = $config->get('dependencies');
|
||||
$dependencies += ['module' => []];
|
||||
$this->assertEqual(in_array('entity_reference', $dependencies['module']), $present);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests field_post_update_remove_handler_submit_setting().
|
||||
*
|
||||
* @see field_post_update_remove_handler_submit_setting()
|
||||
*/
|
||||
public function testEntityReferenceFieldConfigCleanUpdate() {
|
||||
$field_config = $this->config('field.field.node.article.field_tags');
|
||||
// Check that 'handler_submit' key exists in field config settings.
|
||||
$this->assertEquals('Change handler', $field_config->get('settings.handler_submit'));
|
||||
|
||||
$this->runUpdates();
|
||||
|
||||
$field_config = $this->config('field.field.node.article.field_tags');
|
||||
// Check that 'handler_submit' has been removed from field config settings.
|
||||
$this->assertArrayNotHasKey('handler_submit', $field_config->get('settings'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Views;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\Tests\views\Functional\ViewTestBase;
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Provides some helper methods for testing fieldapi integration into views.
|
||||
*
|
||||
* @todo Test on a generic entity not on a node. What has to be tested:
|
||||
* - Make sure that every wanted field is added to the according entity type.
|
||||
* - Make sure the joins are done correctly.
|
||||
* - Use basic fields and make sure that the full wanted object is built.
|
||||
* - Use relationships between different entity types, for example node and
|
||||
* the node author(user).
|
||||
*/
|
||||
abstract class FieldTestBase extends ViewTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node', 'field_test_views'];
|
||||
|
||||
/**
|
||||
* Stores the field definitions used by the test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $fieldStorages;
|
||||
|
||||
/**
|
||||
* Stores the fields of the field storage. They have the same keys as the
|
||||
* field storages.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $fields;
|
||||
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp($import_test_views);
|
||||
|
||||
// Ensure the page node type exists.
|
||||
NodeType::create([
|
||||
'type' => 'page',
|
||||
'name' => 'page',
|
||||
])->save();
|
||||
|
||||
ViewTestData::createTestViews(get_class($this), ['field_test_views']);
|
||||
}
|
||||
|
||||
public function setUpFieldStorages($amount = 3, $type = 'string') {
|
||||
// Create three fields.
|
||||
$field_names = [];
|
||||
for ($i = 0; $i < $amount; $i++) {
|
||||
$field_names[$i] = 'field_name_' . $i;
|
||||
$this->fieldStorages[$i] = FieldStorageConfig::create([
|
||||
'field_name' => $field_names[$i],
|
||||
'entity_type' => 'node',
|
||||
'type' => $type,
|
||||
]);
|
||||
$this->fieldStorages[$i]->save();
|
||||
}
|
||||
return $field_names;
|
||||
}
|
||||
|
||||
public function setUpFields($bundle = 'page') {
|
||||
foreach ($this->fieldStorages as $key => $field_storage) {
|
||||
$this->fields[$key] = FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => $bundle,
|
||||
]);
|
||||
$this->fields[$key]->save();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Views;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests the UI of the field field handler.
|
||||
*
|
||||
* @group field
|
||||
* @see \Drupal\field\Plugin\views\field\Field
|
||||
*/
|
||||
class FieldUITest extends FieldTestBase {
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_view_fieldapi'];
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['views_ui'];
|
||||
|
||||
/**
|
||||
* A user with the 'administer views' permission.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $account;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp($import_test_views);
|
||||
|
||||
$this->account = $this->drupalCreateUser(['administer views']);
|
||||
$this->drupalLogin($this->account);
|
||||
|
||||
$this->setUpFieldStorages(1, 'text');
|
||||
$this->setUpFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests basic field handler settings in the UI.
|
||||
*/
|
||||
public function testHandlerUI() {
|
||||
$url = "admin/structure/views/nojs/handler/test_view_fieldapi/default/field/field_name_0";
|
||||
$this->drupalGet($url);
|
||||
|
||||
// Tests the available formatter options.
|
||||
$result = $this->xpath('//select[@id=:id]/option', [':id' => 'edit-options-type']);
|
||||
$options = array_map(function ($item) {
|
||||
return $item->getAttribute('value');
|
||||
}, $result);
|
||||
// @todo Replace this sort by assertArray once it's in.
|
||||
sort($options, SORT_STRING);
|
||||
$this->assertEqual($options, ['text_default', 'text_trimmed'], 'The text formatters for a simple text field appear as expected.');
|
||||
|
||||
$this->drupalPostForm(NULL, ['options[type]' => 'text_trimmed'], t('Apply'));
|
||||
|
||||
$this->drupalGet($url);
|
||||
$this->assertOptionSelected('edit-options-type', 'text_trimmed');
|
||||
|
||||
$random_number = rand(100, 400);
|
||||
$this->drupalPostForm(NULL, ['options[settings][trim_length]' => $random_number], t('Apply'));
|
||||
$this->drupalGet($url);
|
||||
$this->assertFieldByName('options[settings][trim_length]', $random_number, 'The formatter setting got saved.');
|
||||
|
||||
// Save the view and test whether the settings are saved.
|
||||
$this->drupalPostForm('admin/structure/views/view/test_view_fieldapi', [], t('Save'));
|
||||
$view = Views::getView('test_view_fieldapi');
|
||||
$view->initHandlers();
|
||||
$this->assertEqual($view->field['field_name_0']->options['type'], 'text_trimmed');
|
||||
$this->assertEqual($view->field['field_name_0']->options['settings']['trim_length'], $random_number);
|
||||
|
||||
// Now change the formatter back to 'default' which doesn't have any
|
||||
// settings. We want to ensure that the settings are empty then.
|
||||
$edit['options[type]'] = 'text_default';
|
||||
$this->drupalPostForm('admin/structure/views/nojs/handler/test_view_fieldapi/default/field/field_name_0', $edit, t('Apply'));
|
||||
$this->drupalPostForm('admin/structure/views/view/test_view_fieldapi', [], t('Save'));
|
||||
$view = Views::getView('test_view_fieldapi');
|
||||
$view->initHandlers();
|
||||
$this->assertEqual($view->field['field_name_0']->options['type'], 'text_default');
|
||||
$this->assertEqual($view->field['field_name_0']->options['settings'], []);
|
||||
|
||||
// Ensure that the view depends on the field storage.
|
||||
$dependencies = \Drupal::service('config.manager')->findConfigEntityDependents('config', [$this->fieldStorages[0]->getConfigDependencyName()]);
|
||||
$this->assertTrue(isset($dependencies['views.view.test_view_fieldapi']), 'The view is dependent on the field storage.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the basic field handler form when aggregation is enabled.
|
||||
*/
|
||||
public function testHandlerUIAggregation() {
|
||||
// Enable aggregation.
|
||||
$edit = ['group_by' => '1'];
|
||||
$this->drupalPostForm('admin/structure/views/nojs/display/test_view_fieldapi/default/group_by', $edit, t('Apply'));
|
||||
|
||||
$url = "admin/structure/views/nojs/handler/test_view_fieldapi/default/field/field_name_0";
|
||||
$this->drupalGet($url);
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Test the click sort column options.
|
||||
// Tests the available formatter options.
|
||||
$result = $this->xpath('//select[@id=:id]/option', [':id' => 'edit-options-click-sort-column']);
|
||||
$options = array_map(function ($item) {
|
||||
return (string) $item->getAttribute('value');
|
||||
}, $result);
|
||||
sort($options, SORT_STRING);
|
||||
|
||||
$this->assertEqual($options, ['format', 'value'], 'The expected sort field options were found.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests adding a boolean field filter handler.
|
||||
*/
|
||||
public function testBooleanFilterHandler() {
|
||||
// Create a boolean field.
|
||||
$field_name = 'field_boolean';
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'node',
|
||||
'type' => 'boolean',
|
||||
]);
|
||||
$field_storage->save();
|
||||
$field = FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'page',
|
||||
]);
|
||||
$field->save();
|
||||
|
||||
$url = "admin/structure/views/nojs/add-handler/test_view_fieldapi/default/filter";
|
||||
$this->drupalPostForm($url, ['name[node__' . $field_name . '.' . $field_name . '_value]' => TRUE], t('Add and configure @handler', ['@handler' => t('filter criteria')]));
|
||||
$this->assertResponse(200);
|
||||
// Verify that using a boolean field as a filter also results in using the
|
||||
// boolean plugin.
|
||||
$option = $this->xpath('//label[@for="edit-options-value-1"]');
|
||||
$this->assertEqual(t('True'), $option[0]->getText());
|
||||
$option = $this->xpath('//label[@for="edit-options-value-0"]');
|
||||
$this->assertEqual(t('False'), $option[0]->getText());
|
||||
|
||||
// Expose the filter and see if the 'Any' option is added and if we can save
|
||||
// it.
|
||||
$this->drupalPostForm(NULL, [], 'Expose filter');
|
||||
$option = $this->xpath('//label[@for="edit-options-value-all"]');
|
||||
$this->assertEqual(t('- Any -'), $option[0]->getText());
|
||||
$this->drupalPostForm(NULL, ['options[value]' => 'All', 'options[expose][required]' => FALSE], 'Apply');
|
||||
$this->drupalPostForm(NULL, [], 'Save');
|
||||
$this->drupalGet('/admin/structure/views/nojs/handler/test_view_fieldapi/default/filter/field_boolean_value');
|
||||
$this->assertFieldChecked('edit-options-value-all');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,310 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional\Views;
|
||||
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\Views;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Tests the field itself of the Field integration.
|
||||
*
|
||||
* @group field
|
||||
* @TODO
|
||||
* Check a entity-type with bundles
|
||||
* Check a entity-type without bundles
|
||||
* Check locale:disabled, locale:enabled and locale:enabled with another language
|
||||
* Check revisions
|
||||
*/
|
||||
class HandlerFieldFieldTest extends FieldTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node', 'field_test'];
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_view_fieldapi'];
|
||||
|
||||
/**
|
||||
* Test nodes.
|
||||
*
|
||||
* @var \Drupal\node\NodeInterface[]
|
||||
*/
|
||||
public $nodes;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp($import_test_views);
|
||||
|
||||
// Setup basic fields.
|
||||
$this->setUpFieldStorages(3);
|
||||
|
||||
// Setup a field with cardinality > 1.
|
||||
$this->fieldStorages[3] = FieldStorageConfig::create([
|
||||
'field_name' => 'field_name_3',
|
||||
'entity_type' => 'node',
|
||||
'type' => 'string',
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
]);
|
||||
$this->fieldStorages[3]->save();
|
||||
// Setup a field that will have no value.
|
||||
$this->fieldStorages[4] = FieldStorageConfig::create([
|
||||
'field_name' => 'field_name_4',
|
||||
'entity_type' => 'node',
|
||||
'type' => 'string',
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
]);
|
||||
$this->fieldStorages[4]->save();
|
||||
|
||||
// Setup a text field.
|
||||
$this->fieldStorages[5] = FieldStorageConfig::create([
|
||||
'field_name' => 'field_name_5',
|
||||
'entity_type' => 'node',
|
||||
'type' => 'text',
|
||||
]);
|
||||
$this->fieldStorages[5]->save();
|
||||
|
||||
// Setup a text field with access control.
|
||||
// @see field_test_entity_field_access()
|
||||
$this->fieldStorages[6] = FieldStorageConfig::create([
|
||||
'field_name' => 'field_no_view_access',
|
||||
'entity_type' => 'node',
|
||||
'type' => 'text',
|
||||
]);
|
||||
$this->fieldStorages[6]->save();
|
||||
|
||||
$this->setUpFields();
|
||||
|
||||
// Create some nodes.
|
||||
$this->nodes = [];
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$edit = ['type' => 'page'];
|
||||
|
||||
foreach ([0, 1, 2, 5] as $key) {
|
||||
$field_storage = $this->fieldStorages[$key];
|
||||
$edit[$field_storage->getName()][0]['value'] = $this->randomMachineName(8);
|
||||
}
|
||||
// Add a hidden value for the no-view field.
|
||||
$edit[$this->fieldStorages[6]->getName()][0]['value'] = 'ssh secret squirrel';
|
||||
for ($j = 0; $j < 5; $j++) {
|
||||
$edit[$this->fieldStorages[3]->getName()][$j]['value'] = $this->randomMachineName(8);
|
||||
}
|
||||
// Set this field to be empty.
|
||||
$edit[$this->fieldStorages[4]->getName()] = [['value' => NULL]];
|
||||
|
||||
$this->nodes[$i] = $this->drupalCreateNode($edit);
|
||||
}
|
||||
|
||||
$this->container->get('views.views_data')->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the testing view with random field data.
|
||||
*
|
||||
* @param \Drupal\views\ViewExecutable $view
|
||||
* The view to add field data to.
|
||||
*/
|
||||
protected function prepareView(ViewExecutable $view) {
|
||||
$view->storage->invalidateCaches();
|
||||
$view->initDisplay();
|
||||
foreach ($this->fieldStorages as $field_storage) {
|
||||
$field_name = $field_storage->getName();
|
||||
$view->display_handler->options['fields'][$field_name]['id'] = $field_name;
|
||||
$view->display_handler->options['fields'][$field_name]['table'] = 'node__' . $field_name;
|
||||
$view->display_handler->options['fields'][$field_name]['field'] = $field_name;
|
||||
}
|
||||
}
|
||||
|
||||
public function testFieldRender() {
|
||||
$this->_testSimpleFieldRender();
|
||||
$this->_testInaccessibleFieldRender();
|
||||
$this->_testFormatterSimpleFieldRender();
|
||||
$this->_testMultipleFieldRender();
|
||||
}
|
||||
|
||||
public function _testSimpleFieldRender() {
|
||||
$view = Views::getView('test_view_fieldapi');
|
||||
$this->prepareView($view);
|
||||
$this->executeView($view);
|
||||
|
||||
// Tests that the rendered fields match the actual value of the fields.
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
for ($key = 0; $key < 2; $key++) {
|
||||
$field_name = $this->fieldStorages[$key]->getName();
|
||||
$rendered_field = $view->style_plugin->getField($i, $field_name);
|
||||
$expected_field = $this->nodes[$i]->$field_name->value;
|
||||
$this->assertEqual($rendered_field, $expected_field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function _testInaccessibleFieldRender() {
|
||||
$view = Views::getView('test_view_fieldapi');
|
||||
$this->prepareView($view);
|
||||
$this->executeView($view);
|
||||
|
||||
// Check that the field handler for the hidden field is correctly removed
|
||||
// from the display.
|
||||
// @see https://www.drupal.org/node/2382931
|
||||
$this->assertFalse(array_key_exists('field_no_view_access', $view->field));
|
||||
|
||||
// Check that the access-denied field is not visible.
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$field_name = $this->fieldStorages[6]->getName();
|
||||
$rendered_field = $view->style_plugin->getField($i, $field_name);
|
||||
$this->assertFalse($rendered_field, 'Hidden field not rendered');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that fields with formatters runs as expected.
|
||||
*/
|
||||
public function _testFormatterSimpleFieldRender() {
|
||||
$view = Views::getView('test_view_fieldapi');
|
||||
$this->prepareView($view);
|
||||
$view->displayHandlers->get('default')->options['fields'][$this->fieldStorages[5]->getName()]['type'] = 'text_trimmed';
|
||||
$view->displayHandlers->get('default')->options['fields'][$this->fieldStorages[5]->getName()]['settings'] = [
|
||||
'trim_length' => 3,
|
||||
];
|
||||
$this->executeView($view);
|
||||
|
||||
// Make sure that the formatter works as expected.
|
||||
// @TODO: actually there should be a specific formatter.
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$rendered_field = $view->style_plugin->getField($i, $this->fieldStorages[5]->getName());
|
||||
$this->assertEqual(strlen(html_entity_decode($rendered_field)), 3);
|
||||
}
|
||||
}
|
||||
|
||||
public function _testMultipleFieldRender() {
|
||||
$view = Views::getView('test_view_fieldapi');
|
||||
$field_name = $this->fieldStorages[3]->getName();
|
||||
|
||||
// Test delta limit.
|
||||
$this->prepareView($view);
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['group_rows'] = TRUE;
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['delta_limit'] = 3;
|
||||
$this->executeView($view);
|
||||
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$rendered_field = $view->style_plugin->getField($i, $field_name);
|
||||
$items = [];
|
||||
$pure_items = $this->nodes[$i]->{$field_name}->getValue();
|
||||
$pure_items = array_splice($pure_items, 0, 3);
|
||||
foreach ($pure_items as $j => $item) {
|
||||
$items[] = $pure_items[$j]['value'];
|
||||
}
|
||||
$this->assertEqual($rendered_field, implode(', ', $items), 'The amount of items is limited.');
|
||||
}
|
||||
|
||||
// Test that an empty field is rendered without error.
|
||||
$view->style_plugin->getField(4, $this->fieldStorages[4]->getName());
|
||||
$view->destroy();
|
||||
|
||||
// Test delta limit + offset
|
||||
$this->prepareView($view);
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['group_rows'] = TRUE;
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['delta_limit'] = 3;
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['delta_offset'] = 1;
|
||||
$this->executeView($view);
|
||||
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$rendered_field = $view->style_plugin->getField($i, $field_name);
|
||||
$items = [];
|
||||
$pure_items = $this->nodes[$i]->{$field_name}->getValue();
|
||||
$pure_items = array_splice($pure_items, 1, 3);
|
||||
foreach ($pure_items as $j => $item) {
|
||||
$items[] = $pure_items[$j]['value'];
|
||||
}
|
||||
$this->assertEqual($rendered_field, implode(', ', $items), 'The amount of items is limited and the offset is correct.');
|
||||
}
|
||||
$view->destroy();
|
||||
|
||||
// Test delta limit + reverse.
|
||||
$this->prepareView($view);
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['delta_offset'] = 0;
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['group_rows'] = TRUE;
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['delta_limit'] = 3;
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['delta_reversed'] = TRUE;
|
||||
$this->executeView($view);
|
||||
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$rendered_field = $view->style_plugin->getField($i, $field_name);
|
||||
$items = [];
|
||||
$pure_items = $this->nodes[$i]->{$field_name}->getValue();
|
||||
array_splice($pure_items, 0, -3);
|
||||
$pure_items = array_reverse($pure_items);
|
||||
foreach ($pure_items as $j => $item) {
|
||||
$items[] = $pure_items[$j]['value'];
|
||||
}
|
||||
$this->assertEqual($rendered_field, implode(', ', $items), 'The amount of items is limited and they are reversed.');
|
||||
}
|
||||
$view->destroy();
|
||||
|
||||
// Test delta first last.
|
||||
$this->prepareView($view);
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['group_rows'] = TRUE;
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['delta_limit'] = 0;
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['delta_first_last'] = TRUE;
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['delta_reversed'] = FALSE;
|
||||
$this->executeView($view);
|
||||
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$rendered_field = $view->style_plugin->getField($i, $field_name);
|
||||
$items = [];
|
||||
$pure_items = $this->nodes[$i]->{$field_name}->getValue();
|
||||
$items[] = $pure_items[0]['value'];
|
||||
$items[] = $pure_items[4]['value'];
|
||||
$this->assertEqual($rendered_field, implode(', ', $items), 'Items are limited to first and last.');
|
||||
}
|
||||
$view->destroy();
|
||||
|
||||
// Test delta limit + custom separator.
|
||||
$this->prepareView($view);
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['delta_first_last'] = FALSE;
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['delta_limit'] = 3;
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['group_rows'] = TRUE;
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['separator'] = ':';
|
||||
$this->executeView($view);
|
||||
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$rendered_field = $view->style_plugin->getField($i, $field_name);
|
||||
$items = [];
|
||||
$pure_items = $this->nodes[$i]->{$field_name}->getValue();
|
||||
$pure_items = array_splice($pure_items, 0, 3);
|
||||
foreach ($pure_items as $j => $item) {
|
||||
$items[] = $pure_items[$j]['value'];
|
||||
}
|
||||
$this->assertEqual($rendered_field, implode(':', $items), 'The amount of items is limited and the custom separator is correct.');
|
||||
}
|
||||
$view->destroy();
|
||||
|
||||
// Test separator with HTML, ensure it is escaped.
|
||||
$this->prepareView($view);
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['group_rows'] = TRUE;
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['delta_limit'] = 3;
|
||||
$view->displayHandlers->get('default')->options['fields'][$field_name]['separator'] = '<h2>test</h2>';
|
||||
$this->executeView($view);
|
||||
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$rendered_field = $view->style_plugin->getField($i, $field_name);
|
||||
$items = [];
|
||||
$pure_items = $this->nodes[$i]->{$field_name}->getValue();
|
||||
$pure_items = array_splice($pure_items, 0, 3);
|
||||
foreach ($pure_items as $j => $item) {
|
||||
$items[] = $pure_items[$j]['value'];
|
||||
}
|
||||
$this->assertEqual($rendered_field, implode('<h2>test</h2>', $items), 'The custom separator is correctly escaped.');
|
||||
}
|
||||
$view->destroy();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Functional;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\Traits\Core\CronRunTrait;
|
||||
|
||||
/**
|
||||
* Tests the behavior of a field module after being disabled and re-enabled.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class reEnableModuleFieldTest extends BrowserTestBase {
|
||||
|
||||
use CronRunTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = [
|
||||
'field',
|
||||
'node',
|
||||
// We use telephone module instead of test_field because test_field is
|
||||
// hidden and does not display on the admin/modules page.
|
||||
'telephone',
|
||||
];
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->drupalCreateContentType(['type' => 'article']);
|
||||
$this->drupalLogin($this->drupalCreateUser([
|
||||
'create article content',
|
||||
'edit own article content',
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the behavior of a field module after being disabled and re-enabled.
|
||||
*
|
||||
* @see field_system_info_alter()
|
||||
*/
|
||||
public function testReEnabledField() {
|
||||
|
||||
// Add a telephone field to the article content type.
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => 'field_telephone',
|
||||
'entity_type' => 'node',
|
||||
'type' => 'telephone',
|
||||
]);
|
||||
$field_storage->save();
|
||||
FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => 'article',
|
||||
'label' => 'Telephone Number',
|
||||
])->save();
|
||||
|
||||
entity_get_form_display('node', 'article', 'default')
|
||||
->setComponent('field_telephone', [
|
||||
'type' => 'telephone_default',
|
||||
'settings' => [
|
||||
'placeholder' => '123-456-7890',
|
||||
],
|
||||
])
|
||||
->save();
|
||||
|
||||
entity_get_display('node', 'article', 'default')
|
||||
->setComponent('field_telephone', [
|
||||
'type' => 'telephone_link',
|
||||
'weight' => 1,
|
||||
])
|
||||
->save();
|
||||
|
||||
// Display the article node form and verify the telephone widget is present.
|
||||
$this->drupalGet('node/add/article');
|
||||
$this->assertFieldByName("field_telephone[0][value]", '', 'Widget found.');
|
||||
|
||||
// Submit an article node with a telephone field so data exist for the
|
||||
// field.
|
||||
$edit = [
|
||||
'title[0][value]' => $this->randomMachineName(),
|
||||
'field_telephone[0][value]' => "123456789",
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertRaw('<a href="tel:123456789">');
|
||||
|
||||
// Test that the module can't be uninstalled from the UI while there is data
|
||||
// for its fields.
|
||||
$admin_user = $this->drupalCreateUser(['access administration pages', 'administer modules']);
|
||||
$this->drupalLogin($admin_user);
|
||||
$this->drupalGet('admin/modules/uninstall');
|
||||
$this->assertText("The Telephone number field type is used in the following field: node.field_telephone");
|
||||
|
||||
// Add another telephone field to a different entity type in order to test
|
||||
// the message for the case when multiple fields are blocking the
|
||||
// uninstallation of a module.
|
||||
$field_storage2 = entity_create('field_storage_config', [
|
||||
'field_name' => 'field_telephone_2',
|
||||
'entity_type' => 'user',
|
||||
'type' => 'telephone',
|
||||
]);
|
||||
$field_storage2->save();
|
||||
FieldConfig::create([
|
||||
'field_storage' => $field_storage2,
|
||||
'bundle' => 'user',
|
||||
'label' => 'User Telephone Number',
|
||||
])->save();
|
||||
|
||||
$this->drupalGet('admin/modules/uninstall');
|
||||
$this->assertText("The Telephone number field type is used in the following fields: node.field_telephone, user.field_telephone_2");
|
||||
|
||||
// Delete both fields.
|
||||
$field_storage->delete();
|
||||
$field_storage2->delete();
|
||||
|
||||
$this->drupalGet('admin/modules/uninstall');
|
||||
$this->assertText('Fields pending deletion');
|
||||
$this->cronRun();
|
||||
$this->assertNoText("The Telephone number field type is used in the following field: node.field_telephone");
|
||||
$this->assertNoText('Fields pending deletion');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\FunctionalJavascript\Boolean;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
|
||||
|
||||
/**
|
||||
* Tests the Boolean field formatter settings.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class BooleanFormatterSettingsTest extends WebDriverTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['field', 'field_ui', 'text', 'node', 'user'];
|
||||
|
||||
/**
|
||||
* The name of the entity bundle that is created in the test.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $bundle;
|
||||
|
||||
/**
|
||||
* The name of the Boolean field to use for testing.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldName;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Create a content type. Use Node because it has Field UI pages that work.
|
||||
$type_name = mb_strtolower($this->randomMachineName(8)) . '_test';
|
||||
$type = $this->drupalCreateContentType(['name' => $type_name, 'type' => $type_name]);
|
||||
$this->bundle = $type->id();
|
||||
|
||||
$admin_user = $this->drupalCreateUser([
|
||||
'access content',
|
||||
'administer content types',
|
||||
'administer node fields',
|
||||
'administer node display',
|
||||
'bypass node access',
|
||||
'administer nodes',
|
||||
]);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
||||
$this->fieldName = mb_strtolower($this->randomMachineName(8));
|
||||
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => $this->fieldName,
|
||||
'entity_type' => 'node',
|
||||
'type' => 'boolean',
|
||||
]);
|
||||
$field_storage->save();
|
||||
|
||||
$instance = FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => $this->bundle,
|
||||
'label' => $this->randomMachineName(),
|
||||
]);
|
||||
$instance->save();
|
||||
|
||||
$display = entity_get_display('node', $this->bundle, 'default')
|
||||
->setComponent($this->fieldName, [
|
||||
'type' => 'boolean',
|
||||
'settings' => [],
|
||||
]);
|
||||
$display->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the formatter settings page for the Boolean formatter.
|
||||
*/
|
||||
public function testBooleanFormatterSettings() {
|
||||
// List the options we expect to see on the settings form. Omit the one
|
||||
// with the Unicode check/x characters, which does not appear to work
|
||||
// well in WebTestBase.
|
||||
$options = [
|
||||
'Yes / No',
|
||||
'True / False',
|
||||
'On / Off',
|
||||
'Enabled / Disabled',
|
||||
'1 / 0',
|
||||
'Custom',
|
||||
];
|
||||
|
||||
// For several different values of the field settings, test that the
|
||||
// options, including default, are shown correctly.
|
||||
$settings = [
|
||||
['Yes', 'No'],
|
||||
['On', 'Off'],
|
||||
['TRUE', 'FALSE'],
|
||||
];
|
||||
|
||||
$assert_session = $this->assertSession();
|
||||
foreach ($settings as $values) {
|
||||
// Set up the field settings.
|
||||
$this->drupalGet('admin/structure/types/manage/' . $this->bundle . '/fields/node.' . $this->bundle . '.' . $this->fieldName);
|
||||
$this->drupalPostForm(NULL, [
|
||||
'settings[on_label]' => $values[0],
|
||||
'settings[off_label]' => $values[1],
|
||||
], t('Save settings'));
|
||||
|
||||
// Open the Manage Display page and trigger the field settings form.
|
||||
$this->drupalGet('admin/structure/types/manage/' . $this->bundle . '/display');
|
||||
$this->getSession()->getPage()->pressButton($this->fieldName . '_settings_edit');
|
||||
$assert_session->waitForElement('css', '.ajax-new-content');
|
||||
|
||||
// Test that the settings options are present in the correct format.
|
||||
foreach ($options as $string) {
|
||||
$assert_session->pageTextContains($string);
|
||||
}
|
||||
$assert_session->pageTextContains(t('Field settings (@on_label / @off_label)', ['@on_label' => $values[0], '@off_label' => $values[1]]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\FunctionalJavascript;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
|
||||
|
||||
/**
|
||||
* Tests add more behavior for a multiple value field.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class FormJSAddMoreTest extends WebDriverTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['field_test', 'entity_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$account = $this->drupalCreateUser([
|
||||
'view test entity',
|
||||
'administer entity_test content',
|
||||
]);
|
||||
$this->drupalLogin($account);
|
||||
|
||||
$field = [
|
||||
'field_name' => 'field_unlimited',
|
||||
'entity_type' => 'entity_test',
|
||||
'bundle' => 'entity_test',
|
||||
'label' => $this->randomMachineName() . '_label',
|
||||
'description' => '[site:name]_description',
|
||||
'weight' => mt_rand(0, 127),
|
||||
'settings' => [
|
||||
'test_field_setting' => $this->randomMachineName(),
|
||||
],
|
||||
];
|
||||
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => 'field_unlimited',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
|
||||
])->save();
|
||||
FieldConfig::create($field)->save();
|
||||
|
||||
$entity_form_display = EntityFormDisplay::load($field['entity_type'] . '.' . $field['bundle'] . '.default');
|
||||
$entity_form_display->setComponent($field['field_name'])->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the 'Add more' functionality.
|
||||
*/
|
||||
public function testFieldFormJsAddMore() {
|
||||
$this->drupalGet('entity_test/add');
|
||||
|
||||
$assert_session = $this->assertSession();
|
||||
$page = $this->getSession()->getPage();
|
||||
$add_more_button = $page->findButton('field_unlimited_add_more');
|
||||
|
||||
// First set a value on the first input field.
|
||||
$field_0 = $page->findField('field_unlimited[0][value]');
|
||||
$field_0->setValue('1');
|
||||
|
||||
// Add another item.
|
||||
$add_more_button->click();
|
||||
$field_1 = $assert_session->waitForField('field_unlimited[1][value]');
|
||||
$this->assertNotEmpty($field_1, 'Successfully added another item.');
|
||||
|
||||
// Validate the value of the first field has not changed.
|
||||
$this->assertEquals('1', $field_0->getValue(), 'Value for the first item has not changed.');
|
||||
|
||||
// Validate the value of the second item is empty.
|
||||
$this->assertEmpty($field_1->getValue(), 'Value for the second item is currently empty.');
|
||||
|
||||
// Add another item.
|
||||
$add_more_button->click();
|
||||
$field_2 = $assert_session->waitForField('field_unlimited[2][value]');
|
||||
$this->assertNotEmpty($field_2, 'Successfully added another item.');
|
||||
|
||||
// Set values for the 2nd and 3rd fields to validate dragging.
|
||||
$field_1->setValue('2');
|
||||
$field_2->setValue('3');
|
||||
|
||||
$field_weight_0 = $page->findField('field_unlimited[0][_weight]');
|
||||
$field_weight_1 = $page->findField('field_unlimited[1][_weight]');
|
||||
$field_weight_2 = $page->findField('field_unlimited[2][_weight]');
|
||||
|
||||
// Assert starting situation matches expectations.
|
||||
$this->assertGreaterThan($field_weight_0->getValue(), $field_weight_1->getValue());
|
||||
$this->assertGreaterThan($field_weight_1->getValue(), $field_weight_2->getValue());
|
||||
|
||||
// Drag the first row after the third row.
|
||||
$dragged = $field_0->find('xpath', 'ancestor::tr[contains(@class, "draggable")]//a[@class="tabledrag-handle"]');
|
||||
$target = $field_2->find('xpath', 'ancestor::tr[contains(@class, "draggable")]');
|
||||
$dragged->dragTo($target);
|
||||
|
||||
// Assert the order of items is updated correctly after dragging.
|
||||
$this->assertGreaterThan($field_weight_2->getValue(), $field_weight_0->getValue());
|
||||
$this->assertGreaterThan($field_weight_1->getValue(), $field_weight_2->getValue());
|
||||
|
||||
// Validate the order of items conforms to the last drag action after a
|
||||
// updating the form via the server.
|
||||
$add_more_button->click();
|
||||
$field_3 = $assert_session->waitForField('field_unlimited[3][value]');
|
||||
$this->assertNotEmpty($field_3);
|
||||
$this->assertGreaterThan($field_weight_2->getValue(), $field_weight_0->getValue());
|
||||
$this->assertGreaterThan($field_weight_1->getValue(), $field_weight_2->getValue());
|
||||
|
||||
// Validate no extraneous widget is displayed.
|
||||
$element = $page->findField('field_unlimited[4][value]');
|
||||
$this->assertEmpty($element);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\FunctionalJavascript\Number;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
|
||||
use Drupal\node\Entity\Node;
|
||||
|
||||
/**
|
||||
* Tests the numeric field widget.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class NumberFieldTest extends WebDriverTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = ['node', 'entity_test', 'field_ui'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->drupalLogin($this->drupalCreateUser([
|
||||
'view test entity',
|
||||
'administer entity_test content',
|
||||
'administer content types',
|
||||
'administer node fields',
|
||||
'administer node display',
|
||||
'bypass node access',
|
||||
'administer entity_test fields',
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test default formatter behavior.
|
||||
*/
|
||||
public function testNumberFormatter() {
|
||||
$type = mb_strtolower($this->randomMachineName());
|
||||
$float_field = mb_strtolower($this->randomMachineName());
|
||||
$integer_field = mb_strtolower($this->randomMachineName());
|
||||
$thousand_separators = ['', '.', ',', ' ', chr(8201), "'"];
|
||||
$decimal_separators = ['.', ','];
|
||||
$prefix = $this->randomMachineName();
|
||||
$suffix = $this->randomMachineName();
|
||||
$random_float = rand(0, pow(10, 6));
|
||||
$random_integer = rand(0, pow(10, 6));
|
||||
$assert_session = $this->assertSession();
|
||||
|
||||
// Create a content type containing float and integer fields.
|
||||
$this->drupalCreateContentType(['type' => $type]);
|
||||
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $float_field,
|
||||
'entity_type' => 'node',
|
||||
'type' => 'float',
|
||||
])->save();
|
||||
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => $integer_field,
|
||||
'entity_type' => 'node',
|
||||
'type' => 'integer',
|
||||
])->save();
|
||||
|
||||
FieldConfig::create([
|
||||
'field_name' => $float_field,
|
||||
'entity_type' => 'node',
|
||||
'bundle' => $type,
|
||||
'settings' => [
|
||||
'prefix' => $prefix,
|
||||
'suffix' => $suffix,
|
||||
],
|
||||
])->save();
|
||||
|
||||
FieldConfig::create([
|
||||
'field_name' => $integer_field,
|
||||
'entity_type' => 'node',
|
||||
'bundle' => $type,
|
||||
'settings' => [
|
||||
'prefix' => $prefix,
|
||||
'suffix' => $suffix,
|
||||
],
|
||||
])->save();
|
||||
|
||||
entity_get_form_display('node', $type, 'default')
|
||||
->setComponent($float_field, [
|
||||
'type' => 'number',
|
||||
'settings' => [
|
||||
'placeholder' => '0.00',
|
||||
],
|
||||
])
|
||||
->setComponent($integer_field, [
|
||||
'type' => 'number',
|
||||
'settings' => [
|
||||
'placeholder' => '0.00',
|
||||
],
|
||||
])
|
||||
->save();
|
||||
|
||||
entity_get_display('node', $type, 'default')
|
||||
->setComponent($float_field, [
|
||||
'type' => 'number_decimal',
|
||||
])
|
||||
->setComponent($integer_field, [
|
||||
'type' => 'number_unformatted',
|
||||
])
|
||||
->save();
|
||||
|
||||
// Create a node to test formatters.
|
||||
$node = Node::create([
|
||||
'type' => $type,
|
||||
'title' => $this->randomMachineName(),
|
||||
$float_field => ['value' => $random_float],
|
||||
$integer_field => ['value' => $random_integer],
|
||||
]);
|
||||
$node->save();
|
||||
|
||||
// Go to manage display page.
|
||||
$this->drupalGet("admin/structure/types/manage/$type/display");
|
||||
|
||||
// Configure number_decimal formatter for the 'float' field type.
|
||||
$thousand_separator = $thousand_separators[array_rand($thousand_separators)];
|
||||
$decimal_separator = $decimal_separators[array_rand($decimal_separators)];
|
||||
$scale = rand(0, 10);
|
||||
|
||||
$page = $this->getSession()->getPage();
|
||||
$page->pressButton("${float_field}_settings_edit");
|
||||
$assert_session->waitForElement('css', '.ajax-new-content');
|
||||
$edit = [
|
||||
"fields[${float_field}][settings_edit_form][settings][prefix_suffix]" => TRUE,
|
||||
"fields[${float_field}][settings_edit_form][settings][scale]" => $scale,
|
||||
"fields[${float_field}][settings_edit_form][settings][decimal_separator]" => $decimal_separator,
|
||||
"fields[${float_field}][settings_edit_form][settings][thousand_separator]" => $thousand_separator,
|
||||
];
|
||||
foreach ($edit as $name => $value) {
|
||||
$page->fillField($name, $value);
|
||||
}
|
||||
$page->pressButton("${float_field}_plugin_settings_update");
|
||||
$assert_session->waitForElement('css', '.field-plugin-summary-cell > .ajax-new-content');
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
|
||||
// Check number_decimal and number_unformatted formatters behavior.
|
||||
$this->drupalGet('node/' . $node->id());
|
||||
$float_formatted = number_format($random_float, $scale, $decimal_separator, $thousand_separator);
|
||||
$this->assertRaw("$prefix$float_formatted$suffix", 'Prefix and suffix added');
|
||||
$this->assertRaw((string) $random_integer);
|
||||
|
||||
// Configure the number_decimal formatter.
|
||||
entity_get_display('node', $type, 'default')
|
||||
->setComponent($integer_field, [
|
||||
'type' => 'number_integer',
|
||||
])
|
||||
->save();
|
||||
$this->drupalGet("admin/structure/types/manage/$type/display");
|
||||
|
||||
$thousand_separator = $thousand_separators[array_rand($thousand_separators)];
|
||||
|
||||
$page = $this->getSession()->getPage();
|
||||
$page->pressButton("${integer_field}_settings_edit");
|
||||
$assert_session->waitForElement('css', '.ajax-new-content');
|
||||
$edit = [
|
||||
"fields[${integer_field}][settings_edit_form][settings][prefix_suffix]" => FALSE,
|
||||
"fields[${integer_field}][settings_edit_form][settings][thousand_separator]" => $thousand_separator,
|
||||
];
|
||||
foreach ($edit as $name => $value) {
|
||||
$page->fillField($name, $value);
|
||||
}
|
||||
$page->pressButton("${integer_field}_plugin_settings_update");
|
||||
$assert_session->waitForElement('css', '.field-plugin-summary-cell > .ajax-new-content');
|
||||
$this->drupalPostForm(NULL, [], t('Save'));
|
||||
|
||||
// Check number_integer formatter behavior.
|
||||
$this->drupalGet('node/' . $node->id());
|
||||
|
||||
$integer_formatted = number_format($random_integer, 0, '', $thousand_separator);
|
||||
$this->assertRaw($integer_formatted, 'Random integer formatted');
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Drupal\Tests\field\Kernel\Boolean;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
|
||||
use Drupal\Core\Entity\FieldableEntityInterface;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
|
@ -55,7 +54,7 @@ class BooleanFormatterTest extends KernelTestBase {
|
|||
|
||||
$this->entityType = 'entity_test';
|
||||
$this->bundle = $this->entityType;
|
||||
$this->fieldName = Unicode::strtolower($this->randomMachineName());
|
||||
$this->fieldName = mb_strtolower($this->randomMachineName());
|
||||
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => $this->fieldName,
|
||||
|
@ -115,7 +114,7 @@ class BooleanFormatterTest extends KernelTestBase {
|
|||
$format = [
|
||||
'format' => 'custom',
|
||||
'format_custom_false' => 'FALSE',
|
||||
'format_custom_true' => 'TRUE'
|
||||
'format_custom_true' => 'TRUE',
|
||||
];
|
||||
$data[] = [0, $format, 'FALSE'];
|
||||
$data[] = [1, $format, 'TRUE'];
|
||||
|
|
|
@ -105,7 +105,7 @@ class BulkDeleteTest extends FieldKernelTestBase {
|
|||
'field_name' => 'bf_1',
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'type' => 'test_field',
|
||||
'cardinality' => 1
|
||||
'cardinality' => 1,
|
||||
]);
|
||||
$field_storage->save();
|
||||
$this->fieldStorages[] = $field_storage;
|
||||
|
@ -113,7 +113,7 @@ class BulkDeleteTest extends FieldKernelTestBase {
|
|||
'field_name' => 'bf_2',
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'type' => 'test_field',
|
||||
'cardinality' => 4
|
||||
'cardinality' => 4,
|
||||
]);
|
||||
$field_storage->save();
|
||||
$this->fieldStorages[] = $field_storage;
|
||||
|
@ -162,10 +162,11 @@ class BulkDeleteTest extends FieldKernelTestBase {
|
|||
$bundle = reset($this->bundles);
|
||||
$field_storage = reset($this->fieldStorages);
|
||||
$field_name = $field_storage->getName();
|
||||
$factory = \Drupal::service('entity.query');
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('entity_test');
|
||||
|
||||
// There are 10 entities of this bundle.
|
||||
$found = $factory->get('entity_test')
|
||||
$found = $storage
|
||||
->getQuery()
|
||||
->condition('type', $bundle)
|
||||
->execute();
|
||||
$this->assertEqual(count($found), 10, 'Correct number of entities found before deleting');
|
||||
|
@ -181,7 +182,6 @@ class BulkDeleteTest extends FieldKernelTestBase {
|
|||
$this->assertEqual($field->getTargetBundle(), $bundle, 'The deleted field is for the correct bundle');
|
||||
|
||||
// Check that the actual stored content did not change during delete.
|
||||
$storage = \Drupal::entityManager()->getStorage($this->entityTypeId);
|
||||
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
|
||||
$table_mapping = $storage->getTableMapping();
|
||||
$table = $table_mapping->getDedicatedDataTableName($field_storage);
|
||||
|
@ -194,7 +194,8 @@ class BulkDeleteTest extends FieldKernelTestBase {
|
|||
}
|
||||
|
||||
// There are 0 entities of this bundle with non-deleted data.
|
||||
$found = $factory->get('entity_test')
|
||||
$found = $storage
|
||||
->getQuery()
|
||||
->condition('type', $bundle)
|
||||
->condition("$field_name.deleted", 0)
|
||||
->execute();
|
||||
|
@ -202,7 +203,8 @@ class BulkDeleteTest extends FieldKernelTestBase {
|
|||
|
||||
// There are 10 entities of this bundle when deleted fields are allowed, and
|
||||
// their values are correct.
|
||||
$found = $factory->get('entity_test')
|
||||
$found = $storage
|
||||
->getQuery()
|
||||
->condition('type', $bundle)
|
||||
->condition("$field_name.deleted", 1)
|
||||
->sort('id')
|
||||
|
@ -222,7 +224,7 @@ class BulkDeleteTest extends FieldKernelTestBase {
|
|||
'field_name' => $field_name,
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'type' => 'test_field',
|
||||
'cardinality' => 1
|
||||
'cardinality' => 1,
|
||||
]);
|
||||
$deleted_field_storage->save();
|
||||
// Create the field.
|
||||
|
@ -253,7 +255,7 @@ class BulkDeleteTest extends FieldKernelTestBase {
|
|||
'field_name' => $field_name,
|
||||
'entity_type' => $this->entityTypeId,
|
||||
'type' => 'test_field',
|
||||
'cardinality' => 1
|
||||
'cardinality' => 1,
|
||||
]);
|
||||
$field_storage->save();
|
||||
FieldConfig::create([
|
||||
|
|
|
@ -15,7 +15,7 @@ class ConfigFieldDefinitionTest extends FieldKernelTestBase {
|
|||
/**
|
||||
* The entity manager service.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface;
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ class DisplayApiTest extends FieldKernelTestBase {
|
|||
/**
|
||||
* The field cardinality to use in this test.
|
||||
*
|
||||
* @var number
|
||||
* @var int
|
||||
*/
|
||||
protected $cardinality;
|
||||
|
||||
|
|
|
@ -8,12 +8,12 @@ use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
|||
use Drupal\Core\Field\Plugin\Field\FieldFormatter\EntityReferenceEntityFormatter;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\filter\Entity\FilterFormat;
|
||||
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
|
||||
use Drupal\user\Entity\Role;
|
||||
use Drupal\user\RoleInterface;
|
||||
use Drupal\entity_test\Entity\EntityTestLabel;
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
||||
|
||||
/**
|
||||
* Tests the formatters functionality.
|
||||
|
@ -332,7 +332,6 @@ class EntityReferenceFormatterTest extends EntityKernelTestBase {
|
|||
$this->assertEquals($expected_occurrences, $actual_occurrences);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests the label formatter.
|
||||
*/
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
namespace Drupal\Tests\field\Kernel\EntityReference;
|
||||
|
||||
use Drupal\comment\Entity\Comment;
|
||||
use Drupal\comment\Entity\CommentType;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FieldItemInterface;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
|
@ -14,15 +14,16 @@ use Drupal\entity_test\Entity\EntityTest;
|
|||
use Drupal\entity_test\Entity\EntityTestStringId;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\node\NodeInterface;
|
||||
use Drupal\taxonomy\TermInterface;
|
||||
use Drupal\Tests\field\Kernel\FieldKernelTestBase;
|
||||
use Drupal\file\Entity\File;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\taxonomy\Entity\Term;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
||||
|
||||
/**
|
||||
* Tests the new entity API for the entity reference field type.
|
||||
|
@ -78,7 +79,7 @@ class EntityReferenceItemTest extends FieldKernelTestBase {
|
|||
|
||||
$this->vocabulary = Vocabulary::create([
|
||||
'name' => $this->randomMachineName(),
|
||||
'vid' => Unicode::strtolower($this->randomMachineName()),
|
||||
'vid' => mb_strtolower($this->randomMachineName()),
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
$this->vocabulary->save();
|
||||
|
@ -90,6 +91,14 @@ class EntityReferenceItemTest extends FieldKernelTestBase {
|
|||
]);
|
||||
$this->term->save();
|
||||
|
||||
NodeType::create([
|
||||
'type' => $this->randomMachineName(),
|
||||
])->save();
|
||||
CommentType::create([
|
||||
'id' => $this->randomMachineName(),
|
||||
'target_entity_type_id' => 'node',
|
||||
])->save();
|
||||
|
||||
$this->entityStringId = EntityTestStringId::create([
|
||||
'id' => $this->randomMachineName(),
|
||||
]);
|
||||
|
@ -103,6 +112,7 @@ class EntityReferenceItemTest extends FieldKernelTestBase {
|
|||
$this->createEntityReferenceField('entity_test', 'entity_test', 'field_test_user', 'Test user entity reference', 'user');
|
||||
$this->createEntityReferenceField('entity_test', 'entity_test', 'field_test_comment', 'Test comment entity reference', 'comment');
|
||||
$this->createEntityReferenceField('entity_test', 'entity_test', 'field_test_file', 'Test file entity reference', 'file');
|
||||
$this->createEntityReferenceField('entity_test_string_id', 'entity_test_string_id', 'field_test_entity_test', 'Test content entity reference with string ID', 'entity_test');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -194,6 +204,37 @@ class EntityReferenceItemTest extends FieldKernelTestBase {
|
|||
$entity = EntityTest::create(['user_id' => ['target_id' => (int) $user->id(), 'entity' => $user]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the ::generateSampleValue() method.
|
||||
*/
|
||||
public function testGenerateSampleValue() {
|
||||
$entity = EntityTest::create();
|
||||
|
||||
// Test while a term exists.
|
||||
$entity->field_test_taxonomy_term->generateSampleItems();
|
||||
$this->assertInstanceOf(TermInterface::class, $entity->field_test_taxonomy_term->entity);
|
||||
$this->entityValidateAndSave($entity);
|
||||
|
||||
// Delete the term and test again.
|
||||
$this->term->delete();
|
||||
$entity->field_test_taxonomy_term->generateSampleItems();
|
||||
$this->assertInstanceOf(TermInterface::class, $entity->field_test_taxonomy_term->entity);
|
||||
$this->entityValidateAndSave($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the ::generateSampleValue() method when it has a circular reference.
|
||||
*/
|
||||
public function testGenerateSampleValueCircularReference() {
|
||||
// Delete the existing entity.
|
||||
$this->entityStringId->delete();
|
||||
|
||||
$entity_storage = \Drupal::entityTypeManager()->getStorage('entity_test');
|
||||
$entity = $entity_storage->createWithSampleValues('entity_test');
|
||||
$this->assertInstanceOf(EntityTestStringId::class, $entity->field_test_entity_test_string_id->entity);
|
||||
$this->assertInstanceOf(EntityTest::class, $entity->field_test_entity_test_string_id->entity->field_test_entity_test->entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests referencing content entities with string IDs.
|
||||
*/
|
||||
|
@ -241,7 +282,7 @@ class EntityReferenceItemTest extends FieldKernelTestBase {
|
|||
// Make sure the computed term reflects updates to the term id.
|
||||
$vocabulary2 = $vocabulary = Vocabulary::create([
|
||||
'name' => $this->randomMachineName(),
|
||||
'vid' => Unicode::strtolower($this->randomMachineName()),
|
||||
'vid' => mb_strtolower($this->randomMachineName()),
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
]);
|
||||
$vocabulary2->save();
|
||||
|
@ -312,13 +353,13 @@ class EntityReferenceItemTest extends FieldKernelTestBase {
|
|||
* Tests that the 'handler' field setting stores the proper plugin ID.
|
||||
*/
|
||||
public function testSelectionHandlerSettings() {
|
||||
$field_name = Unicode::strtolower($this->randomMachineName());
|
||||
$field_name = mb_strtolower($this->randomMachineName());
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'entity_reference',
|
||||
'settings' => [
|
||||
'target_type' => 'entity_test'
|
||||
'target_type' => 'entity_test',
|
||||
],
|
||||
]);
|
||||
$field_storage->save();
|
||||
|
@ -410,7 +451,7 @@ class EntityReferenceItemTest extends FieldKernelTestBase {
|
|||
$this->assertEqual($errors[0]->getPropertyPath(), 'field_test_node.0.entity');
|
||||
|
||||
// Publish the node and try again.
|
||||
$node->setPublished(TRUE);
|
||||
$node->setPublished();
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(0, count($errors));
|
||||
|
||||
|
@ -460,7 +501,7 @@ class EntityReferenceItemTest extends FieldKernelTestBase {
|
|||
$this->assertEqual($errors[1]->getPropertyPath(), 'field_test_node.1.target_id');
|
||||
|
||||
// Publish one of the nodes and try again.
|
||||
$saved_unpublished_node->setPublished(TRUE);
|
||||
$saved_unpublished_node->setPublished();
|
||||
$saved_unpublished_node->save();
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(1, count($errors));
|
||||
|
@ -468,7 +509,7 @@ class EntityReferenceItemTest extends FieldKernelTestBase {
|
|||
$this->assertEqual($errors[0]->getPropertyPath(), 'field_test_node.0.entity');
|
||||
|
||||
// Publish the last invalid node and try again.
|
||||
$unsaved_unpublished_node->setPublished(TRUE);
|
||||
$unsaved_unpublished_node->setPublished();
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(0, count($errors));
|
||||
|
||||
|
@ -492,7 +533,7 @@ class EntityReferenceItemTest extends FieldKernelTestBase {
|
|||
$this->assertEqual($errors[0]->getPropertyPath(), 'field_test_comment.0.entity');
|
||||
|
||||
// Publish the comment and try again.
|
||||
$comment->setPublished(TRUE);
|
||||
$comment->setPublished();
|
||||
$errors = $entity->validate();
|
||||
$this->assertEqual(0, count($errors));
|
||||
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
|
||||
namespace Drupal\Tests\field\Kernel\EntityReference;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\Logger\RfcLogLevel;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
||||
use Symfony\Component\Debug\BufferingLogger;
|
||||
|
||||
/**
|
||||
* Tests entity reference field settings.
|
||||
|
@ -44,6 +46,13 @@ class EntityReferenceSettingsTest extends KernelTestBase {
|
|||
*/
|
||||
protected $customBundle;
|
||||
|
||||
/**
|
||||
* The service name for a logger implementation that collects anything logged.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $testLogServiceName = 'entity_reference_settings_test.logger';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -55,31 +64,43 @@ class EntityReferenceSettingsTest extends KernelTestBase {
|
|||
$this->installEntitySchema('entity_test');
|
||||
|
||||
$this->nodeType = NodeType::create([
|
||||
'type' => Unicode::strtolower($this->randomMachineName()),
|
||||
'type' => mb_strtolower($this->randomMachineName()),
|
||||
'name' => $this->randomString(),
|
||||
]);
|
||||
$this->nodeType->save();
|
||||
|
||||
$this->vocabulary = Vocabulary::create([
|
||||
'vid' => Unicode::strtolower($this->randomMachineName()),
|
||||
'name' => $this->randomString(),
|
||||
]);
|
||||
$this->vocabulary->save();
|
||||
|
||||
// Create a custom bundle.
|
||||
$this->customBundle = 'test_bundle_' . Unicode::strtolower($this->randomMachineName());
|
||||
$this->customBundle = 'test_bundle_' . mb_strtolower($this->randomMachineName());
|
||||
entity_test_create_bundle($this->customBundle, NULL, 'entity_test');
|
||||
|
||||
// Prepare the logger for collecting the expected critical error.
|
||||
$this->container->get($this->testLogServiceName)->cleanLogs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that config bundle deletions are mirrored in field config settings.
|
||||
*/
|
||||
public function testConfigTargetBundleDeletion() {
|
||||
// Create two vocabularies.
|
||||
/** @var \Drupal\taxonomy\Entity\Vocabulary[] $vocabularies */
|
||||
$vocabularies = [];
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$vid = mb_strtolower($this->randomMachineName());
|
||||
$vocabularies[$i] = Vocabulary::create([
|
||||
'name' => $this->randomString(),
|
||||
'vid' => $vid,
|
||||
]);
|
||||
$vocabularies[$i]->save();
|
||||
}
|
||||
// Attach an entity reference field to $this->nodeType.
|
||||
$name = Unicode::strtolower($this->randomMachineName());
|
||||
$name = mb_strtolower($this->randomMachineName());
|
||||
$label = $this->randomString();
|
||||
$vid = $this->vocabulary->id();
|
||||
$handler_settings = ['target_bundles' => [$vid => $vid]];
|
||||
$handler_settings = [
|
||||
'target_bundles' => [
|
||||
$vocabularies[0]->id() => $vocabularies[0]->id(),
|
||||
$vocabularies[1]->id() => $vocabularies[1]->id(),
|
||||
],
|
||||
];
|
||||
$this->createEntityReferenceField('node', $this->nodeType->id(), $name, $label, 'taxonomy_term', 'default', $handler_settings);
|
||||
|
||||
// Check that the 'target_bundle' setting contains the vocabulary.
|
||||
|
@ -88,13 +109,32 @@ class EntityReferenceSettingsTest extends KernelTestBase {
|
|||
$this->assertEqual($handler_settings, $actual_handler_settings);
|
||||
|
||||
// Delete the vocabulary.
|
||||
$this->vocabulary->delete();
|
||||
$vocabularies[0]->delete();
|
||||
// Ensure that noting is logged.
|
||||
$this->assertEmpty($this->container->get($this->testLogServiceName)->cleanLogs());
|
||||
|
||||
// Check that the deleted vocabulary is no longer present in the
|
||||
// 'target_bundles' field setting.
|
||||
$field_config = FieldConfig::loadByName('node', $this->nodeType->id(), $name);
|
||||
$handler_settings = $field_config->getSetting('handler_settings');
|
||||
$this->assertTrue(empty($handler_settings['target_bundles']));
|
||||
$this->assertEquals([$vocabularies[1]->id() => $vocabularies[1]->id()], $handler_settings['target_bundles']);
|
||||
|
||||
// Delete the other vocabulary.
|
||||
$vocabularies[1]->delete();
|
||||
// Ensure that field_field_config_presave() logs the expected critical
|
||||
// error.
|
||||
$log_message = $this->container->get($this->testLogServiceName)->cleanLogs()[0];
|
||||
$this->assertEquals(RfcLogLevel::CRITICAL, $log_message[0]);
|
||||
$this->assertEquals('The %field_name entity reference field (entity_type: %entity_type, bundle: %bundle) no longer has any valid bundle it can reference. The field is not working correctly anymore and has to be adjusted.', $log_message[1]);
|
||||
$this->assertEquals($field_config->getName(), $log_message[2]['%field_name']);
|
||||
$this->assertEquals('node', $log_message[2]['%entity_type']);
|
||||
$this->assertEquals($this->nodeType->id(), $log_message[2]['%bundle']);
|
||||
|
||||
// Check that the deleted bundle is no longer present in the
|
||||
// 'target_bundles' field setting.
|
||||
$field_config = FieldConfig::loadByName('node', $this->nodeType->id(), $name);
|
||||
$handler_settings = $field_config->getSetting('handler_settings');
|
||||
$this->assertEquals([], $handler_settings['target_bundles']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -102,7 +142,7 @@ class EntityReferenceSettingsTest extends KernelTestBase {
|
|||
*/
|
||||
public function testCustomTargetBundleDeletion() {
|
||||
// Attach an entity reference field to $this->nodeType.
|
||||
$name = Unicode::strtolower($this->randomMachineName());
|
||||
$name = mb_strtolower($this->randomMachineName());
|
||||
$label = $this->randomString();
|
||||
$handler_settings = ['target_bundles' => [$this->customBundle => $this->customBundle]];
|
||||
$this->createEntityReferenceField('node', $this->nodeType->id(), $name, $label, 'entity_test', 'default', $handler_settings);
|
||||
|
@ -115,6 +155,15 @@ class EntityReferenceSettingsTest extends KernelTestBase {
|
|||
// Delete the custom bundle.
|
||||
entity_test_delete_bundle($this->customBundle, 'entity_test');
|
||||
|
||||
// Ensure that field_field_config_presave() logs the expected critical
|
||||
// error.
|
||||
$log_message = $this->container->get($this->testLogServiceName)->cleanLogs()[0];
|
||||
$this->assertEquals(RfcLogLevel::CRITICAL, $log_message[0]);
|
||||
$this->assertEquals('The %field_name entity reference field (entity_type: %entity_type, bundle: %bundle) no longer has any valid bundle it can reference. The field is not working correctly anymore and has to be adjusted.', $log_message[1]);
|
||||
$this->assertEquals($field_config->getName(), $log_message[2]['%field_name']);
|
||||
$this->assertEquals('node', $log_message[2]['%entity_type']);
|
||||
$this->assertEquals($this->nodeType->id(), $log_message[2]['%bundle']);
|
||||
|
||||
// Check that the deleted bundle is no longer present in the
|
||||
// 'target_bundles' field setting.
|
||||
$field_config = FieldConfig::loadByName('node', $this->nodeType->id(), $name);
|
||||
|
@ -122,4 +171,14 @@ class EntityReferenceSettingsTest extends KernelTestBase {
|
|||
$this->assertTrue(empty($handler_settings['target_bundles']));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function register(ContainerBuilder $container) {
|
||||
parent::register($container);
|
||||
$container
|
||||
->register($this->testLogServiceName, BufferingLogger::class)
|
||||
->addTag('logger');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@ namespace Drupal\Tests\field\Kernel\EntityReference\Views;
|
|||
|
||||
use Drupal\entity_test\Entity\EntityTestMulChanged;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\entity_test\Entity\EntityTestMul;
|
||||
use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
|
||||
use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
use Drupal\views\Views;
|
||||
|
@ -34,7 +34,7 @@ class EntityReferenceRelationshipTest extends ViewsKernelTestBase {
|
|||
'test_entity_reference_entity_test_mul_view',
|
||||
'test_entity_reference_reverse_entity_test_mul_view',
|
||||
'test_entity_reference_group_by_empty_relationships',
|
||||
];
|
||||
];
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
|
@ -67,7 +67,7 @@ class EntityReferenceRelationshipTest extends ViewsKernelTestBase {
|
|||
// Create reference from entity_test_mul to entity_test.
|
||||
$this->createEntityReferenceField('entity_test_mul', 'entity_test_mul', 'field_data_test', 'field_data_test', 'entity_test');
|
||||
|
||||
// Create another field for testing with a long name. So it's storage name
|
||||
// Create another field for testing with a long name. So its storage name
|
||||
// will become hashed. Use entity_test_mul_changed, so the resulting field
|
||||
// tables created will be greater than 48 chars long.
|
||||
// @see \Drupal\Core\Entity\Sql\DefaultTableMapping::generateFieldTableName()
|
||||
|
@ -272,7 +272,7 @@ class EntityReferenceRelationshipTest extends ViewsKernelTestBase {
|
|||
$this->assertEqual($row->_entity->id(), $this->entities[$index]->id());
|
||||
|
||||
// Test the forward relationship.
|
||||
//$this->assertEqual($row->entity_test_entity_test_mul__field_data_test_id, 1);
|
||||
// $this->assertEqual($row->entity_test_entity_test_mul__field_data_test_id, 1);
|
||||
|
||||
// Test that the correct relationship entity is on the row.
|
||||
$this->assertEqual($row->_relationship_entities['field_test_data_with_a_long_name']->id(), 1);
|
||||
|
@ -331,6 +331,15 @@ class EntityReferenceRelationshipTest extends ViewsKernelTestBase {
|
|||
// Fourth result has no reference from EntityTestMul hence the output for
|
||||
// should be empty.
|
||||
$this->assertEqual('', $view->getStyle()->getField(3, 'name_2'));
|
||||
|
||||
$fields = $view->field;
|
||||
// Check getValue for reference with a value. The first 3 rows reference
|
||||
// EntityTestMul, so have value 'name1'.
|
||||
$this->assertEquals('name1', $fields['name_2']->getValue($view->result[0]));
|
||||
$this->assertEquals('name1', $fields['name_2']->getValue($view->result[1]));
|
||||
$this->assertEquals('name1', $fields['name_2']->getValue($view->result[2]));
|
||||
// Ensure getValue works on empty references.
|
||||
$this->assertNull($fields['name_2']->getValue($view->result[3]));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
|
@ -291,7 +291,7 @@ class FieldAttachStorageTest extends FieldKernelTestBase {
|
|||
$cardinality = $this->fieldTestData->field_storage->getCardinality();
|
||||
|
||||
// Create a new bundle.
|
||||
$new_bundle = 'test_bundle_' . Unicode::strtolower($this->randomMachineName());
|
||||
$new_bundle = 'test_bundle_' . mb_strtolower($this->randomMachineName());
|
||||
entity_test_create_bundle($new_bundle, NULL, $entity_type);
|
||||
|
||||
// Add a field to that bundle.
|
||||
|
@ -318,7 +318,7 @@ class FieldAttachStorageTest extends FieldKernelTestBase {
|
|||
$this->createFieldWithStorage('', $entity_type);
|
||||
|
||||
// Create a new bundle.
|
||||
$new_bundle = 'test_bundle_' . Unicode::strtolower($this->randomMachineName());
|
||||
$new_bundle = 'test_bundle_' . mb_strtolower($this->randomMachineName());
|
||||
entity_test_create_bundle($new_bundle, NULL, $entity_type);
|
||||
|
||||
// Add a field to that bundle.
|
||||
|
@ -326,7 +326,7 @@ class FieldAttachStorageTest extends FieldKernelTestBase {
|
|||
FieldConfig::create($this->fieldTestData->field_definition)->save();
|
||||
|
||||
// Create a second field for the test bundle
|
||||
$field_name = Unicode::strtolower($this->randomMachineName() . '_field_name');
|
||||
$field_name = mb_strtolower($this->randomMachineName() . '_field_name');
|
||||
$field_storage = [
|
||||
'field_name' => $field_name,
|
||||
'entity_type' => $entity_type,
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Entity\EntityStorageException;
|
||||
use Drupal\Core\Field\FieldException;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
|
@ -12,6 +11,8 @@ use Drupal\field\Entity\FieldConfig;
|
|||
/**
|
||||
* Create field entities by attaching fields to entities.
|
||||
*
|
||||
* @coversDefaultClass \Drupal\Core\Field\FieldConfigBase
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class FieldCrudTest extends FieldKernelTestBase {
|
||||
|
@ -41,7 +42,7 @@ class FieldCrudTest extends FieldKernelTestBase {
|
|||
parent::setUp();
|
||||
|
||||
$this->fieldStorageDefinition = [
|
||||
'field_name' => Unicode::strtolower($this->randomMachineName()),
|
||||
'field_name' => mb_strtolower($this->randomMachineName()),
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'test_field',
|
||||
];
|
||||
|
@ -64,10 +65,6 @@ class FieldCrudTest extends FieldKernelTestBase {
|
|||
* Test the creation of a field.
|
||||
*/
|
||||
public function testCreateField() {
|
||||
// Set a state flag so that field_test.module knows to add an in-memory
|
||||
// constraint for this field.
|
||||
\Drupal::state()->set('field_test_add_constraint', $this->fieldStorage->getName());
|
||||
/** @var \Drupal\Core\Field\FieldConfigInterface $field */
|
||||
$field = FieldConfig::create($this->fieldDefinition);
|
||||
$field->save();
|
||||
|
||||
|
@ -100,17 +97,6 @@ class FieldCrudTest extends FieldKernelTestBase {
|
|||
// Check that the denormalized 'field_type' was properly written.
|
||||
$this->assertEqual($config['field_type'], $this->fieldStorageDefinition['type']);
|
||||
|
||||
// Test constraints are applied. A Range constraint is added dynamically to
|
||||
// limit the field to values between 0 and 32.
|
||||
// @see field_test_entity_bundle_field_info_alter()
|
||||
$this->doFieldValidationTests();
|
||||
|
||||
// Test FieldConfigBase::setPropertyConstraints().
|
||||
\Drupal::state()->set('field_test_set_constraint', $this->fieldStorage->getName());
|
||||
\Drupal::state()->set('field_test_add_constraint', FALSE);
|
||||
\Drupal::entityManager()->clearCachedFieldDefinitions();
|
||||
$this->doFieldValidationTests();
|
||||
|
||||
// Guarantee that the field/bundle combination is unique.
|
||||
try {
|
||||
FieldConfig::create($this->fieldDefinition)->save();
|
||||
|
@ -133,11 +119,86 @@ class FieldCrudTest extends FieldKernelTestBase {
|
|||
// TODO: test other failures.
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests setting and adding property constraints to a configurable field.
|
||||
*
|
||||
* @covers ::setPropertyConstraints
|
||||
* @covers ::addPropertyConstraints
|
||||
*/
|
||||
public function testFieldPropertyConstraints() {
|
||||
$field = FieldConfig::create($this->fieldDefinition);
|
||||
$field->save();
|
||||
$field_name = $this->fieldStorage->getName();
|
||||
|
||||
// Test that constraints are applied to configurable fields. A TestField and
|
||||
// a Range constraint are added dynamically to limit the field to values
|
||||
// between 0 and 32.
|
||||
// @see field_test_entity_bundle_field_info_alter()
|
||||
\Drupal::state()->set('field_test_constraint', $field_name);
|
||||
|
||||
// Clear the field definitions cache so the new constraints added by
|
||||
// field_test_entity_bundle_field_info_alter() are taken into consideration.
|
||||
\Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();
|
||||
|
||||
// Test the newly added property constraints in the same request as when the
|
||||
// caches were cleared. This will test the field definitions that are stored
|
||||
// in the static cache of
|
||||
// \Drupal\Core\Entity\EntityFieldManager::getFieldDefinitions().
|
||||
$this->doFieldPropertyConstraintsTests();
|
||||
|
||||
// In order to test a real-world scenario where the property constraints are
|
||||
// only stored in the persistent cache of
|
||||
// \Drupal\Core\Entity\EntityFieldManager::getFieldDefinitions(), we need to
|
||||
// simulate a new request by removing the 'entity_field.manager' service,
|
||||
// thus forcing it to be re-initialized without static caches.
|
||||
\Drupal::getContainer()->set('entity_field.manager', NULL);
|
||||
|
||||
// This will test the field definitions that are stored in the persistent
|
||||
// cache by \Drupal\Core\Entity\EntityFieldManager::getFieldDefinitions().
|
||||
$this->doFieldPropertyConstraintsTests();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests configurable field validation.
|
||||
*
|
||||
* @see field_test_entity_bundle_field_info_alter()
|
||||
*/
|
||||
protected function doFieldPropertyConstraintsTests() {
|
||||
$field_name = $this->fieldStorage->getName();
|
||||
|
||||
// Check that a valid value (not -2 and between 0 and 32) doesn't trigger
|
||||
// any violation.
|
||||
$entity = EntityTest::create();
|
||||
$entity->set($field_name, 1);
|
||||
$violations = $entity->validate();
|
||||
$this->assertCount(0, $violations, 'No violations found when in-range value passed.');
|
||||
|
||||
// Check that a value that is specifically restricted triggers both
|
||||
// violations.
|
||||
$entity->set($field_name, -2);
|
||||
$violations = $entity->validate();
|
||||
$this->assertCount(2, $violations, 'Two violations found when using a null and outside the range value.');
|
||||
|
||||
$this->assertEquals($field_name . '.0.value', $violations[0]->getPropertyPath());
|
||||
$this->assertEquals(t('%name does not accept the value @value.', ['%name' => $field_name, '@value' => -2]), $violations[0]->getMessage());
|
||||
|
||||
$this->assertEquals($field_name . '.0.value', $violations[1]->getPropertyPath());
|
||||
$this->assertEquals(t('This value should be %limit or more.', ['%limit' => 0]), $violations[1]->getMessage());
|
||||
|
||||
// Check that a value that is not specifically restricted but outside the
|
||||
// range triggers the expected violation.
|
||||
$entity->set($field_name, 33);
|
||||
$violations = $entity->validate();
|
||||
$this->assertCount(1, $violations, 'Violations found when using value outside the range.');
|
||||
$this->assertEquals($field_name . '.0.value', $violations[0]->getPropertyPath());
|
||||
$this->assertEquals(t('This value should be %limit or less.', ['%limit' => 32]), $violations[0]->getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creating a field with custom storage set.
|
||||
*/
|
||||
public function testCreateFieldCustomStorage() {
|
||||
$field_name = Unicode::strtolower($this->randomMachineName());
|
||||
$field_name = mb_strtolower($this->randomMachineName());
|
||||
\Drupal::state()->set('field_test_custom_storage', $field_name);
|
||||
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
|
@ -207,12 +268,11 @@ class FieldCrudTest extends FieldKernelTestBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Test the deletion of a field.
|
||||
* Test the deletion of a field with no data.
|
||||
*/
|
||||
public function testDeleteField() {
|
||||
// TODO: Test deletion of the data stored in the field also.
|
||||
// Need to check that data for a 'deleted' field / storage doesn't get loaded
|
||||
// Need to check data marked deleted is cleaned on cron (not implemented yet...)
|
||||
public function testDeleteFieldNoData() {
|
||||
// Deleting and purging fields with data is tested in
|
||||
// \Drupal\Tests\field\Kernel\BulkDeleteTest.
|
||||
|
||||
// Create two fields for the same field storage so we can test that only one
|
||||
// is deleted.
|
||||
|
@ -227,17 +287,18 @@ class FieldCrudTest extends FieldKernelTestBase {
|
|||
$this->assertTrue(!empty($field) && empty($field->deleted), 'A new field is not marked for deletion.');
|
||||
$field->delete();
|
||||
|
||||
// Make sure the field is marked as deleted when it is specifically loaded.
|
||||
$field = current(entity_load_multiple_by_properties('field_config', ['entity_type' => 'entity_test', 'field_name' => $this->fieldDefinition['field_name'], 'bundle' => $this->fieldDefinition['bundle'], 'include_deleted' => TRUE]));
|
||||
$this->assertTrue($field->isDeleted(), 'A deleted field is marked for deletion.');
|
||||
// Make sure the field was deleted without being marked for purging as there
|
||||
// was no data.
|
||||
$fields = entity_load_multiple_by_properties('field_config', ['entity_type' => 'entity_test', 'field_name' => $this->fieldDefinition['field_name'], 'bundle' => $this->fieldDefinition['bundle'], 'include_deleted' => TRUE]);
|
||||
$this->assertEquals(0, count($fields), 'A deleted field is marked for deletion.');
|
||||
|
||||
// Try to load the field normally and make sure it does not show up.
|
||||
$field = FieldConfig::load('entity_test.' . '.' . $this->fieldDefinition['bundle'] . '.' . $this->fieldDefinition['field_name']);
|
||||
$this->assertTrue(empty($field), 'A deleted field is not loaded by default.');
|
||||
$this->assertTrue(empty($field), 'Field was deleted');
|
||||
|
||||
// Make sure the other field is not deleted.
|
||||
$another_field = FieldConfig::load('entity_test.' . $another_field_definition['bundle'] . '.' . $another_field_definition['field_name']);
|
||||
$this->assertTrue(!empty($another_field) && empty($another_field->deleted), 'A non-deleted field is not marked for deletion.');
|
||||
$this->assertTrue(!empty($another_field) && !$another_field->isDeleted(), 'A non-deleted field is not marked for deletion.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -280,24 +341,4 @@ class FieldCrudTest extends FieldKernelTestBase {
|
|||
$this->assertFalse(FieldStorageConfig::loadByName('entity_test', $field_storage->getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests configurable field validation.
|
||||
*
|
||||
* @see field_test_entity_bundle_field_info_alter()
|
||||
*/
|
||||
protected function doFieldValidationTests() {
|
||||
$entity = EntityTest::create();
|
||||
$entity->set($this->fieldStorage->getName(), 1);
|
||||
$violations = $entity->validate();
|
||||
$this->assertEqual(count($violations), 0, 'No violations found when in-range value passed.');
|
||||
|
||||
$entity->set($this->fieldStorage->getName(), 33);
|
||||
$violations = $entity->validate();
|
||||
$this->assertEqual(count($violations), 1, 'Violations found when using value outside the range.');
|
||||
$this->assertEqual($violations[0]->getPropertyPath(), $this->fieldStorage->getName() . '.0.value');
|
||||
$this->assertEqual($violations[0]->getMessage(), t('This value should be %limit or less.', [
|
||||
'%limit' => 32,
|
||||
]));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,13 @@
|
|||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
|
||||
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Core\Entity\ContentEntityTypeInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Extension\Extension;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
|
@ -21,22 +27,13 @@ class FieldDefinitionIntegrityTest extends KernelTestBase {
|
|||
* Tests the integrity of field plugin definitions.
|
||||
*/
|
||||
public function testFieldPluginDefinitionIntegrity() {
|
||||
|
||||
// Enable all core modules that provide field plugins.
|
||||
$modules = system_rebuild_module_data();
|
||||
$modules = array_filter($modules, function (Extension $module) {
|
||||
// Filter contrib, hidden, already enabled modules and modules in the
|
||||
// Testing package.
|
||||
if ($module->origin === 'core'
|
||||
&& empty($module->info['hidden'])
|
||||
&& $module->status == FALSE
|
||||
&& $module->info['package'] !== 'Testing'
|
||||
&& is_readable($module->getPath() . '/src/Plugin/Field')) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
});
|
||||
$this->enableModules(array_keys($modules));
|
||||
// Enable all core modules that provide field plugins, and their
|
||||
// dependencies.
|
||||
$this->enableModules(
|
||||
$this->modulesWithSubdirectory(
|
||||
'src' . DIRECTORY_SEPARATOR . 'Plugin' . DIRECTORY_SEPARATOR . 'Field'
|
||||
)
|
||||
);
|
||||
|
||||
/** @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface $field_type_manager */
|
||||
$field_type_manager = \Drupal::service('plugin.manager.field.field_type');
|
||||
|
@ -108,7 +105,114 @@ class FieldDefinitionIntegrityTest extends KernelTestBase {
|
|||
else {
|
||||
$this->pass(sprintf('Field formatter %s integrates with existing field types.', $definition['id']));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to load field plugin definitions used in core's existing entities.
|
||||
*/
|
||||
public function testFieldPluginDefinitionAvailability() {
|
||||
$this->enableModules(
|
||||
$this->modulesWithSubdirectory('src' . DIRECTORY_SEPARATOR . 'Entity')
|
||||
);
|
||||
|
||||
/** @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface $field_type_manager */
|
||||
$field_formatter_manager = $this->container->get('plugin.manager.field.formatter');
|
||||
|
||||
/** @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface $field_type_manager */
|
||||
$field_widget_manager = $this->container->get('plugin.manager.field.widget');
|
||||
|
||||
/** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */
|
||||
$entity_field_manager = $this->container->get('entity_field.manager');
|
||||
|
||||
/** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
|
||||
$entity_type_manager = $this->container->get('entity_type.manager');
|
||||
|
||||
/** @var \Drupal\Core\Field\BaseFieldDefinition[][] $field_definitions */
|
||||
$field_definitions = [];
|
||||
|
||||
/** @var \Drupal\Core\Entity\EntityTypeInterface[] $content_entity_types */
|
||||
$content_entity_types = array_filter($entity_type_manager->getDefinitions(), function (EntityTypeInterface $entity_type) {
|
||||
return $entity_type instanceof ContentEntityTypeInterface;
|
||||
});
|
||||
|
||||
foreach ($content_entity_types as $entity_type_id => $entity_type_definition) {
|
||||
$field_definitions[$entity_type_id] = $entity_field_manager->getBaseFieldDefinitions($entity_type_id);
|
||||
}
|
||||
|
||||
foreach ($field_definitions as $entity_type_id => $definitions) {
|
||||
foreach ($definitions as $field_id => $field_definition) {
|
||||
$this->checkDisplayOption($entity_type_id, $field_id, $field_definition, $field_formatter_manager, 'view');
|
||||
$this->checkDisplayOption($entity_type_id, $field_id, $field_definition, $field_widget_manager, 'form');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that tries to load plugin definitions.
|
||||
*
|
||||
* @param string $entity_type_id
|
||||
* Id of entity type. Required by message.
|
||||
* @param string $field_id
|
||||
* Id of field. Required by message.
|
||||
* @param \Drupal\Core\Field\BaseFieldDefinition $field_definition
|
||||
* Field definition that provide display options.
|
||||
* @param \Drupal\Component\Plugin\Discovery\DiscoveryInterface $plugin_manager
|
||||
* Plugin manager that will try to provide plugin definition.
|
||||
* @param string $display_context
|
||||
* Defines which display options should be loaded.
|
||||
*/
|
||||
protected function checkDisplayOption($entity_type_id, $field_id, BaseFieldDefinition $field_definition, DiscoveryInterface $plugin_manager, $display_context) {
|
||||
$display_options = $field_definition->getDisplayOptions($display_context);
|
||||
if (!empty($display_options['type'])) {
|
||||
try {
|
||||
$plugin_manager->getDefinition($display_options['type']);
|
||||
}
|
||||
catch (PluginNotFoundException $e) {
|
||||
$this->fail(sprintf(
|
||||
'PluginNotFoundException here for "%s" field %s display options of "%s" entity type. Original message: %s',
|
||||
$field_id,
|
||||
$display_context,
|
||||
$entity_type_id,
|
||||
$e->getMessage()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find modules with a specified subdirectory.
|
||||
*
|
||||
* @param string $subdirectory
|
||||
* The required path, relative to the module directory.
|
||||
*
|
||||
* @return string[]
|
||||
* A list of module names satisfying these criteria:
|
||||
* - provided by core
|
||||
* - not hidden
|
||||
* - not already enabled
|
||||
* - not in the Testing package
|
||||
* - containing the required $subdirectory
|
||||
* and all modules required by any of these modules.
|
||||
*/
|
||||
protected function modulesWithSubdirectory($subdirectory) {
|
||||
$modules = system_rebuild_module_data();
|
||||
$modules = array_filter($modules, function (Extension $module) use ($subdirectory) {
|
||||
// Filter contrib, hidden, already enabled modules and modules in the
|
||||
// Testing package.
|
||||
return ($module->origin === 'core'
|
||||
&& empty($module->info['hidden'])
|
||||
&& $module->status == FALSE
|
||||
&& $module->info['package'] !== 'Testing'
|
||||
&& is_readable($module->getPath() . DIRECTORY_SEPARATOR . $subdirectory));
|
||||
});
|
||||
// Gather the dependencies of the modules.
|
||||
$dependencies = NestedArray::mergeDeepArray(array_map(function (Extension $module) {
|
||||
return array_keys($module->requires);
|
||||
}, $modules));
|
||||
|
||||
return array_unique(NestedArray::mergeDeep(array_keys($modules), $dependencies));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
126
web/core/modules/field/tests/src/Kernel/FieldDisplayTest.php
Normal file
126
web/core/modules/field/tests/src/Kernel/FieldDisplayTest.php
Normal file
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTestRev;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Symfony\Component\CssSelector\CssSelectorConverter;
|
||||
|
||||
/**
|
||||
* Tests Field display.
|
||||
*
|
||||
* @group field
|
||||
*/
|
||||
class FieldDisplayTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = [
|
||||
'entity_test',
|
||||
'field',
|
||||
'system',
|
||||
'user',
|
||||
];
|
||||
|
||||
/**
|
||||
* Test entity type name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $entityType;
|
||||
|
||||
/**
|
||||
* Test entity bundle name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $bundle;
|
||||
|
||||
/**
|
||||
* Test field name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldName;
|
||||
|
||||
/**
|
||||
* Entity view display.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface
|
||||
*/
|
||||
protected $display;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Configure the theme system.
|
||||
$this->installConfig(['system', 'field']);
|
||||
$this->installEntitySchema('entity_test_rev');
|
||||
|
||||
$this->entityType = 'entity_test_rev';
|
||||
$this->bundle = $this->entityType;
|
||||
$this->fieldName = mb_strtolower($this->randomMachineName());
|
||||
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => $this->fieldName,
|
||||
'entity_type' => $this->entityType,
|
||||
'type' => 'string',
|
||||
]);
|
||||
$field_storage->save();
|
||||
|
||||
$instance = FieldConfig::create([
|
||||
'field_storage' => $field_storage,
|
||||
'bundle' => $this->bundle,
|
||||
'label' => $this->randomMachineName(),
|
||||
]);
|
||||
$instance->save();
|
||||
|
||||
$values = [
|
||||
'targetEntityType' => $this->entityType,
|
||||
'bundle' => $this->bundle,
|
||||
'mode' => 'default',
|
||||
'status' => TRUE,
|
||||
];
|
||||
|
||||
$this->display = \Drupal::entityTypeManager()
|
||||
->getStorage('entity_view_display')
|
||||
->create($values);
|
||||
$this->display->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that visually hidden works with core.
|
||||
*/
|
||||
public function testFieldVisualHidden() {
|
||||
$value = $this->randomMachineName();
|
||||
|
||||
// Set the formatter to link to the entity.
|
||||
$this->display->setComponent($this->fieldName, [
|
||||
'type' => 'string',
|
||||
'label' => 'visually_hidden',
|
||||
'settings' => [],
|
||||
])->save();
|
||||
|
||||
$entity = EntityTestRev::create([]);
|
||||
$entity->{$this->fieldName}->value = $value;
|
||||
$entity->save();
|
||||
|
||||
$build = $this->display->build($entity);
|
||||
$renderer = \Drupal::service('renderer');
|
||||
$content = $renderer->renderPlain($build);
|
||||
$this->setRawContent((string) $content);
|
||||
|
||||
$css_selector_converter = new CssSelectorConverter();
|
||||
$elements = $this->xpath($css_selector_converter->toXPath('.visually-hidden'));
|
||||
$this->assertCount(1, $elements, $content);
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
|
@ -50,6 +51,14 @@ class FieldImportDeleteTest extends FieldKernelTestBase {
|
|||
$field_config_name_2a = "field.field.$field_id_2a";
|
||||
$field_config_name_2b = "field.field.$field_id_2b";
|
||||
|
||||
// Create an entity with data in the first field to make sure that field
|
||||
// needs to be purged.
|
||||
$entity_test = EntityTest::create([
|
||||
'type' => 'entity_test',
|
||||
]);
|
||||
$entity_test->set($field_name, 'test data');
|
||||
$entity_test->save();
|
||||
|
||||
// Create a second bundle for the 'Entity test' entity type.
|
||||
entity_test_create_bundle('test_bundle');
|
||||
|
||||
|
@ -60,11 +69,11 @@ class FieldImportDeleteTest extends FieldKernelTestBase {
|
|||
$active = $this->container->get('config.storage');
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
$this->copyConfig($active, $sync);
|
||||
$this->assertTrue($sync->delete($field_storage_config_name), SafeMarkup::format('Deleted field storage: @field_storage', ['@field_storage' => $field_storage_config_name]));
|
||||
$this->assertTrue($sync->delete($field_storage_config_name_2), SafeMarkup::format('Deleted field storage: @field_storage', ['@field_storage' => $field_storage_config_name_2]));
|
||||
$this->assertTrue($sync->delete($field_config_name), SafeMarkup::format('Deleted field: @field', ['@field' => $field_config_name]));
|
||||
$this->assertTrue($sync->delete($field_config_name_2a), SafeMarkup::format('Deleted field: @field', ['@field' => $field_config_name_2a]));
|
||||
$this->assertTrue($sync->delete($field_config_name_2b), SafeMarkup::format('Deleted field: @field', ['@field' => $field_config_name_2b]));
|
||||
$this->assertTrue($sync->delete($field_storage_config_name), new FormattableMarkup('Deleted field storage: @field_storage', ['@field_storage' => $field_storage_config_name]));
|
||||
$this->assertTrue($sync->delete($field_storage_config_name_2), new FormattableMarkup('Deleted field storage: @field_storage', ['@field_storage' => $field_storage_config_name_2]));
|
||||
$this->assertTrue($sync->delete($field_config_name), new FormattableMarkup('Deleted field: @field', ['@field' => $field_config_name]));
|
||||
$this->assertTrue($sync->delete($field_config_name_2a), new FormattableMarkup('Deleted field: @field', ['@field' => $field_config_name_2a]));
|
||||
$this->assertTrue($sync->delete($field_config_name_2b), new FormattableMarkup('Deleted field: @field', ['@field' => $field_config_name_2b]));
|
||||
|
||||
$deletes = $this->configImporter()->getUnprocessedConfiguration('delete');
|
||||
$this->assertEqual(count($deletes), 5, 'Importing configuration will delete 3 fields and 2 field storages.');
|
||||
|
@ -97,10 +106,10 @@ class FieldImportDeleteTest extends FieldKernelTestBase {
|
|||
$this->assertIdentical($active->listAll($field_config_name_2a), []);
|
||||
$this->assertIdentical($active->listAll($field_config_name_2b), []);
|
||||
|
||||
// Check that the storage definition is preserved in state.
|
||||
// Check that only the first storage definition is preserved in state.
|
||||
$deleted_storages = \Drupal::state()->get('field.storage.deleted') ?: [];
|
||||
$this->assertTrue(isset($deleted_storages[$field_storage_uuid]));
|
||||
$this->assertTrue(isset($deleted_storages[$field_storage_uuid_2]));
|
||||
$this->assertFalse(isset($deleted_storages[$field_storage_uuid_2]));
|
||||
|
||||
// Purge field data, and check that the storage definition has been
|
||||
// completely removed once the data is purged.
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
|
@ -87,7 +86,7 @@ abstract class FieldKernelTestBase extends KernelTestBase {
|
|||
$field = 'field' . $suffix;
|
||||
$field_definition = 'field_definition' . $suffix;
|
||||
|
||||
$this->fieldTestData->$field_name = Unicode::strtolower($this->randomMachineName() . '_field_name' . $suffix);
|
||||
$this->fieldTestData->$field_name = mb_strtolower($this->randomMachineName() . '_field_name' . $suffix);
|
||||
$this->fieldTestData->$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => $this->fieldTestData->$field_name,
|
||||
'entity_type' => $entity_type,
|
||||
|
@ -113,7 +112,7 @@ abstract class FieldKernelTestBase extends KernelTestBase {
|
|||
'type' => 'test_field_widget',
|
||||
'settings' => [
|
||||
'test_widget_setting' => $this->randomMachineName(),
|
||||
]
|
||||
],
|
||||
])
|
||||
->save();
|
||||
}
|
||||
|
@ -172,7 +171,7 @@ abstract class FieldKernelTestBase extends KernelTestBase {
|
|||
*
|
||||
* This function only checks a single column in the field values.
|
||||
*
|
||||
* @param EntityInterface $entity
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity to test.
|
||||
* @param $field_name
|
||||
* The name of the field to test
|
||||
|
|
|
@ -113,7 +113,7 @@ class FieldStorageCrudTest extends FieldKernelTestBase {
|
|||
try {
|
||||
$field_storage_definition = [
|
||||
'field_name' => 'test_field',
|
||||
'type' => 'test_field'
|
||||
'type' => 'test_field',
|
||||
];
|
||||
FieldStorageConfig::create($field_storage_definition)->save();
|
||||
$this->fail('Cannot create a field without an entity type.');
|
||||
|
@ -188,7 +188,7 @@ class FieldStorageCrudTest extends FieldKernelTestBase {
|
|||
*/
|
||||
public function testCreateWithExplicitSchema() {
|
||||
$schema = [
|
||||
'dummy' => 'foobar'
|
||||
'dummy' => 'foobar',
|
||||
];
|
||||
$field_storage = FieldStorageConfig::create([
|
||||
'field_name' => 'field_2',
|
||||
|
@ -284,8 +284,9 @@ class FieldStorageCrudTest extends FieldKernelTestBase {
|
|||
/**
|
||||
* Test the deletion of a field storage.
|
||||
*/
|
||||
public function testDelete() {
|
||||
// TODO: Also test deletion of the data stored in the field ?
|
||||
public function testDeleteNoData() {
|
||||
// Deleting and purging field storages with data is tested in
|
||||
// \Drupal\Tests\field\Kernel\BulkDeleteTest.
|
||||
|
||||
// Create two fields (so we can test that only one is deleted).
|
||||
$field_storage_definition = [
|
||||
|
@ -317,23 +318,22 @@ class FieldStorageCrudTest extends FieldKernelTestBase {
|
|||
$this->assertTrue(!empty($field_storage) && !$field_storage->isDeleted(), 'A new storage is not marked for deletion.');
|
||||
FieldStorageConfig::loadByName('entity_test', $field_storage_definition['field_name'])->delete();
|
||||
|
||||
// Make sure that the field is marked as deleted when it is specifically
|
||||
// loaded.
|
||||
$field_storage = current(entity_load_multiple_by_properties('field_storage_config', ['field_name' => $field_storage_definition['field_name'], 'include_deleted' => TRUE]));
|
||||
$this->assertTrue($field_storage->isDeleted(), 'A deleted storage is marked for deletion.');
|
||||
// Make sure that the field storage is deleted as it had no data.
|
||||
$field_storages = entity_load_multiple_by_properties('field_storage_config', ['field_name' => $field_storage_definition['field_name'], 'include_deleted' => TRUE]);
|
||||
$this->assertEquals(0, count($field_storages), 'Field storage was deleted');
|
||||
|
||||
// Make sure that this field is marked as deleted when it is
|
||||
// specifically loaded.
|
||||
$field = current(entity_load_multiple_by_properties('field_config', ['entity_type' => 'entity_test', 'field_name' => $field_definition['field_name'], 'bundle' => $field_definition['bundle'], 'include_deleted' => TRUE]));
|
||||
$this->assertTrue($field->isDeleted(), 'A field whose storage was deleted is marked for deletion.');
|
||||
$fields = entity_load_multiple_by_properties('field_config', ['entity_type' => 'entity_test', 'field_name' => $field_definition['field_name'], 'bundle' => $field_definition['bundle'], 'include_deleted' => TRUE]);
|
||||
$this->assertEquals(0, count($fields), 'Field storage was deleted');
|
||||
|
||||
// Try to load the storage normally and make sure it does not show up.
|
||||
$field_storage = FieldStorageConfig::load('entity_test.' . $field_storage_definition['field_name']);
|
||||
$this->assertTrue(empty($field_storage), 'A deleted storage is not loaded by default.');
|
||||
$this->assertTrue(empty($field_storage), 'Field storage was deleted');
|
||||
|
||||
// Try to load the field normally and make sure it does not show up.
|
||||
$field = FieldConfig::load('entity_test.' . '.' . $field_definition['bundle'] . '.' . $field_definition['field_name']);
|
||||
$this->assertTrue(empty($field), 'A field whose storage was deleted is not loaded by default.');
|
||||
$this->assertTrue(empty($field), 'Field was deleted');
|
||||
|
||||
// Make sure the other field and its storage are not deleted.
|
||||
$another_field_storage = FieldStorageConfig::load('entity_test.' . $another_field_storage_definition['field_name']);
|
||||
|
@ -347,7 +347,7 @@ class FieldStorageCrudTest extends FieldKernelTestBase {
|
|||
FieldConfig::create($field_definition)->save();
|
||||
$field_storage = FieldStorageConfig::load('entity_test.' . $field_storage_definition['field_name']);
|
||||
$this->assertTrue(!empty($field_storage) && !$field_storage->isDeleted(), 'A new storage with a previously used name is created.');
|
||||
$field = FieldConfig::load('entity_test.' . $field_definition['bundle'] . '.' . $field_definition['field_name'] );
|
||||
$field = FieldConfig::load('entity_test.' . $field_definition['bundle'] . '.' . $field_definition['field_name']);
|
||||
$this->assertTrue(!empty($field) && !$field->isDeleted(), 'A new field for a previously used field name is created.');
|
||||
|
||||
// Save an entity with data for the field
|
||||
|
@ -433,8 +433,9 @@ class FieldStorageCrudTest extends FieldKernelTestBase {
|
|||
'type' => 'test_field',
|
||||
'settings' => [
|
||||
'changeable' => 0,
|
||||
'unchangeable' => 0
|
||||
]]);
|
||||
'unchangeable' => 0,
|
||||
],
|
||||
]);
|
||||
$field_storage->save();
|
||||
$field_storage->setSetting('changeable', $field_storage->getSetting('changeable') + 1);
|
||||
try {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Drupal\Tests\field\Kernel;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Core\Extension\ExtensionDiscovery;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
|
@ -48,8 +48,8 @@ class FieldTypePluginManagerTest extends FieldKernelTestBase {
|
|||
|
||||
$instance = $field_type_manager->createInstance($type, $configuration);
|
||||
|
||||
$this->assertTrue($instance instanceof $class, SafeMarkup::format('Created a @class instance', ['@class' => $class]));
|
||||
$this->assertEqual($field_name, $instance->getName(), SafeMarkup::format('Instance name is @name', ['@name' => $field_name]));
|
||||
$this->assertTrue($instance instanceof $class, new FormattableMarkup('Created a @class instance', ['@class' => $class]));
|
||||
$this->assertEqual($field_name, $instance->getName(), new FormattableMarkup('Instance name is @name', ['@name' => $field_name]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,8 +79,8 @@ class FieldTypePluginManagerTest extends FieldKernelTestBase {
|
|||
|
||||
$instance = $field_type_manager->createInstance($type, $configuration);
|
||||
|
||||
$this->assertTrue($instance instanceof $class, SafeMarkup::format('Created a @class instance', ['@class' => $class]));
|
||||
$this->assertEqual($field_name, $instance->getName(), SafeMarkup::format('Instance name is @name', ['@name' => $field_name]));
|
||||
$this->assertTrue($instance instanceof $class, new FormattableMarkup('Created a @class instance', ['@class' => $class]));
|
||||
$this->assertEqual($field_name, $instance->getName(), new FormattableMarkup('Instance name is @name', ['@name' => $field_name]));
|
||||
$this->assertEqual($instance->getFieldDefinition()->getLabel(), 'Jenny', 'Instance label is Jenny');
|
||||
$this->assertEqual($instance->getFieldDefinition()->getDefaultValue($entity), [['value' => 8675309]], 'Instance default_value is 8675309');
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ class FieldTypePluginManagerTest extends FieldKernelTestBase {
|
|||
* Enable all core modules.
|
||||
*/
|
||||
protected function enableAllCoreModules() {
|
||||
$listing = new ExtensionDiscovery(\Drupal::root());
|
||||
$listing = new ExtensionDiscovery($this->root);
|
||||
$module_list = $listing->scan('module', FALSE);
|
||||
/** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */
|
||||
$module_handler = $this->container->get('module_handler');
|
||||
|
|
|
@ -129,11 +129,14 @@ class MigrateFieldFormatterSettingsTest extends MigrateDrupal6TestBase {
|
|||
// Test the file field formatter settings.
|
||||
$expected['weight'] = 8;
|
||||
$expected['type'] = 'file_default';
|
||||
$expected['settings'] = [];
|
||||
$expected['settings'] = [
|
||||
'use_description_as_link_text' => TRUE,
|
||||
];
|
||||
$component = $display->getComponent('field_test_filefield');
|
||||
$this->assertIdentical($expected, $component);
|
||||
$display = EntityViewDisplay::load('node.story.default');
|
||||
$expected['type'] = 'file_url_plain';
|
||||
$expected['settings'] = [];
|
||||
$component = $display->getComponent('field_test_filefield');
|
||||
$this->assertIdentical($expected, $component);
|
||||
|
||||
|
@ -194,7 +197,7 @@ class MigrateFieldFormatterSettingsTest extends MigrateDrupal6TestBase {
|
|||
$component = $display->getComponent('field_test_datetime');
|
||||
$this->assertIdentical($expected, $component);
|
||||
// Test that our Id map has the correct data.
|
||||
$this->assertIdentical(['node', 'story', 'teaser', 'field_test'], $this->getMigration('d6_field_formatter_settings')->getIdMap()->lookupDestinationID(['story', 'teaser', 'node', 'field_test']));
|
||||
$this->assertIdentical(['node', 'story', 'teaser', 'field_test'], $this->getMigration('d6_field_formatter_settings')->getIdMap()->lookupDestinationId(['story', 'teaser', 'node', 'field_test']));
|
||||
|
||||
// Test hidden field.
|
||||
$this->assertComponentNotExists('node.test_planet.teaser', 'field_test_text_single_checkbox');
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Tests\migrate\Kernel\MigrateDumpAlterInterface;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Tests migration field label and description i18n translations.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
* @group legacy
|
||||
*/
|
||||
class MigrateFieldInstanceLabelDescriptionTest extends MigrateDrupal6TestBase implements MigrateDumpAlterInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'config_translation',
|
||||
'locale',
|
||||
'language',
|
||||
'menu_ui',
|
||||
'node',
|
||||
'field',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->migrateFields();
|
||||
|
||||
$this->installEntitySchema('node');
|
||||
$this->installConfig(['node']);
|
||||
$this->installSchema('node', ['node_access']);
|
||||
$this->installSchema('system', ['sequences']);
|
||||
$this->executeMigration('language');
|
||||
$this->executeMigration('d6_field_instance_label_description_translation');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function migrateDumpAlter(KernelTestBase $test) {
|
||||
$db = Database::getConnection('default', 'migrate');
|
||||
// Alter the database to test the migration is successful when a translated
|
||||
// field is deleted but the translation data for that field remains in both
|
||||
// the i18n_strings and locales_target tables.
|
||||
$db->delete('content_node_field_instance')
|
||||
->condition('field_name', 'field_test')
|
||||
->condition('type_name', 'story')
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of file variables to file.settings.yml.
|
||||
*/
|
||||
public function testFieldInstanceLabelDescriptionTranslationMigration() {
|
||||
$language_manager = $this->container->get('language_manager');
|
||||
|
||||
// Tests fields on 'story' node type.
|
||||
// Check that the deleted field with translations was skipped.
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test');
|
||||
$this->assertNull($config_translation->get('label'));
|
||||
$this->assertNull($config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_two');
|
||||
$this->assertSame("fr - Integer Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example integer field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_four');
|
||||
$this->assertSame("fr - Float Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example float field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_email');
|
||||
$this->assertSame("fr - Email Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example email field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_imagefield');
|
||||
$this->assertSame("fr - Image Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example image field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('zu', 'field.field.node.story.field_test_imagefield');
|
||||
$this->assertSame("zu - Image Field", $config_translation->get('label'));
|
||||
$this->assertSame("zu - An example image field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_filefield');
|
||||
$this->assertSame("fr - File Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example file field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_link');
|
||||
$this->assertSame("fr - Link Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example link field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_date');
|
||||
$this->assertSame("fr - Date Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example date field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_datetime');
|
||||
$this->assertSame("fr - Datetime Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example datetime field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_datestamp');
|
||||
$this->assertSame("fr - Date Stamp Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example date stamp field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_date');
|
||||
$this->assertSame("fr - Date Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example date field.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_phone');
|
||||
$this->assertSame("fr - Phone Field", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example phone field.", $config_translation->get('description'));
|
||||
|
||||
// Tests fields on 'test_page' node type.
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.test_page.field_test');
|
||||
$this->assertSame("Champ de texte", $config_translation->get('label'));
|
||||
$this->assertSame("fr - An example text field.", $config_translation->get('description'));
|
||||
|
||||
// Tests fields on 'test_planet' node type.
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.test_planet.field_multivalue');
|
||||
$this->assertSame("fr - Decimal Field", $config_translation->get('label'));
|
||||
$this->assertSame("Un exemple plusieurs valeurs champ décimal.", $config_translation->get('description'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.test_planet.field_test_text_single_checkbox');
|
||||
$this->assertNull($config_translation->get('label'));
|
||||
$this->assertSame('fr - An example text field using a single on/off checkbox.', $config_translation->get('description'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Migrate field instance option translations.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateFieldInstanceOptionTranslationTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules =
|
||||
[
|
||||
'config_translation',
|
||||
'language',
|
||||
'locale',
|
||||
'menu_ui',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(['node']);
|
||||
$this->executeMigrations([
|
||||
'language',
|
||||
'd6_node_type',
|
||||
'd6_field',
|
||||
'd6_field_instance',
|
||||
'd6_field_option_translation',
|
||||
'd6_field_instance_option_translation',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests migration of file variables to file.settings.yml.
|
||||
*/
|
||||
public function testFieldInstanceOptionTranslation() {
|
||||
$language_manager = $this->container->get('language_manager');
|
||||
|
||||
/** @var \Drupal\language\Config\LanguageConfigOverride $config_translation */
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_float_single_checkbox');
|
||||
$option_translation = ['on_label' => 'fr - 1.234'];
|
||||
$this->assertSame($option_translation, $config_translation->get('settings'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('zu', 'field.field.node.story.field_test_float_single_checkbox');
|
||||
$option_translation = ['on_label' => 'zu - 1.234'];
|
||||
$this->assertSame($option_translation, $config_translation->get('settings'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_text_single_checkbox');
|
||||
$option_translation = [
|
||||
'off_label' => 'fr - Hello',
|
||||
'on_label' => 'fr - Goodbye',
|
||||
];
|
||||
$this->assertSame($option_translation, $config_translation->get('settings'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.story.field_test_text_single_checkbox2');
|
||||
$option_translation = [
|
||||
'off_label' => 'fr - Off',
|
||||
'on_label' => 'fr - Hello',
|
||||
];
|
||||
$this->assertSame($option_translation, $config_translation->get('settings'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('zu', 'field.field.node.story.field_test_text_single_checkbox2');
|
||||
$option_translation = ['on_label' => 'zu - Hello'];
|
||||
$this->assertSame($option_translation, $config_translation->get('settings'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
|
||||
/**
|
||||
* Migrate field option translations.
|
||||
*
|
||||
* @group migrate_drupal_6
|
||||
*/
|
||||
class MigrateFieldOptionTranslationTest extends MigrateDrupal6TestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'config_translation',
|
||||
'language',
|
||||
'locale',
|
||||
'menu_ui',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->executeMigrations([
|
||||
'language',
|
||||
'd6_field',
|
||||
'd6_field_option_translation',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Drupal 6 field to Drupal 8 migration.
|
||||
*/
|
||||
public function testFieldOptionTranslation() {
|
||||
$language_manager = $this->container->get('language_manager');
|
||||
|
||||
// Test a select list with allowed values of key only.
|
||||
/** @var \Drupal\language\Config\LanguageConfigOverride $config_translation */
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.storage.node.field_test_integer_selectlist');
|
||||
$allowed_values = [
|
||||
1 => [
|
||||
'label' => 'fr - 2341',
|
||||
],
|
||||
3 => [
|
||||
'label' => 'fr - 4123',
|
||||
],
|
||||
];
|
||||
$this->assertSame($allowed_values, $config_translation->get('settings.allowed_values'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('zu', 'field.storage.node.field_test_integer_selectlist');
|
||||
$allowed_values = [
|
||||
1 => [
|
||||
'label' => 'zu - 2341',
|
||||
],
|
||||
];
|
||||
$this->assertSame($allowed_values, $config_translation->get('settings.allowed_values'));
|
||||
|
||||
// Test a select list with allowed values of key|label.
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.storage.node.field_test_string_selectlist');
|
||||
$allowed_values = [
|
||||
0 => [
|
||||
'label' => 'Noir',
|
||||
],
|
||||
];
|
||||
$this->assertSame($allowed_values, $config_translation->get('settings.allowed_values'));
|
||||
|
||||
$config_translation = $language_manager->getLanguageConfigOverride('zu', 'field.storage.node.field_test_string_selectlist');
|
||||
$allowed_values = [
|
||||
0 => [
|
||||
'label' => 'Okumnyama',
|
||||
],
|
||||
1 => [
|
||||
'label' => 'Mhlophe',
|
||||
],
|
||||
];
|
||||
$this->assertSame($allowed_values, $config_translation->get('settings.allowed_values'));
|
||||
}
|
||||
|
||||
}
|
|
@ -107,6 +107,16 @@ class MigrateFieldWidgetSettingsTest extends MigrateDrupal6TestBase {
|
|||
$this->assertInternalType('array', $component);
|
||||
$this->assertSame('options_select', $component['type']);
|
||||
|
||||
$component = entity_get_form_display('node', 'employee', 'default')
|
||||
->getComponent('field_company_2');
|
||||
$this->assertInternalType('array', $component);
|
||||
$this->assertSame('options_buttons', $component['type']);
|
||||
|
||||
$component = entity_get_form_display('node', 'employee', 'default')
|
||||
->getComponent('field_company_3');
|
||||
$this->assertInternalType('array', $component);
|
||||
$this->assertSame('entity_reference_autocomplete_tags', $component['type']);
|
||||
|
||||
$component = entity_get_form_display('node', 'employee', 'default')
|
||||
->getComponent('field_commander');
|
||||
$this->assertInternalType('array', $component);
|
||||
|
|
|
@ -56,7 +56,7 @@ class MigrateFieldFormatterSettingsTest extends MigrateDrupal7TestBase {
|
|||
'label' => $this->randomMachineName(),
|
||||
])->save();
|
||||
CommentType::create([
|
||||
'id' => 'comment_node_forum',
|
||||
'id' => 'comment_forum',
|
||||
'label' => $this->randomMachineName(),
|
||||
])->save();
|
||||
CommentType::create([
|
||||
|
@ -97,7 +97,7 @@ class MigrateFieldFormatterSettingsTest extends MigrateDrupal7TestBase {
|
|||
Database::getConnection('default', 'migrate')
|
||||
->update('field_config_instance')
|
||||
->fields([
|
||||
'data' => serialize( [
|
||||
'data' => serialize([
|
||||
'label' => 'Body',
|
||||
'widget' =>
|
||||
[
|
||||
|
@ -122,9 +122,7 @@ class MigrateFieldFormatterSettingsTest extends MigrateDrupal7TestBase {
|
|||
[
|
||||
'label' => 'hidden',
|
||||
'type' => 'text_default',
|
||||
'settings' =>
|
||||
[
|
||||
],
|
||||
'settings' => [],
|
||||
'module' => 'text',
|
||||
'weight' => 0,
|
||||
],
|
||||
|
@ -215,8 +213,8 @@ class MigrateFieldFormatterSettingsTest extends MigrateDrupal7TestBase {
|
|||
$this->assertEntity('comment.comment_node_book.default');
|
||||
$this->assertComponent('comment.comment_node_book.default', 'comment_body', 'text_default', 'hidden', 0);
|
||||
|
||||
$this->assertEntity('comment.comment_node_forum.default');
|
||||
$this->assertComponent('comment.comment_node_forum.default', 'comment_body', 'text_default', 'hidden', 0);
|
||||
$this->assertEntity('comment.comment_forum.default');
|
||||
$this->assertComponent('comment.comment_forum.default', 'comment_body', 'text_default', 'hidden', 0);
|
||||
|
||||
$this->assertEntity('comment.comment_node_page.default');
|
||||
$this->assertComponent('comment.comment_node_page.default', 'comment_body', 'text_default', 'hidden', 0);
|
||||
|
@ -229,6 +227,11 @@ class MigrateFieldFormatterSettingsTest extends MigrateDrupal7TestBase {
|
|||
$this->assertComponent('node.article.default', 'body', 'text_default', 'hidden', 0);
|
||||
$this->assertComponent('node.article.default', 'field_tags', 'entity_reference_label', 'above', 10);
|
||||
$this->assertComponent('node.article.default', 'field_image', 'image', 'hidden', -1);
|
||||
$this->assertComponent('node.article.default', 'field_text_plain', 'string', 'above', 11);
|
||||
$this->assertComponent('node.article.default', 'field_text_filtered', 'text_default', 'above', 12);
|
||||
$this->assertComponent('node.article.default', 'field_text_long_plain', 'basic_string', 'above', 14);
|
||||
$this->assertComponent('node.article.default', 'field_text_long_filtered', 'text_default', 'above', 15);
|
||||
$this->assertComponent('node.article.default', 'field_text_sum_filtered', 'text_default', 'above', 18);
|
||||
|
||||
$this->assertEntity('node.article.teaser');
|
||||
$this->assertComponent('node.article.teaser', 'body', 'text_summary_or_trimmed', 'hidden', 0);
|
||||
|
@ -257,6 +260,11 @@ class MigrateFieldFormatterSettingsTest extends MigrateDrupal7TestBase {
|
|||
|
||||
$this->assertEntity('node.page.default');
|
||||
$this->assertComponent('node.page.default', 'body', 'text_default', 'hidden', 0);
|
||||
$this->assertComponent('node.page.default', 'field_text_plain', 'string', 'above', 1);
|
||||
$this->assertComponent('node.page.default', 'field_text_filtered', 'text_default', 'above', 2);
|
||||
$this->assertComponent('node.page.default', 'field_text_long_plain', 'basic_string', 'above', 4);
|
||||
$this->assertComponent('node.page.default', 'field_text_long_filtered', 'text_default', 'above', 5);
|
||||
$this->assertComponent('node.page.default', 'field_text_sum_filtered', 'text_default', 'above', 8);
|
||||
|
||||
$this->assertEntity('node.page.teaser');
|
||||
$this->assertComponent('node.page.teaser', 'body', 'text_summary_or_trimmed', 'hidden', 0);
|
||||
|
@ -275,6 +283,7 @@ class MigrateFieldFormatterSettingsTest extends MigrateDrupal7TestBase {
|
|||
$this->assertComponent('node.test_content_type.default', 'field_link', 'link', 'above', 9);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_text_list', 'list_default', 'above', 10);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_integer_list', 'list_default', 'above', 11);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_float_list', 'list_default', 'above', 19);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_long_text', 'text_default', 'above', 12);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_node_entityreference', 'entity_reference_label', 'above', 15);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_user_entityreference', 'entity_reference_label', 'above', 16);
|
||||
|
|
|
@ -2,12 +2,11 @@
|
|||
|
||||
namespace Drupal\Tests\field\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\comment\Entity\CommentType;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\FieldConfigInterface;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
use Drupal\Tests\migrate\Kernel\NodeCommentCombinationTrait;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
|
||||
/**
|
||||
* Migrates Drupal 7 field instances.
|
||||
|
@ -16,10 +15,10 @@ use Drupal\node\Entity\NodeType;
|
|||
*/
|
||||
class MigrateFieldInstanceTest extends MigrateDrupal7TestBase {
|
||||
|
||||
use NodeCommentCombinationTrait;
|
||||
|
||||
/**
|
||||
* The modules to be enabled during the test.
|
||||
*
|
||||
* @var array
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'comment',
|
||||
|
@ -40,35 +39,16 @@ class MigrateFieldInstanceTest extends MigrateDrupal7TestBase {
|
|||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installConfig(static::$modules);
|
||||
$this->createType('page');
|
||||
$this->createType('article');
|
||||
$this->createType('blog');
|
||||
$this->createType('book');
|
||||
$this->createType('forum');
|
||||
$this->createType('test_content_type');
|
||||
$this->createNodeCommentCombination('page');
|
||||
$this->createNodeCommentCombination('article');
|
||||
$this->createNodeCommentCombination('blog');
|
||||
$this->createNodeCommentCombination('book');
|
||||
$this->createNodeCommentCombination('forum', 'comment_forum');
|
||||
$this->createNodeCommentCombination('test_content_type');
|
||||
Vocabulary::create(['vid' => 'test_vocabulary'])->save();
|
||||
$this->executeMigrations(['d7_field', 'd7_field_instance']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a node type with a corresponding comment type.
|
||||
*
|
||||
* @param string $id
|
||||
* The node type ID.
|
||||
*/
|
||||
protected function createType($id) {
|
||||
NodeType::create([
|
||||
'type' => $id,
|
||||
'label' => $this->randomString(),
|
||||
])->save();
|
||||
|
||||
CommentType::create([
|
||||
'id' => 'comment_node_' . $id,
|
||||
'label' => $this->randomString(),
|
||||
'target_entity_type_id' => 'node',
|
||||
])->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts various aspects of a field config entity.
|
||||
*
|
||||
|
@ -88,15 +68,15 @@ class MigrateFieldInstanceTest extends MigrateDrupal7TestBase {
|
|||
|
||||
/** @var \Drupal\field\FieldConfigInterface $field */
|
||||
$field = FieldConfig::load($id);
|
||||
$this->assertTrue($field instanceof FieldConfigInterface);
|
||||
$this->assertIdentical($expected_label, $field->label());
|
||||
$this->assertIdentical($expected_field_type, $field->getType());
|
||||
$this->assertIdentical($expected_entity_type, $field->getTargetEntityTypeId());
|
||||
$this->assertIdentical($expected_bundle, $field->getTargetBundle());
|
||||
$this->assertIdentical($expected_name, $field->getName());
|
||||
$this->assertEqual($is_required, $field->isRequired());
|
||||
$this->assertIdentical($expected_entity_type . '.' . $expected_name, $field->getFieldStorageDefinition()->id());
|
||||
$this->assertSame($expected_translatable, $field->isTranslatable());
|
||||
$this->assertInstanceOf(FieldConfigInterface::class, $field);
|
||||
$this->assertEquals($expected_label, $field->label());
|
||||
$this->assertEquals($expected_field_type, $field->getType());
|
||||
$this->assertEquals($expected_entity_type, $field->getTargetEntityTypeId());
|
||||
$this->assertEquals($expected_bundle, $field->getTargetBundle());
|
||||
$this->assertEquals($expected_name, $field->getName());
|
||||
$this->assertEquals($is_required, $field->isRequired());
|
||||
$this->assertEquals($expected_entity_type . '.' . $expected_name, $field->getFieldStorageDefinition()->id());
|
||||
$this->assertEquals($expected_translatable, $field->isTranslatable());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -127,31 +107,100 @@ class MigrateFieldInstanceTest extends MigrateDrupal7TestBase {
|
|||
$this->assertEntity('comment.comment_node_book.comment_body', 'Comment', 'text_long', TRUE, FALSE);
|
||||
$this->assertEntity('node.book.body', 'Body', 'text_with_summary', FALSE, FALSE);
|
||||
$this->assertEntity('node.forum.taxonomy_forums', 'Forums', 'entity_reference', TRUE, FALSE);
|
||||
$this->assertEntity('comment.comment_node_forum.comment_body', 'Comment', 'text_long', TRUE, FALSE);
|
||||
$this->assertEntity('comment.comment_forum.comment_body', 'Comment', 'text_long', TRUE, FALSE);
|
||||
$this->assertEntity('node.forum.body', 'Body', 'text_with_summary', FALSE, FALSE);
|
||||
$this->assertEntity('comment.comment_node_test_content_type.comment_body', 'Comment', 'text_long', TRUE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_boolean', 'Boolean', 'boolean', FALSE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_email', 'Email', 'email', FALSE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_phone', 'Phone', 'telephone', TRUE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_date', 'Date', 'datetime', FALSE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_date_with_end_time', 'Date With End Time', 'datetime', FALSE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_date_with_end_time', 'Date With End Time', 'timestamp', FALSE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_file', 'File', 'file', FALSE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_float', 'Float', 'float', FALSE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_images', 'Images', 'image', TRUE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_integer', 'Integer', 'integer', TRUE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_integer', 'Integer', 'integer', TRUE, TRUE);
|
||||
$this->assertEntity('node.test_content_type.field_link', 'Link', 'link', FALSE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_text_list', 'Text List', 'list_string', FALSE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_integer_list', 'Integer List', 'list_integer', FALSE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_float_list', 'Float List', 'list_float', FALSE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_long_text', 'Long text', 'text_with_summary', FALSE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_term_reference', 'Term Reference', 'entity_reference', FALSE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_text', 'Text', 'text', FALSE, FALSE);
|
||||
$this->assertEntity('comment.comment_node_test_content_type.field_integer', 'Integer', 'integer', FALSE, FALSE);
|
||||
$this->assertEntity('node.test_content_type.field_text', 'Text', 'string', FALSE, FALSE);
|
||||
$this->assertEntity('comment.comment_node_test_content_type.field_integer', 'Integer', 'integer', FALSE, TRUE);
|
||||
$this->assertEntity('user.user.field_file', 'File', 'file', FALSE, FALSE);
|
||||
|
||||
|
||||
$this->assertLinkFields('node.test_content_type.field_link', DRUPAL_OPTIONAL);
|
||||
$this->assertLinkFields('node.article.field_link', DRUPAL_DISABLED);
|
||||
$this->assertLinkFields('node.blog.field_link', DRUPAL_REQUIRED);
|
||||
|
||||
// Tests that fields created by the Title module are not migrated.
|
||||
$title_field = FieldConfig::load('node.test_content_type.title_field');
|
||||
$this->assertNull($title_field);
|
||||
$subject_field = FieldConfig::load('comment.comment_node_article.subject_field');
|
||||
$this->assertNull($subject_field);
|
||||
$name_field = FieldConfig::load('taxonomy_term.test_vocabulary.name_field');
|
||||
$this->assertNull($name_field);
|
||||
$description_field = FieldConfig::load('taxonomy_term.test_vocabulary.description_field');
|
||||
$this->assertNull($description_field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the migration of text field instances with different text processing.
|
||||
*/
|
||||
public function testTextFieldInstances() {
|
||||
// All text and text_long field instances using a field base that has only
|
||||
// plain text instances should be migrated to string and string_long fields.
|
||||
// All text_with_summary field instances using a field base that has only
|
||||
// plain text instances should not have been migrated since there's no such
|
||||
// thing as a string_with_summary field.
|
||||
$this->assertEntity('node.page.field_text_plain', 'Text plain', 'string', FALSE, FALSE);
|
||||
$this->assertEntity('node.article.field_text_plain', 'Text plain', 'string', FALSE, TRUE);
|
||||
$this->assertEntity('node.page.field_text_long_plain', 'Text long plain', 'string_long', FALSE, FALSE);
|
||||
$this->assertEntity('node.article.field_text_long_plain', 'Text long plain', 'string_long', FALSE, TRUE);
|
||||
$this->assertNull(FieldConfig::load('node.page.field_text_sum_plain'));
|
||||
$this->assertNull(FieldConfig::load('node.article.field_text_sum_plain'));
|
||||
|
||||
// All text, text_long and text_with_summary field instances using a field
|
||||
// base that has only filtered text instances should be migrated to text,
|
||||
// text_long and text_with_summary fields.
|
||||
$this->assertEntity('node.page.field_text_filtered', 'Text filtered', 'text', FALSE, FALSE);
|
||||
$this->assertEntity('node.article.field_text_filtered', 'Text filtered', 'text', FALSE, TRUE);
|
||||
$this->assertEntity('node.page.field_text_long_filtered', 'Text long filtered', 'text_long', FALSE, FALSE);
|
||||
$this->assertEntity('node.article.field_text_long_filtered', 'Text long filtered', 'text_long', FALSE, TRUE);
|
||||
$this->assertEntity('node.page.field_text_sum_filtered', 'Text summary filtered', 'text_with_summary', FALSE, FALSE);
|
||||
$this->assertEntity('node.article.field_text_sum_filtered', 'Text summary filtered', 'text_with_summary', FALSE, TRUE);
|
||||
|
||||
// All text, text_long and text_with_summary field instances using a field
|
||||
// base that has both plain text and filtered text instances should not have
|
||||
// been migrated.
|
||||
$this->assertNull(FieldConfig::load('node.page.field_text_plain_filtered'));
|
||||
$this->assertNull(FieldConfig::load('node.article.field_text_plain_filtered'));
|
||||
$this->assertNull(FieldConfig::load('node.page.field_text_long_plain_filtered'));
|
||||
$this->assertNull(FieldConfig::load('node.article.field_text_long_plain_filtered'));
|
||||
$this->assertNull(FieldConfig::load('node.page.field_text_sum_plain_filtered'));
|
||||
$this->assertNull(FieldConfig::load('node.article.field_text_sum_plain_filtered'));
|
||||
|
||||
// For each text field instances that were skipped, there should be a log
|
||||
// message with the required steps to fix this.
|
||||
$migration = $this->getMigration('d7_field_instance');
|
||||
$messages = $migration->getIdMap()->getMessageIterator()->fetchAll();
|
||||
$errors = array_map(function ($message) {
|
||||
return $message->message;
|
||||
}, $messages);
|
||||
$this->assertCount(8, $errors);
|
||||
sort($errors);
|
||||
$message = 'Can\'t migrate source field field_text_long_plain_filtered configured with both plain text and filtered text processing. See https://www.drupal.org/docs/8/upgrade/known-issues-when-upgrading-from-drupal-6-or-7-to-drupal-8#plain-text';
|
||||
$this->assertEquals($errors[0], $message);
|
||||
$this->assertEquals($errors[1], $message);
|
||||
$message = 'Can\'t migrate source field field_text_plain_filtered configured with both plain text and filtered text processing. See https://www.drupal.org/docs/8/upgrade/known-issues-when-upgrading-from-drupal-6-or-7-to-drupal-8#plain-text';
|
||||
$this->assertEquals($errors[2], $message);
|
||||
$this->assertEquals($errors[3], $message);
|
||||
$message = 'Can\'t migrate source field field_text_sum_plain of type text_with_summary configured with plain text processing. See https://www.drupal.org/docs/8/upgrade/known-issues-when-upgrading-from-drupal-6-or-7-to-drupal-8#plain-text';
|
||||
$this->assertEquals($errors[4], $message);
|
||||
$this->assertEquals($errors[5], $message);
|
||||
$message = 'Can\'t migrate source field field_text_sum_plain_filtered of type text_with_summary configured with plain text processing. See https://www.drupal.org/docs/8/upgrade/known-issues-when-upgrading-from-drupal-6-or-7-to-drupal-8#plain-text';
|
||||
$this->assertEquals($errors[6], $message);
|
||||
$this->assertEquals($errors[7], $message);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -96,11 +96,21 @@ class MigrateFieldInstanceWidgetSettingsTest extends MigrateDrupal7TestBase {
|
|||
public function testWidgetSettings() {
|
||||
$this->assertEntity('node.page.default', 'node', 'page');
|
||||
$this->assertComponent('node.page.default', 'body', 'text_textarea_with_summary', -4);
|
||||
$this->assertComponent('node.page.default', 'field_text_plain', 'string_textfield', -2);
|
||||
$this->assertComponent('node.page.default', 'field_text_filtered', 'text_textfield', 0);
|
||||
$this->assertComponent('node.page.default', 'field_text_long_plain', 'string_textarea', 4);
|
||||
$this->assertComponent('node.page.default', 'field_text_long_filtered', 'text_textarea', 6);
|
||||
$this->assertComponent('node.page.default', 'field_text_sum_filtered', 'text_textarea_with_summary', 12);
|
||||
|
||||
$this->assertEntity('node.article.default', 'node', 'article');
|
||||
$this->assertComponent('node.article.default', 'body', 'text_textarea_with_summary', -4);
|
||||
$this->assertComponent('node.article.default', 'field_tags', 'entity_reference_autocomplete', -4);
|
||||
$this->assertComponent('node.article.default', 'field_image', 'image_image', -1);
|
||||
$this->assertComponent('node.article.default', 'field_text_plain', 'string_textfield', 11);
|
||||
$this->assertComponent('node.article.default', 'field_text_filtered', 'text_textfield', 12);
|
||||
$this->assertComponent('node.article.default', 'field_text_long_plain', 'string_textarea', 14);
|
||||
$this->assertComponent('node.article.default', 'field_text_long_filtered', 'text_textarea', 15);
|
||||
$this->assertComponent('node.article.default', 'field_text_sum_filtered', 'text_textarea_with_summary', 18);
|
||||
|
||||
$this->assertEntity('node.blog.default', 'node', 'blog');
|
||||
$this->assertComponent('node.blog.default', 'body', 'text_textarea_with_summary', -4);
|
||||
|
@ -129,8 +139,9 @@ class MigrateFieldInstanceWidgetSettingsTest extends MigrateDrupal7TestBase {
|
|||
$this->assertComponent('node.test_content_type.default', 'field_node_entityreference', 'entity_reference_autocomplete', 16);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_user_entityreference', 'options_buttons', 17);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_term_entityreference', 'entity_reference_autocomplete_tags', 18);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_text', 'text_textfield', 15);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_text', 'string_textfield', 15);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_text_list', 'options_select', 11);
|
||||
$this->assertComponent('node.test_content_type.default', 'field_float_list', 'options_select', 20);
|
||||
|
||||
$this->assertEntity('user.user.default', 'user', 'user');
|
||||
$this->assertComponent('user.user.default', 'field_file', 'file_generic', 8);
|
||||
|
|
|
@ -57,11 +57,11 @@ class MigrateFieldTest extends MigrateDrupal7TestBase {
|
|||
|
||||
/** @var \Drupal\field\FieldStorageConfigInterface $field */
|
||||
$field = FieldStorageConfig::load($id);
|
||||
$this->assertTrue($field instanceof FieldStorageConfigInterface);
|
||||
$this->assertIdentical($expected_name, $field->getName());
|
||||
$this->assertIdentical($expected_type, $field->getType());
|
||||
$this->assertEqual($expected_translatable, $field->isTranslatable());
|
||||
$this->assertIdentical($expected_entity_type, $field->getTargetEntityTypeId());
|
||||
$this->assertInstanceOf(FieldStorageConfigInterface::class, $field);
|
||||
$this->assertEquals($expected_name, $field->getName());
|
||||
$this->assertEquals($expected_type, $field->getType());
|
||||
$this->assertEquals($expected_translatable, $field->isTranslatable());
|
||||
$this->assertEquals($expected_entity_type, $field->getTargetEntityTypeId());
|
||||
|
||||
if ($expected_cardinality === 1) {
|
||||
$this->assertFalse($field->isMultiple());
|
||||
|
@ -69,7 +69,7 @@ class MigrateFieldTest extends MigrateDrupal7TestBase {
|
|||
else {
|
||||
$this->assertTrue($field->isMultiple());
|
||||
}
|
||||
$this->assertIdentical($expected_cardinality, $field->getCardinality());
|
||||
$this->assertEquals($expected_cardinality, $field->getCardinality());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,38 +91,98 @@ class MigrateFieldTest extends MigrateDrupal7TestBase {
|
|||
$this->assertEntity('node.field_tags', 'entity_reference', TRUE, -1);
|
||||
$this->assertEntity('node.field_term_reference', 'entity_reference', TRUE, 1);
|
||||
$this->assertEntity('node.taxonomy_forums', 'entity_reference', TRUE, 1);
|
||||
$this->assertEntity('node.field_text', 'text', TRUE, 1);
|
||||
$this->assertEntity('node.field_text', 'string', TRUE, 1);
|
||||
$this->assertEntity('node.field_text_list', 'list_string', TRUE, 3);
|
||||
$this->assertEntity('node.field_float_list', 'list_float', TRUE, 1);
|
||||
$this->assertEntity('node.field_boolean', 'boolean', TRUE, 1);
|
||||
$this->assertEntity('node.field_email', 'email', TRUE, -1);
|
||||
$this->assertEntity('node.field_phone', 'telephone', TRUE, 1);
|
||||
$this->assertEntity('node.field_date', 'datetime', TRUE, 1);
|
||||
$this->assertEntity('node.field_date_with_end_time', 'datetime', TRUE, 1);
|
||||
$this->assertEntity('node.field_date_with_end_time', 'timestamp', TRUE, 1);
|
||||
$this->assertEntity('node.field_node_entityreference', 'entity_reference', TRUE, -1);
|
||||
$this->assertEntity('node.field_user_entityreference', 'entity_reference', TRUE, 1);
|
||||
$this->assertEntity('node.field_term_entityreference', 'entity_reference', TRUE, -1);
|
||||
$this->assertEntity('node.field_date_without_time', 'datetime', TRUE, 1);
|
||||
$this->assertEntity('node.field_datetime_without_time', 'datetime', TRUE, 1);
|
||||
|
||||
// Tests that fields created by the Title module are not migrated.
|
||||
$title_field = FieldStorageConfig::load('node.title_field');
|
||||
$this->assertNull($title_field);
|
||||
$subject_field = FieldStorageConfig::load('comment.subject_field');
|
||||
$this->assertNull($subject_field);
|
||||
$name_field = FieldStorageConfig::load('taxonomy_term.name_field');
|
||||
$this->assertNull($name_field);
|
||||
$description_field = FieldStorageConfig::load('taxonomy_term.description_field');
|
||||
$this->assertNull($description_field);
|
||||
|
||||
// Assert that the taxonomy term reference fields are referencing the
|
||||
// correct entity type.
|
||||
$field = FieldStorageConfig::load('node.field_term_reference');
|
||||
$this->assertIdentical('taxonomy_term', $field->getSetting('target_type'));
|
||||
$this->assertEquals('taxonomy_term', $field->getSetting('target_type'));
|
||||
$field = FieldStorageConfig::load('node.taxonomy_forums');
|
||||
$this->assertIdentical('taxonomy_term', $field->getSetting('target_type'));
|
||||
$this->assertEquals('taxonomy_term', $field->getSetting('target_type'));
|
||||
|
||||
// Assert that the entityreference fields are referencing the correct
|
||||
// entity type.
|
||||
$field = FieldStorageConfig::load('node.field_node_entityreference');
|
||||
$this->assertIdentical('node', $field->getSetting('target_type'));
|
||||
$this->assertEquals('node', $field->getSetting('target_type'));
|
||||
$field = FieldStorageConfig::load('node.field_user_entityreference');
|
||||
$this->assertIdentical('user', $field->getSetting('target_type'));
|
||||
$this->assertEquals('user', $field->getSetting('target_type'));
|
||||
$field = FieldStorageConfig::load('node.field_term_entityreference');
|
||||
$this->assertIdentical('taxonomy_term', $field->getSetting('target_type'));
|
||||
$this->assertEquals('taxonomy_term', $field->getSetting('target_type'));
|
||||
|
||||
// Validate that the source count and processed count match up.
|
||||
/** @var \Drupal\migrate\Plugin\MigrationInterface $migration */
|
||||
// Make sure that datetime fields get the right datetime_type setting
|
||||
$field = FieldStorageConfig::load('node.field_date');
|
||||
$this->assertEquals('datetime', $field->getSetting('datetime_type'));
|
||||
$field = FieldStorageConfig::load('node.field_date_without_time');
|
||||
$this->assertEquals('date', $field->getSetting('datetime_type'));
|
||||
$field = FieldStorageConfig::load('node.field_datetime_without_time');
|
||||
$this->assertEquals('date', $field->getSetting('datetime_type'));
|
||||
// Except for field_date_with_end_time which is a timestamp and so does not
|
||||
// have a datetime_type setting.
|
||||
$field = FieldStorageConfig::load('node.field_date_with_end_time');
|
||||
$this->assertNull($field->getSetting('datetime_type'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the migration of text fields with different text processing.
|
||||
*/
|
||||
public function testTextFields() {
|
||||
// All text and text_long field bases that have only plain text instances
|
||||
// should be migrated to string and string_long fields.
|
||||
// All text_with_summary field bases that have only plain text instances
|
||||
// should not have been migrated since there's no such thing as a
|
||||
// string_with_summary field.
|
||||
$this->assertEntity('node.field_text_plain', 'string', TRUE, 1);
|
||||
$this->assertEntity('node.field_text_long_plain', 'string_long', TRUE, 1);
|
||||
$this->assertNull(FieldStorageConfig::load('node.field_text_sum_plain'));
|
||||
|
||||
// All text, text_long and text_with_summary field bases that have only
|
||||
// filtered text instances should be migrated to text, text_long and
|
||||
// text_with_summary fields.
|
||||
$this->assertEntity('node.field_text_filtered', 'text', TRUE, 1);
|
||||
$this->assertEntity('node.field_text_long_filtered', 'text_long', TRUE, 1);
|
||||
$this->assertEntity('node.field_text_sum_filtered', 'text_with_summary', TRUE, 1);
|
||||
|
||||
// All text, text_long and text_with_summary field bases that have both
|
||||
// plain text and filtered text instances should not have been migrated.
|
||||
$this->assertNull(FieldStorageConfig::load('node.field_text_plain_filtered'));
|
||||
$this->assertNull(FieldStorageConfig::load('node.field_text_long_plain_filtered'));
|
||||
$this->assertNull(FieldStorageConfig::load('node.field_text_sum_plain_filtered'));
|
||||
|
||||
// For each text field bases that were skipped, there should be a log
|
||||
// message with the required steps to fix this.
|
||||
$migration = $this->getMigration('d7_field');
|
||||
$this->assertSame($migration->getSourcePlugin()
|
||||
->count(), $migration->getIdMap()->processedCount());
|
||||
$messages = $migration->getIdMap()->getMessageIterator()->fetchAll();
|
||||
$errors = array_map(function ($message) {
|
||||
return $message->message;
|
||||
}, $messages);
|
||||
sort($errors);
|
||||
$this->assertCount(4, $errors);
|
||||
$this->assertEquals($errors[0], 'Can\'t migrate source field field_text_long_plain_filtered configured with both plain text and filtered text processing. See https://www.drupal.org/docs/8/upgrade/known-issues-when-upgrading-from-drupal-6-or-7-to-drupal-8#plain-text');
|
||||
$this->assertEquals($errors[1], 'Can\'t migrate source field field_text_plain_filtered configured with both plain text and filtered text processing. See https://www.drupal.org/docs/8/upgrade/known-issues-when-upgrading-from-drupal-6-or-7-to-drupal-8#plain-text');
|
||||
$this->assertEquals($errors[2], 'Can\'t migrate source field field_text_sum_plain of type text_with_summary configured with plain text processing. See https://www.drupal.org/docs/8/upgrade/known-issues-when-upgrading-from-drupal-6-or-7-to-drupal-8#plain-text');
|
||||
$this->assertEquals($errors[3], 'Can\'t migrate source field field_text_sum_plain_filtered of type text_with_summary configured with plain text processing. See https://www.drupal.org/docs/8/upgrade/known-issues-when-upgrading-from-drupal-6-or-7-to-drupal-8#plain-text');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,8 +34,6 @@ class MigrateViewModesTest extends MigrateDrupal7TestBase {
|
|||
* The expected label of the view mode.
|
||||
* @param string $entity_type
|
||||
* The expected entity type ID which owns the view mode.
|
||||
* @param bool $status
|
||||
* The expected status of the view mode.
|
||||
*/
|
||||
protected function assertEntity($id, $label, $entity_type) {
|
||||
/** @var \Drupal\Core\Entity\EntityViewModeInterface $view_mode */
|
||||
|
|
|
@ -35,7 +35,7 @@ class RollbackFieldInstanceTest extends MigrateFieldInstanceTest {
|
|||
'comment.comment_node_book.comment_body',
|
||||
'node.book.body',
|
||||
'node.forum.taxonomy_forums',
|
||||
'comment.comment_node_forum.comment_body',
|
||||
'comment.comment_forum.comment_body',
|
||||
'node.forum.body',
|
||||
'comment.comment_node_test_content_type.comment_body',
|
||||
'node.test_content_type.field_boolean',
|
||||
|
|
|
@ -93,7 +93,7 @@ class NumberItemTest extends FieldKernelTestBase {
|
|||
$this->assertEqual($entity->field_float->value, $new_float);
|
||||
$this->assertEqual($entity->field_decimal->value, $new_decimal);
|
||||
|
||||
/// Test sample item generation.
|
||||
// Test sample item generation.
|
||||
$entity = EntityTest::create();
|
||||
$entity->field_integer->generateSampleItems();
|
||||
$entity->field_float->generateSampleItems();
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\field\Kernel\Plugin\migrate\source\d6;
|
||||
|
||||
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
|
||||
|
||||
/**
|
||||
* Tests the field label and description translation source plugin.
|
||||
*
|
||||
* @covers \Drupal\field\Plugin\migrate\source\d6\FieldLabelDescriptionTranslation
|
||||
* @group migrate_drupal
|
||||
*/
|
||||
class FieldInstanceLabelDescriptionTranslationTest extends MigrateSqlSourceTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['config_translation', 'migrate_drupal', 'field'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerSource() {
|
||||
$test = [];
|
||||
|
||||
// The source data.
|
||||
$test[0]['source_data'] = [
|
||||
'i18n_strings' => [
|
||||
[
|
||||
'lid' => 10,
|
||||
'objectid' => 'story-field_test_two',
|
||||
'type' => 'field',
|
||||
'property' => 'widget_label',
|
||||
],
|
||||
[
|
||||
'lid' => 11,
|
||||
'objectid' => 'story-field_test_two',
|
||||
'type' => 'field',
|
||||
'property' => 'widget_description',
|
||||
],
|
||||
[
|
||||
'lid' => 12,
|
||||
'objectid' => 'story-field_test_two',
|
||||
'type' => 'field',
|
||||
'property' => 'widget_description',
|
||||
],
|
||||
],
|
||||
'locales_target' => [
|
||||
[
|
||||
'lid' => 10,
|
||||
'translation' => "fr - Integer Field",
|
||||
'language' => 'fr',
|
||||
],
|
||||
[
|
||||
'lid' => 11,
|
||||
'translation' => 'fr - An example integer field.',
|
||||
'language' => 'fr',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$test[0]['expected_results'] = [
|
||||
[
|
||||
'property' => 'widget_label',
|
||||
'translation' => "fr - Integer Field",
|
||||
'language' => 'fr',
|
||||
'lid' => '10',
|
||||
],
|
||||
[
|
||||
'property' => 'widget_description',
|
||||
'translation' => 'fr - An example integer field.',
|
||||
'language' => 'fr',
|
||||
'lid' => '11',
|
||||
],
|
||||
];
|
||||
return $test;
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue