public function TMGMTUiJavascriptTest::testReview

Tests of the job item review process.

File

tests/src/FunctionalJavascript/TMGMTUiJavascriptTest.php, line 93

Class

TMGMTUiJavascriptTest
Verifies the UI of the review form.

Namespace

Drupal\Tests\tmgmt\FunctionalJavascript

Code

public function testReview() {
  $page = $this
    ->getSession()
    ->getPage();
  $assert_session = $this
    ->assertSession();
  $job = $this
    ->createJob();
  $job->translator = $this->default_translator
    ->id();
  $job->settings = array();
  $job
    ->save();
  $item = $job
    ->addItem('test_source', 'test', 1);

  // The test expects the item to be active.
  $item
    ->active();
  $data = \Drupal::service('tmgmt.data')
    ->flatten($item
    ->getData());
  $keys = array_keys($data);
  $key = $keys[0];
  $this
    ->drupalGet('admin/tmgmt/items/' . $item
    ->id());

  // Test that source and target languages are displayed.
  $assert_session
    ->pageTextContains($item
    ->getJob()
    ->getSourceLanguage()
    ->getName());
  $assert_session
    ->pageTextContains($item
    ->getJob()
    ->getTargetLanguage()
    ->getName());

  // Testing the title of the preview page.
  $title_element = $page
    ->find('css', 'title');
  $this
    ->assertEquals('Job item ' . $item
    ->label() . ' | Drupal', $title_element
    ->getHtml());

  // Testing the result of the
  // TMGMTTranslatorUIControllerInterface::reviewDataItemElement()
  $assert_session
    ->pageTextContains(t('Testing output of review data item element @key from the testing provider.', array(
    '@key' => $key,
  )));

  // Test the review tool source textarea.
  $this
    ->assertSession()
    ->fieldValueEquals('dummy|deep_nesting[source]', $data[$key]['#text']);

  // Save translation.
  $this
    ->submitForm([
    'dummy|deep_nesting[translation]' => $data[$key]['#text'] . 'translated',
  ], 'Save');

  // Test review data item.
  $this
    ->drupalGet('admin/tmgmt/items/' . $item
    ->id());
  $page
    ->pressButton('reviewed-dummy|deep_nesting');
  $assert_session
    ->assertWaitOnAjaxRequest();
  $assert_session
    ->responseContains('icons/gray-check.svg" alt="Reviewed"');
  \Drupal::entityTypeManager()
    ->getStorage('tmgmt_job')
    ->resetCache();
  \Drupal::entityTypeManager()
    ->getStorage('tmgmt_job_item')
    ->resetCache();

  /** @var JobItem $item */
  $item = JobItem::load($item
    ->id());
  $this
    ->assertEquals(1, $item
    ->getCountReviewed(), 'Item reviewed correctly.');

  // Check if translation has been saved.
  $this
    ->assertSession()
    ->fieldValueEquals('dummy|deep_nesting[translation]', $data[$key]['#text'] . 'translated');

  // Tests for the minimum height of the textareas.
  $rows = $this
    ->xpath('//textarea[@name="dummy|deep_nesting[source]"]');
  $this
    ->assertEquals(3, (string) $rows[0]
    ->getAttribute('rows'));
  $rows2 = $this
    ->xpath('//textarea[@name="dummy|deep_nesting[translation]"]');
  $this
    ->assertEquals(3, (string) $rows2[0]
    ->getAttribute('rows'));

  // Test data item status when content changes.
  $this
    ->submitForm([], 'Save');
  $this
    ->drupalGet('admin/tmgmt/items/' . $item
    ->id());
  $assert_session
    ->responseContains('icons/gray-check.svg" alt="Reviewed"');
  $edit = [
    'dummy|deep_nesting[translation]' => 'New text for job item',
  ];
  $this
    ->submitForm($edit, 'Save');
  $this
    ->drupalGet('admin/tmgmt/items/' . $item
    ->id());
  $assert_session
    ->responseContains('icons/gray-check.svg" alt="Reviewed"');
  $this
    ->assertSession()
    ->fieldValueEquals('dummy|deep_nesting[translation]', 'New text for job item');

  // Test for the dynamical height of the source textarea.
  \Drupal::state()
    ->set('tmgmt.test_source_data', array(
    'dummy' => array(
      'deep_nesting' => array(
        '#text' => str_repeat('Text for job item', 20),
        '#label' => 'Label',
      ),
    ),
  ));
  $item2 = $job
    ->addItem('test_source', 'test', 2);
  $this
    ->drupalGet('admin/tmgmt/items/' . $item2
    ->id());
  $rows3 = $this
    ->xpath('//textarea[@name="dummy|deep_nesting[source]"]');
  $this
    ->assertEquals(4, (string) $rows3[0]
    ->getAttribute('rows'));

  // Test for the maximum height of the source textarea.
  \Drupal::state()
    ->set('tmgmt.test_source_data', array(
    'dummy' => array(
      'deep_nesting' => array(
        '#text' => str_repeat('Text for job item', 100),
        '#label' => 'Label',
      ),
    ),
  ));
  $item3 = $job
    ->addItem('test_source', 'test', 3);
  $this
    ->drupalGet('admin/tmgmt/items/' . $item3
    ->id());
  $rows4 = $this
    ->xpath('//textarea[@name="dummy|deep_nesting[source]"]');
  $this
    ->assertEquals(15, (string) $rows4[0]
    ->getAttribute('rows'));

  // Tests the HTML tags validation.
  \Drupal::state()
    ->set('tmgmt.test_source_data', array(
    'title' => array(
      'deep_nesting' => array(
        '#text' => '<p><em><strong>Source text bold and Italic</strong></em></p>',
        '#label' => 'Title',
      ),
    ),
    'body' => array(
      'deep_nesting' => array(
        '#text' => '<p><em><strong>Source body bold and Italic</strong></em></p>',
        '#label' => 'Body',
      ),
    ),
  ));
  $item4 = $job
    ->addItem('test_source', 'test', 4);
  $this
    ->drupalGet('admin/tmgmt/items/' . $item4
    ->id());

  // Drop <strong> tag in translated text.
  $edit = array(
    'title|deep_nesting[translation]' => '<em>Translated italic text missing paragraph</em>',
  );
  $this
    ->submitForm($edit, 'Validate HTML tags');
  $assert_session
    ->responseContains(t('Expected tags @tags not found.', array(
    '@tags' => '<p>,<strong>,</strong>,</p>',
  )));
  $assert_session
    ->responseContains(t('@tag expected 1, found 0.', array(
    '@tag' => '<p>',
  )));
  $assert_session
    ->responseContains(t('@tag expected 1, found 0.', array(
    '@tag' => '<strong>',
  )));
  $assert_session
    ->responseContains(t('@tag expected 1, found 0.', array(
    '@tag' => '</strong>',
  )));
  $assert_session
    ->responseContains(t('@tag expected 1, found 0.', array(
    '@tag' => '</p>',
  )));
  $assert_session
    ->pageTextContains('HTML tag validation failed for 1 field(s).');

  // Change the order of HTML tags.
  $edit = array(
    'title|deep_nesting[translation]' => '<p><strong><em>Translated text Italic and bold</em></strong></p>',
  );
  $this
    ->submitForm($edit, 'Validate HTML tags');
  $assert_session
    ->pageTextContains('Order of the HTML tags are incorrect.');
  $assert_session
    ->pageTextContains('HTML tag validation failed for 1 field(s).');

  // Add multiple tags incorrectly.
  $edit = array(
    'title|deep_nesting[translation]' => '<p><p><p><p><strong><em><em>Translated text Italic and bold, many tags</em></strong></strong></strong></p>',
  );
  $this
    ->submitForm($edit, 'Validate HTML tags');
  $assert_session
    ->responseContains(t('@tag expected 1, found 4.', array(
    '@tag' => '<p>',
  )));
  $assert_session
    ->responseContains(t('@tag expected 1, found 2.', array(
    '@tag' => '<em>',
  )));
  $assert_session
    ->responseContains(t('@tag expected 1, found 3.', array(
    '@tag' => '</strong>',
  )));
  $assert_session
    ->pageTextContains('HTML tag validation failed for 1 field(s).');

  // Check validation errors for two fields.
  $edit = array(
    'title|deep_nesting[translation]' => '<p><p><p><p><strong><em><em>Translated text Italic and bold, many tags</em></strong></strong></strong></p>',
    'body|deep_nesting[translation]' => '<p>Source body bold and Italic</strong></em></p>',
  );
  $this
    ->submitForm($edit, 'Validate HTML tags');
  $assert_session
    ->pageTextContains('HTML tag validation failed for 2 field(s).');

  // Tests that there is always a title.
  $text = '<p><em><strong>Source text bold and Italic</strong></em></p>';
  \Drupal::state()
    ->set('tmgmt.test_source_data', [
    'title' => [
      [
        'value' => [
          '#text' => $text,
          '#label' => 'Title',
          '#translate' => TRUE,
          '#format' => 'filtered_html',
        ],
      ],
    ],
    'body' => [
      'deep_nesting' => [
        '#text' => $text,
        '#label' => 'Body',
        '#translate' => TRUE,
        '#format' => 'filtered_html',
      ],
    ],
  ]);
  $item5 = $job
    ->addItem('test_source', 'test', 4);
  $this
    ->drupalGet($item5
    ->toUrl());
  $this
    ->submitForm([], 'Validate');
  $assert_session
    ->pageTextContains('The field is empty.');

  // Test review just one data item.
  $this
    ->drupalGet('admin/tmgmt/items/' . $item5
    ->id());
  $page
    ->fillField('title|0|value[translation][value]', $text . 'translated');
  $page
    ->fillField('body|deep_nesting[translation][value]', $text . 'no save');
  $page
    ->pressButton('reviewed-title|0|value');
  $assert_session
    ->assertWaitOnAjaxRequest();

  // Check if translation has been saved.
  $this
    ->drupalGet('admin/tmgmt/items/' . $item5
    ->id());
  $this
    ->assertSession()
    ->fieldValueEquals('title|0|value[translation][value]', $text . 'translated');
  $this
    ->assertSession()
    ->fieldValueNotEquals('body|deep_nesting[translation][value]', $text . 'no save');

  // Test if the multibyte character length is 15 characters.
  $mb_text = '文字長が15文字のMBテキスト';

  // Tests field is less than max_length.
  \Drupal::state()
    ->set('tmgmt.test_source_data', [
    'title' => [
      [
        'value' => [
          '#text' => $text,
          '#label' => 'Title',
          '#translate' => TRUE,
          '#max_length' => 10,
        ],
      ],
    ],
    'body' => [
      'deep_nesting' => [
        '#text' => $text,
        '#label' => 'Body',
        '#translate' => TRUE,
        '#max_length' => 20,
      ],
    ],
    // There are 15 multibyte characters so no error occurs in this field.
    'field1' => [
      [
        'value' => [
          '#text' => $mb_text,
          '#label' => 'Field1',
          '#translate' => TRUE,
          '#max_length' => 15,
        ],
      ],
    ],
    // An error will occur in this field because you have entered
    // 15 characters of text into a field with a character limit of 10.
    // However, if it had miscalculated the multibyte characters,
    // the error will display the wrong number of characters.
    'field2' => [
      [
        'value' => [
          '#text' => $mb_text,
          '#label' => 'Field2',
          '#translate' => TRUE,
          '#max_length' => 10,
        ],
      ],
    ],
  ]);
  $item5 = $job
    ->addItem('test_source', 'test', 4);
  $this
    ->drupalGet($item5
    ->toUrl());
  $this
    ->submitForm([
    'title|0|value[translation]' => $text,
    'body|deep_nesting[translation]' => $text,
    'field1|0|value[translation]' => $mb_text,
    'field2|0|value[translation]' => $mb_text,
  ], 'Save');
  $assert_session
    ->pageTextContains(t('The field has @size characters while the limit is @limit.', [
    '@size' => mb_strlen($text),
    '@limit' => 10,
  ]));
  $assert_session
    ->pageTextContains(t('The field has @size characters while the limit is @limit.', [
    '@size' => mb_strlen($text),
    '@limit' => 20,
  ]));

  // Check that there are no errors due to incorrect calculation of the number of multibyte characters.
  $assert_session
    ->pageTextNotContains(t('The field has @size characters while the limit is @limit.', [
    '@size' => strlen($mb_text),
    '@limit' => 15,
  ]));

  // $mb_text is a multibyte string of 15 characters.
  // Verify that the program is counting the characters correctly.
  $assert_session
    ->pageTextContains(t('The field has @size characters while the limit is @limit.', [
    '@size' => mb_strlen($mb_text),
    '@limit' => 10,
  ]));

  // Test if the validation is properly done.
  $page
    ->pressButton('reviewed-body|deep_nesting');
  $this
    ->assertSession()
    ->pageTextContainsOnce((string) t('The field has @size characters while the limit is @limit.', [
    '@size' => mb_strlen($text),
    '@limit' => '10',
  ]));

  // Test for the text with format set.
  \Drupal::state()
    ->set('tmgmt.test_source_data', array(
    'dummy' => array(
      'deep_nesting' => array(
        '#text' => 'Text for job item',
        '#label' => 'Label',
        '#format' => 'filtered_html',
      ),
    ),
  ));
  $item5 = $job
    ->addItem('test_source', 'test', 5);
  $item5
    ->active();
  $this
    ->drupalGet('admin/tmgmt/jobs/' . $job
    ->id());
  $assert_session
    ->pageTextContains('The translation of test_source:test:1 to German is finished and can now be reviewed.');
  $this
    ->clickLink('reviewed');
  $assert_session
    ->pageTextContains('Needs review');
  $title_element = $page
    ->find('css', 'title');
  $this
    ->assertEquals('Job item ' . $item
    ->label() . ' | Drupal', $title_element
    ->getHtml());
  $this
    ->drupalGet($job
    ->toUrl());
  $edit = array(
    'target_language' => 'de',
    'settings[action]' => 'submit',
  );
  $this
    ->submitForm($edit, 'Submit to provider');
  $this
    ->drupalGet('admin/tmgmt/items/' . $item5
    ->id());
  $xpath = $this
    ->xpath('//*[@id="edit-dummydeep-nesting-translation-format-guidelines"]/div//h4');
  $this
    ->assertEquals('Filtered HTML', $xpath[0]
    ->getHtml());
  $rows5 = $this
    ->xpath('//textarea[@name="dummy|deep_nesting[source][value]"]');
  $this
    ->assertEquals(3, (string) $rows5[0]
    ->getAttribute('rows'));
  $this
    ->submitForm([], 'Save');
  $assert_session
    ->pageTextNotContains('has been saved successfully.');
  $this
    ->drupalGet('admin/tmgmt/items/' . $item5
    ->id());
  $assert_session
    ->pageTextContains('In progress');
  $edit = array(
    'dummy|deep_nesting[translation][value]' => 'Translated text for job item',
  );
  $this
    ->submitForm($edit, 'Save');
  $assert_session
    ->pageTextContains('The translation for ' . trim($item5
    ->label()) . ' has been saved successfully.');
  $this
    ->drupalGet('admin/tmgmt/items/' . $item5
    ->id());
  $assert_session
    ->pageTextContains('Translated text for job item');
  $this
    ->submitForm($edit, 'Save as completed');
  $this
    ->assertEquals('Translated text for job item', \Drupal::state()
    ->get('tmgmt_test_saved_translation_' . $item5
    ->getItemType() . '_' . $item5
    ->getItemId())['dummy']['deep_nesting']['#translation']['#text']);

  // Test if the icons are displayed.
  $assert_session
    ->responseContains('views-field-progress">Accepted');
  $assert_session
    ->responseContains('icons/ready.svg"');
  $assert_session
    ->responseContains('title="Needs review"');
  $this
    ->loginAsAdmin();

  // Create two translators.
  $translator1 = $this
    ->createTranslator();
  $translator2 = $this
    ->createTranslator();
  $this
    ->drupalGet('admin/tmgmt/jobs');

  // Assert that translators are in dropdown list.
  $this
    ->assertSession()
    ->optionExists('edit-translator', $translator1
    ->id());
  $this
    ->assertSession()
    ->optionExists('edit-translator', $translator2
    ->id());

  // Assign each job to a translator.
  $job1 = $this
    ->createJob();
  $this
    ->drupalGet('admin/tmgmt/jobs');
  $label = trim($this
    ->xpath('//table/tbody/tr/td[2]')[0]
    ->getHtml());
  $job2 = $this
    ->createJob();
  $this
    ->drupalGet('admin/tmgmt/jobs');
  $this
    ->assertNotEmpty($label, trim($this
    ->xpath('//table/tbody/tr/td[2]')[0]
    ->getHtml()));
  $job1
    ->set('translator', $translator1
    ->id())
    ->save();
  $job2
    ->set('translator', $translator2
    ->id())
    ->save();

  // Test that progress bar is being displayed.
  $assert_session
    ->responseContains('class="tmgmt-progress tmgmt-progress-pending" style="width: 50%"');

  // Filter jobs by translator and assert values.
  $this
    ->drupalGet('admin/tmgmt/jobs', array(
    'query' => array(
      'translator' => $translator1
        ->id(),
    ),
  ));
  $label = trim($this
    ->xpath('//table/tbody/tr/td[5]')[0]
    ->getHtml());
  $this
    ->assertEquals($translator1
    ->label(), $label, 'Found provider label in table');
  $this
    ->assertNotEquals($translator2
    ->label(), $label, "Providers filtered in table");
  $this
    ->drupalGet('admin/tmgmt/jobs', array(
    'query' => array(
      'translator' => $translator2
        ->id(),
    ),
  ));
  $label = trim($this
    ->xpath('//table/tbody/tr/td[5]')[0]
    ->getHtml());
  $this
    ->assertEquals($translator2
    ->label(), $label, 'Found provider label in table');
  $this
    ->assertNotEquals($translator1
    ->label(), $label, "Providers filtered in table");
  $edit = array(
    'dummy|deep_nesting[translation]' => '',
  );
  $this
    ->drupalGet('admin/tmgmt/items/' . $item
    ->id());
  $this
    ->submitForm($edit, 'Validate');
  $assert_session
    ->pageTextContains('The field is empty.');
  $this
    ->submitForm([], 'Save');
  $assert_session
    ->pageTextNotContains('The field is empty.');
  $this
    ->drupalGet('admin/tmgmt/items/' . $item
    ->id());
  $this
    ->submitForm([], 'Save as completed');
  $assert_session
    ->pageTextContains('The field is empty.');

  // Test validation message for 'Validate' button.
  $this
    ->drupalGet('admin/tmgmt/items/' . $item
    ->id());
  $translation_field = $this
    ->randomMachineName();
  $edit = array(
    'dummy|deep_nesting[translation]' => $translation_field,
  );
  $this
    ->submitForm($edit, 'Validate');
  $assert_session
    ->pageTextContains('Validation completed successfully.');

  // Test validation message for 'Validate HTML tags' button.
  $this
    ->submitForm($edit, 'Validate HTML tags');
  $assert_session
    ->pageTextContains('Validation completed successfully.');

  // Test that normal job item are shown in job items overview.
  $this
    ->drupalGet('admin/tmgmt/job_items', array(
    'query' => array(
      'state' => 'All',
    ),
  ));
  $assert_session
    ->pageTextNotContains($job1
    ->label());

  // Test that the legend is being displayed.
  $assert_session
    ->responseContains('class="tmgmt-color-legend clearfix"');

  // Test that progress bar is being displayed.
  $assert_session
    ->responseContains('class="tmgmt-progress tmgmt-progress-reviewed" style="width: 100%"');
}