FormTest.php 28.9 KB
Newer Older
1
2
3
4
<?php

/**
 * @file
5
 * Contains \Drupal\field\Tests\FormTest.
6
7
8
9
 */

namespace Drupal\field\Tests;

10
use Drupal\Component\Utility\Html;
11
use Drupal\Core\Entity\Entity\EntityFormDisplay;
12
use Drupal\Core\Field\FieldStorageDefinitionInterface;
13
use Drupal\Core\Form\FormState;
14
use Drupal\entity_test\Entity\EntityTestBaseFieldDisplay;
15
16
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
17

18
19
/**
 * Tests field form handling.
20
21
 *
 * @group field
22
 */
23
class FormTest extends FieldTestBase {
24
25
26
27

  /**
   * Modules to enable.
   *
28
29
   * Locale is installed so that TranslatableMarkup actually does something.
   *
30
31
   * @var array
   */
32
  public static $modules = array('node', 'field_test', 'options', 'entity_test', 'locale');
33

34
35
36
37
38
  /**
   * An array of values defining a field single.
   *
   * @var array
   */
39
  protected $fieldStorageSingle;
40
41
42
43
44
45

  /**
   * An array of values defining a field multiple.
   *
   * @var array
   */
46
  protected $fieldStorageMultiple;
47
48
49
50
51
52

  /**
   * An array of values defining a field with unlimited cardinality.
   *
   * @var array
   */
53
  protected $fieldStorageUnlimited;
54
55

  /**
56
   * An array of values defining a field.
57
58
59
   *
   * @var array
   */
60
  protected $field;
61

62
  protected function setUp() {
63
    parent::setUp();
64

65
    $web_user = $this->drupalCreateUser(array('view test entity', 'administer entity_test content'));
66
67
    $this->drupalLogin($web_user);

68
    $this->fieldStorageSingle = array(
69
      'field_name' => 'field_single',
70
71
72
      'entity_type' => 'entity_test',
      'type' => 'test_field',
    );
73
    $this->fieldStorageMultiple = array(
74
      'field_name' => 'field_multiple',
75
76
77
78
      'entity_type' => 'entity_test',
      'type' => 'test_field',
      'cardinality' => 4,
    );
79
    $this->fieldStorageUnlimited = array(
80
      'field_name' => 'field_unlimited',
81
82
      'entity_type' => 'entity_test',
      'type' => 'test_field',
83
      'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
84
    );
85

86
    $this->field = array(
87
88
      'entity_type' => 'entity_test',
      'bundle' => 'entity_test',
89
      'label' => $this->randomMachineName() . '_label',
90
      'description' => '[site:name]_description',
91
92
      'weight' => mt_rand(0, 127),
      'settings' => array(
93
        'test_field_setting' => $this->randomMachineName(),
94
95
96
97
98
      ),
    );
  }

