You are here

public function FileFieldWidgetTest::testMultiValuedWidget in Drupal 8

Same name in this branch
  1. 8 core/modules/file/tests/src/Functional/FileFieldWidgetTest.php \Drupal\Tests\file\Functional\FileFieldWidgetTest::testMultiValuedWidget()
  2. 8 core/modules/file/tests/src/FunctionalJavascript/FileFieldWidgetTest.php \Drupal\Tests\file\FunctionalJavascript\FileFieldWidgetTest::testMultiValuedWidget()
Same name and namespace in other branches
  1. 9 core/modules/file/tests/src/FunctionalJavascript/FileFieldWidgetTest.php \Drupal\Tests\file\FunctionalJavascript\FileFieldWidgetTest::testMultiValuedWidget()

Tests upload and remove buttons for multiple multi-valued File fields.

File

core/modules/file/tests/src/FunctionalJavascript/FileFieldWidgetTest.php, line 64

Class

FileFieldWidgetTest
Tests the file field widget, single and multi-valued, using AJAX upload.

Namespace

Drupal\Tests\file\FunctionalJavascript

Code

public function testMultiValuedWidget() {
  $type_name = 'article';
  $field_name = 'test_file_field_1';
  $field_name2 = 'test_file_field_2';
  $cardinality = 3;
  $this
    ->createFileField($field_name, 'node', $type_name, [
    'cardinality' => $cardinality,
  ]);
  $this
    ->createFileField($field_name2, 'node', $type_name, [
    'cardinality' => $cardinality,
  ]);
  $page = $this
    ->getSession()
    ->getPage();
  $assert_session = $this
    ->assertSession();
  $test_file = current($this
    ->getTestFiles('text'));
  $test_file_path = \Drupal::service('file_system')
    ->realpath($test_file->uri);
  $this
    ->drupalGet("node/add/{$type_name}");
  foreach ([
    $field_name2,
    $field_name,
  ] as $each_field_name) {
    for ($delta = 0; $delta < 3; $delta++) {
      $page
        ->attachFileToField('files[' . $each_field_name . '_' . $delta . '][]', $test_file_path);
      $this
        ->assertNotNull($assert_session
        ->waitForElementVisible('css', '[name="' . $each_field_name . '_' . $delta . '_remove_button"]'));
      $this
        ->assertNull($assert_session
        ->waitForButton($each_field_name . '_' . $delta . '_upload_button'));
    }
  }
  $num_expected_remove_buttons = 6;
  foreach ([
    $field_name,
    $field_name2,
  ] as $current_field_name) {

    // How many uploaded files for the current field are remaining.
    $remaining = 3;

    // Test clicking each "Remove" button. For extra robustness, test them out
    // of sequential order. They are 0-indexed, and get renumbered after each
    // iteration, so array(1, 1, 0) means:
    // - First remove the 2nd file.
    // - Then remove what is then the 2nd file (was originally the 3rd file).
    // - Then remove the first file.
    foreach ([
      1,
      1,
      0,
    ] as $delta) {

      // Ensure we have the expected number of Remove buttons, and that they
      // are numbered sequentially.
      $buttons = $this
        ->xpath('//input[@type="submit" and @value="Remove"]');
      $this
        ->assertCount($num_expected_remove_buttons, $buttons, new FormattableMarkup('There are %n "Remove" buttons displayed.', [
        '%n' => $num_expected_remove_buttons,
      ]));
      foreach ($buttons as $i => $button) {
        $key = $i >= $remaining ? $i - $remaining : $i;
        $check_field_name = $field_name2;
        if ($current_field_name == $field_name && $i < $remaining) {
          $check_field_name = $field_name;
        }
        $this
          ->assertIdentical($button
          ->getAttribute('name'), $check_field_name . '_' . $key . '_remove_button');
      }
      $button_name = $current_field_name . '_' . $delta . '_remove_button';
      $remove_button = $assert_session
        ->waitForButton($button_name);
      $remove_button
        ->click();
      $num_expected_remove_buttons--;
      $remaining--;

      // Ensure an "Upload" button for the current field is displayed with the
      // correct name.
      $upload_button_name = $current_field_name . '_' . $remaining . '_upload_button';
      $this
        ->assertNotNull($assert_session
        ->waitForButton($upload_button_name));
      $buttons = $this
        ->xpath('//input[@type="submit" and @value="Upload" and @name=:name]', [
        ':name' => $upload_button_name,
      ]);
      $this
        ->assertCount(1, $buttons, 'The upload button is displayed with the correct name.');

      // Ensure only at most one button per field is displayed.
      $buttons = $this
        ->xpath('//input[@type="submit" and @value="Upload"]');
      $expected = $current_field_name == $field_name ? 1 : 2;
      $this
        ->assertCount($expected, $buttons, 'After removing a file, only one "Upload" button for each possible field is displayed.');
    }
  }
}