  function testFieldFormSingle() {
99
    $field_storage = $this->fieldStorageSingle;
100
    $field_name = $field_storage['field_name'];
101
    $this->field['field_name'] = $field_name;
102
    entity_create('field_storage_config', $field_storage)->save();
103
104
    entity_create('field_config', $this->field)->save();
    entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
105
      ->setComponent($field_name)
106
      ->save();
107
108

    // Display creation form.
109
    $this->drupalGet('entity_test/add');
110
111

    // Create token value expected for description.
112
    $token_description = Html::escape($this->config('system.site')->get('name')) . '_description';
113
    $this->assertText($token_description, 'Token replacement for description is displayed');
114
115
    $this->assertFieldByName("{$field_name}[0][value]", '', 'Widget is displayed');
    $this->assertNoField("{$field_name}[1][value]", 'No extraneous widget is displayed');
116

117
118
    // Check that hook_field_widget_form_alter() does not believe this is the
    // default value form.
119
120
    $this->assertNoText('From hook_field_widget_form_alter(): Default form is true.', 'Not default value form in hook_field_widget_form_alter().');

121
    // Submit with invalid value (field-level validation).
122
    $edit = array(
123
      "{$field_name}[0][value]" => -1
124
    );
125
    $this->drupalPostForm(NULL, $edit, t('Save'));
126
    $this->assertRaw(t('%name does not accept the value -1.', array('%name' => $this->field['label'])), 'Field validation fails with invalid input.');
127
128
129
130
    // TODO : check that the correct field is flagged for error.

    // Create an entity
    $value = mt_rand(1, 127);
131
    $edit = array(
132
      "{$field_name}[0][value]" => $value,
133
    );
134
    $this->drupalPostForm(NULL, $edit, t('Save'));
135
    preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
136
    $id = $match[1];
137
138
139
    $this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created');
    $entity = entity_load('entity_test', $id);
    $this->assertEqual($entity->{$field_name}->value, $value, 'Field value was saved');
140
141

    // Display edit form.
142
    $this->drupalGet('entity_test/manage/' . $id . '/edit');
143
144
    $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');
145
146
147

    // Update the entity.
    $value = mt_rand(1, 127);
148
    $edit = array(
149
      "{$field_name}[0][value]" => $value,
150
    );
151
    $this->drupalPostForm(NULL, $edit, t('Save'));
152
    $this->assertText(t('entity_test @id has been updated.', array('@id' => $id)), 'Entity was updated');
153
    $this->container->get('entity.manager')->getStorage('entity_test')->resetCache(array($id));
154
155
    $entity = entity_load('entity_test', $id);
    $this->assertEqual($entity->{$field_name}->value, $value, 'Field value was updated');
156
157
158

    // Empty the field.
    $value = '';
159
    $edit = array(
160
      "{$field_name}[0][value]" => $value
161
    );
162
    $this->drupalPostForm('entity_test/manage/' . $id . '/edit', $edit, t('Save'));
163
    $this->assertText(t('entity_test @id has been updated.', array('@id' => $id)), 'Entity was updated');
164
    $this->container->get('entity.manager')->getStorage('entity_test')->resetCache(array($id));
165
166
    $entity = entity_load('entity_test', $id);
    $this->assertTrue($entity->{$field_name}->isEmpty(), 'Field was emptied');
167
  }
168

169
170
171
172
  /**
   * Tests field widget default values on entity forms.
   */
  function testFieldFormDefaultValue() {
173
    $field_storage = $this->fieldStorageSingle;
174
    $field_name = $field_storage['field_name'];
175
    $this->field['field_name'] = $field_name;
176
    $default = rand(1, 127);
177
    $this->field['default_value'] = array(array('value' => $default));
178
    entity_create('field_storage_config', $field_storage)->save();
179
180
    entity_create('field_config', $this->field)->save();
    entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
181
      ->setComponent($field_name)
182
      ->save();
183
184

    // Display creation form.
185
    $this->drupalGet('entity_test/add');
186
    // Test that the default value is displayed correctly.
187
    $this->assertFieldByXpath("//input[@name='{$field_name}[0][value]' and @value='$default']");
188
189

    // Try to submit an empty value.
190
    $edit = array(
191
      "{$field_name}[0][value]" => '',
192
    );
193
    $this->drupalPostForm(NULL, $edit, t('Save'));
194
    preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
195
    $id = $match[1];
196
197
198
    $this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created.');
    $entity = entity_load('entity_test', $id);
    $this->assertTrue($entity->{$field_name}->isEmpty(), 'Field is now empty.');
199
200
201
  }

  function testFieldFormSingleRequired() {
202
    $field_storage = $this->fieldStorageSingle;
203
    $field_name = $field_storage['field_name'];
204
205
    $this->field['field_name'] = $field_name;
    $this->field['required'] = TRUE;
206
    entity_create('field_storage_config', $field_storage)->save();
207
208
    entity_create('field_config', $this->field)->save();
    entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
209
      ->setComponent($field_name)
210
      ->save();
211
212
213

    // Submit with missing required value.
    $edit = array();
214
    $this->drupalPostForm('entity_test/add', $edit, t('Save'));
215
    $this->assertRaw(t('@name field is required.', array('@name' => $this->field['label'])), 'Required field with no value fails validation');
216
217
218

    // Create an entity
    $value = mt_rand(1, 127);
219
    $edit = array(
220
      "{$field_name}[0][value]" => $value,
221
    );
222
    $this->drupalPostForm(NULL, $edit, t('Save'));
223
    preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
224
    $id = $match[1];
225
226
227
    $this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created');
    $entity = entity_load('entity_test', $id);
    $this->assertEqual($entity->{$field_name}->value, $value, 'Field value was saved');
228
229
230

    // Edit with missing required value.
    $value = '';
231
    $edit = array(
232
      "{$field_name}[0][value]" => $value,
233
    );
234
    $this->drupalPostForm('entity_test/manage/' . $id . '/edit', $edit, t('Save'));
235
    $this->assertRaw(t('@name field is required.', array('@name' => $this->field['label'])), 'Required field with no value fails validation');
236
237
238
239
  }

//  function testFieldFormMultiple() {
//    $this->field = $this->field_multiple;
240
241
//    $field_name = $this->field['field_name'];
//    $this->instance['field_name'] = $field_name;
242
//    entity_create('field_storage_config', $this->field)->save();
243
//    entity_create('field_config', $this->instance)->save();
244
245
246
//  }

  function testFieldFormUnlimited() {
247
    $field_storage = $this->fieldStorageUnlimited;
248
    $field_name = $field_storage['field_name'];
249
    $this->field['field_name'] = $field_name;
250
    entity_create('field_storage_config', $field_storage)->save();
251
252
    entity_create('field_config', $this->field)->save();
    entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
253
      ->setComponent($field_name)
254
      ->save();
255
256

    // Display creation form -> 1 widget.
257
    $this->drupalGet('entity_test/add');
258
259
    $this->assertFieldByName("{$field_name}[0][value]", '', 'Widget 1 is displayed');
    $this->assertNoField("{$field_name}[1][value]", 'No extraneous widget is displayed');
260

261
262
263
264
    // 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.'));

265
    // Press 'add more' button -> 2 widgets.
266
    $this->drupalPostForm(NULL, array(), t('Add another item'));
267
268
269
    $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');
270
    // TODO : check that non-field inputs are preserved ('title'), etc.
271
272

    // Yet another time so that we can play with more values -> 3 widgets.
273
    $this->drupalPostForm(NULL, array(), t('Add another item'));
274
275
276
277

    // Prepare values and weights.
    $count = 3;
    $delta_range = $count - 1;
278
    $values = $weights = $pattern = $expected_values = array();
279
    $edit = array();
280
281
282
283
284
285
286
287
    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));
288
289
      $edit["{$field_name}[$delta][value]"] = $value;
      $edit["{$field_name}[$delta][_weight]"] = $weight;
290
291
292
293
294
295
296
297
      // 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
298
    $this->drupalPostForm(NULL, $edit, t('Add another item'));
299
    for ($delta = 0; $delta <= $delta_range; $delta++) {
300
301
      $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");
302
303
304
305
    }
    ksort($pattern);
    $pattern = implode('.*', array_values($pattern));
    $this->assertPattern("|$pattern|s", 'Widgets are displayed in the correct order');
306
307
308
    $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');
309
310

    // Submit the form and create the entity.
311
    $this->drupalPostForm(NULL, $edit, t('Save'));
312
    preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
313
    $id = $match[1];
314
315
    $this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created');
    $entity = entity_load('entity_test', $id);
316
317
    ksort($field_values);
    $field_values = array_values($field_values);
318
    $this->assertIdentical($entity->{$field_name}->getValue(), $field_values, 'Field values were saved in the correct order');
319
320
321
322
323
324
325
326
327
328

    // 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
  }

329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
  /**
   * 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.
345
346
    $element = $this->xpath('//h4[contains(@class, "label") and contains(@class, "js-form-required") and contains(text(), :value)]', array(':value' => $this->field['label']));
    $this->assertTrue(isset($element[0]), 'Required symbol added field label.');
347
348
    // Check that the label of the field input is visually hidden and contains
    // the field title and an indication of the delta for a11y.
349
350
    $element = $this->xpath('//label[@for=:for and contains(@class, "js-form-required") and contains(text(), :value)]', array(':for' => 'edit-field-unlimited-0-value', ':value' => $this->field['label'] . ' (value 1)'));
    $this->assertTrue(isset($element[0]), 'Required symbol not added for field input.');
351
352
  }

353
354
355
356
357
  /**
   * Tests widget handling of multiple required radios.
   */
  function testFieldFormMultivalueWithRequiredRadio() {
    // Create a multivalue test field.
358
    $field_storage = $this->fieldStorageUnlimited;
359
    $field_name = $field_storage['field_name'];
360
    $this->field['field_name'] = $field_name;
361
    entity_create('field_storage_config', $field_storage)->save();
362
363
    entity_create('field_config', $this->field)->save();
    entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
364
      ->setComponent($field_name)
365
      ->save();
366
367

    // Add a required radio field.
368
    entity_create('field_storage_config', array(
369
      'field_name' => 'required_radio_test',
370
      'entity_type' => 'entity_test',
371
      'type' => 'list_string',
372
373
374
      'settings' => array(
        'allowed_values' => array('yes' => 'yes', 'no' => 'no'),
      ),
375
    ))->save();
376
    $field = array(
377
      'field_name' => 'required_radio_test',
378
379
      'entity_type' => 'entity_test',
      'bundle' => 'entity_test',
380
      'required' => TRUE,
381
    );
382
383
384
    entity_create('field_config', $field)->save();
    entity_get_form_display($field['entity_type'], $field['bundle'], 'default')
      ->setComponent($field['field_name'], array(
385
386
387
        'type' => 'options_buttons',
      ))
      ->save();
388
389

    // Display creation form.
390
    $this->drupalGet('entity_test/add');
391
392

    // Press the 'Add more' button.
393
    $this->drupalPostForm(NULL, array(), t('Add another item'));
394
395
396
397
398

    // 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.
399
400
401
    $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');
402
403
404
  }

  function testFieldFormJSAddMore() {
405
    $field_storage = $this->fieldStorageUnlimited;
406
    $field_name = $field_storage['field_name'];
407
    $this->field['field_name'] = $field_name;
408
    entity_create('field_storage_config', $field_storage)->save();
409
410
    entity_create('field_config', $this->field)->save();
    entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
411
      ->setComponent($field_name)
412
      ->save();
413
414

    // Display creation form -> 1 widget.
415
    $this->drupalGet('entity_test/add');
416
417

    // Press 'add more' button a couple times -> 3 widgets.
418
    // drupalPostAjaxForm() will not work iteratively, so we add those through
419
    // non-JS submission.
420
421
    $this->drupalPostForm(NULL, array(), t('Add another item'));
    $this->drupalPostForm(NULL, array(), t('Add another item'));
422
423
424
425
426
427
428
429
430
431
432
433
434

    // Prepare values and weights.
    $count = 3;
    $delta_range = $count - 1;
    $values = $weights = $pattern = $expected_values = $edit = array();
    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));
435
436
      $edit["{$field_name}[$delta][value]"] = $value;
      $edit["{$field_name}[$delta][_weight]"] = $weight;
437
438
439
440
441
442
443
444
      // 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 through Ajax, and place the expected HTML result
    // as the tested content.
445
    $commands = $this->drupalPostAjaxForm(NULL, $edit, $field_name . '_add_more');
446
    $this->setRawContent($commands[2]['data']);
447
448

    for ($delta = 0; $delta <= $delta_range; $delta++) {
449
450
      $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");
451
452
453
454
    }
    ksort($pattern);
    $pattern = implode('.*', array_values($pattern));
    $this->assertPattern("|$pattern|s", 'Widgets are displayed in the correct order');
455
456
457
    $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');
458
459
460
461
462
463
  }

  /**
   * Tests widgets handling multiple values.
   */
  function testFieldFormMultipleWidget() {
464
465
    // Create a field with fixed cardinality, configure the form to use a
    // "multiple" widget.
466
    $field_storage = $this->fieldStorageMultiple;
467
    $field_name = $field_storage['field_name'];
468
    $this->field['field_name'] = $field_name;
469
    entity_create('field_storage_config', $field_storage)->save();
470
471
    entity_create('field_config', $this->field)->save();
    entity_get_form_display($this->field['entity_type'], $this->field['bundle'], 'default')
472
      ->setComponent($field_name, array(
473
474
475
        'type' => 'test_field_widget_multiple',
      ))
      ->save();
476
477

    // Display creation form.
478
    $this->drupalGet('entity_test/add');
479
    $this->assertFieldByName($field_name, '', 'Widget is displayed.');
480
481

    // Create entity with three values.
482
    $edit = array(
483
      $field_name => '1, 2, 3',
484
    );
485
    $this->drupalPostForm(NULL, $edit, t('Save'));
486
    preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
487
488
489
    $id = $match[1];

    // Check that the values were saved.
490
    $entity_init = entity_load('entity_test', $id);
491
    $this->assertFieldValues($entity_init, $field_name, array(1, 2, 3));
492
493

    // Display the form, check that the values are correctly filled in.
494
    $this->drupalGet('entity_test/manage/' . $id . '/edit');
495
    $this->assertFieldByName($field_name, '1, 2, 3', 'Widget is displayed.');
496
497

    // Submit the form with more values than the field accepts.
498
    $edit = array($field_name => '1, 2, 3, 4, 5');
499
    $this->drupalPostForm(NULL, $edit, t('Save'));
500
    $this->assertRaw('this field cannot hold more than 4 values', 'Form validation failed.');
501
    // Check that the field values were not submitted.
502
    $this->assertFieldValues($entity_init, $field_name, array(1, 2, 3));
503
504
505
506
507
508
  }

  /**
   * Tests fields with no 'edit' access.
   */
  function testFieldFormAccess() {
509
    $entity_type = 'entity_test_rev';
510
    // Create a "regular" field.
511
512
    $field_storage = $this->fieldStorageSingle;
    $field_storage['entity_type'] = $entity_type;
513
    $field_name = $field_storage['field_name'];
514
515
516
517
    $field = $this->field;
    $field['field_name'] = $field_name;
    $field['entity_type'] = $entity_type;
    $field['bundle'] = $entity_type;
518
    entity_create('field_storage_config', $field_storage)->save();
519
    entity_create('field_config', $field)->save();
520
    entity_get_form_display($entity_type, $entity_type, 'default')
521
522
      ->setComponent($field_name)
      ->save();
523

524
525
    // Create a field with no edit access. See
    // field_test_entity_field_access().
526
    $field_storage_no_access = array(
527
      'field_name' => 'field_no_edit_access',
528
      'entity_type' => $entity_type,
529
530
      'type' => 'test_field',
    );
531
    $field_name_no_access = $field_storage_no_access['field_name'];
532
    $field_no_access = array(
533
      'field_name' => $field_name_no_access,
534
535
      'entity_type' => $entity_type,
      'bundle' => $entity_type,
536
537
      'default_value' => array(0 => array('value' => 99)),
    );
538
    entity_create('field_storage_config', $field_storage_no_access)->save();
539
540
    entity_create('field_config', $field_no_access)->save();
    entity_get_form_display($field_no_access['entity_type'], $field_no_access['bundle'], 'default')
541
542
      ->setComponent($field_name_no_access)
      ->save();
543
544
545

    // Test that the form structure includes full information for each delta
    // apart from #access.
546
    $entity = entity_create($entity_type, array('id' => 0, 'revision_id' => 0));
547

548
    $display = entity_get_form_display($entity_type, $entity_type, 'default');
549
    $form = array();
550
    $form_state = new FormState();
551
    $display->buildForm($entity, $form, $form_state);
552
553
554
555

    $this->assertFalse($form[$field_name_no_access]['#access'], 'Field #access is FALSE for the field without edit access.');

    // Display creation form.
556
    $this->drupalGet($entity_type . '/add');
557
    $this->assertNoFieldByName("{$field_name_no_access}[0][value]", '', 'Widget is not displayed if field access is denied.');
558
559

    // Create entity.
560
    $edit = array(
561
      "{$field_name}[0][value]" => 1,
562
    );
563
    $this->drupalPostForm(NULL, $edit, t('Save'));
564
    preg_match("|$entity_type/manage/(\d+)|", $this->url, $match);
565
566
567
    $id = $match[1];

    // Check that the default value was saved.
568
569
570
    $entity = entity_load($entity_type, $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.');
571
572

    // Create a new revision.
573
    $edit = array(
574
      "{$field_name}[0][value]" => 2,
575
576
      'revision' => TRUE,
    );
577
    $this->drupalPostForm($entity_type . '/manage/' . $id . '/edit', $edit, t('Save'));
578
579

    // Check that the new revision has the expected values.
580
    $this->container->get('entity.manager')->getStorage($entity_type)->resetCache(array($id));
581
582
583
    $entity = entity_load($entity_type, $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.');
584
585

    // Check that the revision is also saved in the revisions table.
586
587
588
//    $entity = entity_revision_load($entity_type, $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.');
589
590
  }

591
  /**
592
   * Tests hiding a field in a form.
593
   */
594
  function testHiddenField() {
595
    $entity_type = 'entity_test_rev';
596
597
    $field_storage = $this->fieldStorageSingle;
    $field_storage['entity_type'] = $entity_type;
598
    $field_name = $field_storage['field_name'];
599
600
601
602
    $this->field['field_name'] = $field_name;
    $this->field['default_value'] = array(0 => array('value' => 99));
    $this->field['entity_type'] = $entity_type;
    $this->field['bundle'] = $entity_type;
603
    entity_create('field_storage_config', $field_storage)->save();
604
605
    $this->field = entity_create('field_config', $this->field);
    $this->field->save();
606
607
    // We explicitly do not assign a widget in a form display, so the field
    // stays hidden in forms.
608
609

    // Display the entity creation form.
610
    $this->drupalGet($entity_type . '/add');
611
612
613

    // Create an entity and test that the default value is assigned correctly to
    // the field that uses the hidden widget.
614
    $this->assertNoField("{$field_name}[0][value]", 'The field does not appear in the form');
615
    $this->drupalPostForm(NULL, array(), t('Save'));
616
    preg_match('|' . $entity_type . '/manage/(\d+)|', $this->url, $match);
617
    $id = $match[1];
618
619
620
    $this->assertText(t('entity_test_rev @id has been created.', array('@id' => $id)), 'Entity was created');
    $entity = entity_load($entity_type, $id);
    $this->assertEqual($entity->{$field_name}->value, 99, 'Default value was saved');
621

622
623
    // Update the field to remove the default value, and switch to the default
    // widget.
624
    $this->field->setDefaultValue(array());
625
    $this->field->save();
626
    entity_get_form_display($entity_type, $this->field->getTargetBundle(), 'default')
627
      ->setComponent($this->field->getName(), array(
628
629
630
        'type' => 'test_field_widget',
      ))
      ->save();
631
632

    // Display edit form.
633
    $this->drupalGet($entity_type . '/manage/' . $id . '/edit');
634
    $this->assertFieldByName("{$field_name}[0][value]", 99, 'Widget is displayed with the correct default value');
635
636
637

    // Update the entity.
    $value = mt_rand(1, 127);
638
    $edit = array("{$field_name}[0][value]" => $value);
639
    $this->drupalPostForm(NULL, $edit, t('Save'));
640
    $this->assertText(t('entity_test_rev @id has been updated.', array('@id' => $id)), 'Entity was updated');
641
    \Drupal::entityManager()->getStorage($entity_type)->resetCache(array($id));
642
643
    $entity = entity_load($entity_type, $id);
    $this->assertEqual($entity->{$field_name}->value, $value, 'Field value was updated');
644

645
    // Set the field back to hidden.
646
    entity_get_form_display($entity_type, $this->field->getTargetBundle(), 'default')
647
      ->removeComponent($this->field->getName())
648
      ->save();
649
650
651

    // Create a new revision.
    $edit = array('revision' => TRUE);
652
    $this->drupalPostForm($entity_type . '/manage/' . $id . '/edit', $edit, t('Save'));
653
654

    // Check that the expected value has been carried over to the new revision.
655
    \Drupal::entityManager()->getStorage($entity_type)->resetCache(array($id));
656
657
    $entity = entity_load($entity_type, $id);
    $this->assertEqual($entity->{$field_name}->value, $value, 'New revision has the expected value for the field with the Hidden widget');
658
  }
659

660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
  /**
   * 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>");
  }

696
}