function TMGMTUiTest::testCheckoutForm

Test the page callbacks to create jobs and check them out.

This includes

  • Varying checkout situations with form detail values.
  • Unsupported checkout situations where translator is not available.
  • Exposed filters for job overview
  • Deleting a job

@todo Separate the exposed filter admin overview test.

File

tests/src/Functional/TMGMTUiTest.php, line 62

Class

TMGMTUiTest
Verifies basic functionality of the user interface

Namespace

Drupal\Tests\tmgmt\Functional

Code

function testCheckoutForm() {

  // Add a first item to the job. This will auto-create the job.
  $job = tmgmt_job_match_item('en', '');
  $job
    ->addItem('test_source', 'test', 1);

  // Go to checkout form.
  $this
    ->drupalGet($job
    ->toUrl());

  // Test primary buttons.
  $this
    ->assertSession()
    ->responseContains('Save job" class="button js-form-submit form-submit"');

  // Check checkout form.
  $this
    ->assertSession()
    ->pageTextContains('test_source:test:1');

  // Assert that the messages element is not shown.
  $this
    ->assertSession()
    ->pageTextNotContains('Translation Job messages');
  $this
    ->assertSession()
    ->pageTextNotContains('Checkout progress');

  // Add two more job items.
  $job
    ->addItem('test_source', 'test', 2);
  $job
    ->addItem('test_source', 'test', 3);

  // Go to checkout form.
  $this
    ->drupalGet($job
    ->toUrl());

  // Check checkout form.
  $this
    ->assertSession()
    ->pageTextContains('test_source:test:1');
  $this
    ->assertSession()
    ->pageTextContains('test_source:test:2');
  $this
    ->assertSession()
    ->pageTextContains('test_source:test:3');

  // @todo: Test ajax functionality.
  // Attempt to translate into greek.
  $edit = array(
    'target_language' => 'el',
    'settings[action]' => 'translate',
  );
  $this
    ->submitForm($edit, 'Submit to provider');
  $this
    ->assertSession()
    ->pageTextContains(t('@translator can not translate from @source to @target.', array(
    '@translator' => 'Test provider',
    '@source' => 'English',
    '@target' => 'Greek',
  )));

  // Job still needs to be in state new.

  /** @var \Drupal\tmgmt\JobInterface $job */
  $job = \Drupal::entityTypeManager()
    ->getStorage('tmgmt_job')
    ->loadUnchanged($job
    ->id());
  $this
    ->assertTrue($job
    ->isUnprocessed());

  // The owner must be the one that submits the job.
  $this
    ->assertTrue($job
    ->isAuthor());
  $this
    ->drupalLogin($this->translator_user);
  $this
    ->drupalGet('admin/tmgmt/jobs/' . $job
    ->id());
  $edit = array(
    'target_language' => 'es',
    'settings[action]' => 'translate',
  );
  $this
    ->submitForm($edit, 'Submit to provider');

  /** @var \Drupal\tmgmt\JobInterface $job */
  $job = \Drupal::entityTypeManager()
    ->getStorage('tmgmt_job')
    ->loadUnchanged($job
    ->id());
  $this
    ->assertTrue($job
    ->isAuthor());

  // Job needs to be in state active.
  $job = \Drupal::entityTypeManager()
    ->getStorage('tmgmt_job')
    ->loadUnchanged($job
    ->id());
  $this
    ->assertTrue($job
    ->isActive());
  foreach ($job
    ->getItems() as $job_item) {

    /* @var $job_item \Drupal\tmgmt\JobItemInterface */
    $this
      ->assertTrue($job_item
      ->isNeedsReview());
  }
  $this
    ->assertSession()
    ->pageTextContains('Test translation created');
  $this
    ->assertSession()
    ->pageTextNotContains('Test provider called');

  // Test redirection.
  $this
    ->assertSession()
    ->pageTextContains('Job overview');

  // Another job.
  $previous_tjid = $job
    ->id();
  $job = tmgmt_job_match_item('en', '');
  $job
    ->addItem('test_source', 'test', 9);
  $this
    ->assertNotEquals($previous_tjid, $job
    ->id());

  // Go to checkout form.
  $this
    ->drupalGet($job
    ->toUrl());

  // Check checkout form.
  $this
    ->assertSession()
    ->pageTextContains('You can provide a label for this job in order to identify it easily later on.');
  $this
    ->assertSession()
    ->pageTextContains('test_source:test:9');
  $edit = array(
    'target_language' => 'es',
    'settings[action]' => 'submit',
  );
  $this
    ->submitForm($edit, 'Submit to provider');
  $this
    ->assertSession()
    ->pageTextContains('Test submit');
  $job = \Drupal::entityTypeManager()
    ->getStorage('tmgmt_job')
    ->loadUnchanged($job
    ->id());
  $this
    ->assertTrue($job
    ->isActive());

  // Another job.
  $job = tmgmt_job_match_item('en', 'es');
  $item10 = $job
    ->addItem('test_source', 'test', 10);

  // Go to checkout form.
  $this
    ->drupalGet($job
    ->toUrl());

  // Check checkout form.
  $this
    ->assertSession()
    ->pageTextContains('You can provide a label for this job in order to identify it easily later on.');
  $this
    ->assertSession()
    ->pageTextContains('test_source:test:10');
  $edit = array(
    'settings[action]' => 'reject',
  );
  $this
    ->submitForm($edit, 'Submit to provider');
  $this
    ->assertSession()
    ->pageTextContains('This is not supported');
  $job = \Drupal::entityTypeManager()
    ->getStorage('tmgmt_job')
    ->loadUnchanged($job
    ->id());
  $this
    ->assertTrue($job
    ->isRejected());

  // Check displayed job messages.
  $args = array(
    '@view' => 'view-tmgmt-job-messages',
  );
  $this
    ->assertCount(2, $this
    ->xpath('//div[contains(@class, @view)]//tbody/tr', $args));

  // Check that the author for each is the current user.
  $message_authors = $this
    ->xpath('//div[contains(@class, @view)]//td[contains(@class, @field)]/*[self::a or self::span]  ', $args + array(
    '@field' => 'views-field-name',
  ));
  $this
    ->assertCount(2, $message_authors);
  foreach ($message_authors as $message_author) {
    $this
      ->assertEquals($this->translator_user
      ->getDisplayName(), $message_author
      ->getText());
  }

  // Make sure that rejected jobs can be re-submitted.
  $this
    ->assertTrue($job
    ->isSubmittable());
  $edit = array(
    'settings[action]' => 'translate',
  );
  $this
    ->submitForm($edit, 'Submit to provider');
  $this
    ->assertSession()
    ->pageTextContains('Test translation created');

  // Now that this job item is in the reviewable state, test primary buttons.
  $this
    ->drupalGet('admin/tmgmt/items/' . $item10
    ->id());
  $this
    ->assertSession()
    ->responseContains('Save" class="button js-form-submit form-submit"');
  $this
    ->submitForm([], 'Save');
  $this
    ->clickLink('View');
  $this
    ->assertSession()
    ->responseContains('Save as completed" class="button button--primary js-form-submit form-submit"');
  $this
    ->submitForm([], 'Save');
  $this
    ->assertSession()
    ->responseContains('Save job" class="button button--primary js-form-submit form-submit"');
  $this
    ->submitForm([], 'Save job');

  // HTML tags count.
  \Drupal::state()
    ->set('tmgmt.test_source_data', array(
    'title' => array(
      'deep_nesting' => array(
        '#text' => '<p><em><strong>Six dummy HTML tags in the title.</strong></em></p>',
        '#label' => 'Title',
      ),
    ),
    'body' => array(
      'deep_nesting' => array(
        '#text' => '<p>Two dummy HTML tags in the body.</p>',
        '#label' => 'Body',
      ),
    ),
    'phantom' => array(
      'deep_nesting' => array(
        '#text' => 'phantom text',
        '#label' => 'phantom label',
        '#translate' => FALSE,
        '#format' => 'filtered_html',
      ),
    ),
  ));
  $item4 = $job
    ->addItem('test_source', 'test', 4);

  // Manually active the item as the test expects that.
  $item4
    ->active();
  $this
    ->drupalGet('admin/tmgmt/items/' . $item4
    ->id());

  // Test if the phantom wrapper is not displayed because of #translate FALSE.
  $this
    ->assertSession()
    ->responseNotContains('tmgmt-ui-element-phantom-wrapper');
  $this
    ->drupalGet('admin/tmgmt/jobs');

  // Total number of tags should be 8 for this job.
  $rows = $this
    ->getSession()
    ->getPage()
    ->findAll('css', 'table.views-table tbody tr');
  $found = FALSE;
  foreach ($rows as $row) {
    if (trim($row
      ->find('css', 'td:nth-child(2)')
      ->getText()) == 'test_source:test:10') {
      $found = TRUE;
      $this
        ->assertEquals(8, $row
        ->find('css', 'td:nth-child(8)')
        ->getText());
    }
  }
  $this
    ->assertTrue($found);

  // Another job.
  $job = tmgmt_job_match_item('en', 'es');
  $job
    ->addItem('test_source', 'test', 11);

  // Go to checkout form.
  $this
    ->drupalGet($job
    ->toUrl());

  // Check checkout form.
  $this
    ->assertSession()
    ->pageTextContains('You can provide a label for this job in order to identify it easily later on.');
  $this
    ->assertSession()
    ->pageTextContains('test_source:test:11');
  $edit = array(
    'settings[action]' => 'fail',
  );
  $this
    ->submitForm($edit, 'Submit to provider');
  $this
    ->assertSession()
    ->pageTextContains('Service not reachable');
  \Drupal::entityTypeManager()
    ->getStorage('tmgmt_job')
    ->resetCache();
  $job = Job::load($job
    ->id());
  $this
    ->assertTrue($job
    ->isUnprocessed());

  // Verify that we are still on the form.
  $this
    ->assertSession()
    ->pageTextContains('You can provide a label for this job in order to identify it easily later on.');

  // Another job.
  $job = tmgmt_job_match_item('en', 'es');
  $job
    ->addItem('test_source', 'test', 12);

  // Go to checkout form.
  $this
    ->drupalGet($job
    ->toUrl());

  // Check checkout form.
  $this
    ->assertSession()
    ->pageTextContains('You can provide a label for this job in order to identify it easily later on.');
  $this
    ->assertSession()
    ->pageTextContains('test_source:test:12');
  $edit = array(
    'settings[action]' => 'not_translatable',
  );
  $this
    ->submitForm($edit, 'Submit to provider');

  // @todo Update to correct failure message.
  $this
    ->assertSession()
    ->pageTextContains('Fail');
  $job = \Drupal::entityTypeManager()
    ->getStorage('tmgmt_job')
    ->loadUnchanged($job
    ->id());
  $this
    ->assertTrue($job
    ->isUnprocessed());

  // Test default settings.
  $this->default_translator
    ->setSetting('action', 'reject');
  $this->default_translator
    ->save();
  $job = tmgmt_job_match_item('en', 'es');
  $job
    ->addItem('test_source', 'test', 13);

  // Go to checkout form.
  $this
    ->drupalGet($job
    ->toUrl());

  // Check checkout form.
  $this
    ->assertSession()
    ->pageTextContains('You can provide a label for this job in order to identify it easily later on.');
  $this
    ->assertSession()
    ->pageTextContains('test_source:test:13');

  // The action should now default to reject.
  $this
    ->submitForm([], 'Submit to provider');
  $this
    ->assertSession()
    ->pageTextContains('This is not supported.');
  $job4 = \Drupal::entityTypeManager()
    ->getStorage('tmgmt_job')
    ->loadUnchanged($job
    ->id());
  $this
    ->assertTrue($job4
    ->isRejected());
  $this
    ->drupalGet('admin/tmgmt/jobs');

  // Test if sources languages are correct.
  $sources = $this
    ->xpath('//table[contains(@class, "views-table")]/tbody/tr/td[@class="views-field views-field-source-language-1"][contains(., "English")]');
  $this
    ->assertCount(4, $sources);

  // Test if targets languages are correct.
  $targets = $this
    ->xpath('//table[contains(@class, "views-table")]/tbody/tr/td[@class="views-field views-field-target-language"][contains(., "Spanish") or contains(., "German")]');
  $this
    ->assertCount(4, $targets);

  // Check that the first action is 'manage'.
  $first_action = $this
    ->xpath('//tbody/tr[2]/td[11]/div/div/ul/li[1]/a');
  $this
    ->assertEquals('Manage', $first_action[0]
    ->getText());

  // Test for Unavailable/Unconfigured Translators.
  $this->default_translator
    ->setSetting('action', 'not_translatable');
  $this->default_translator
    ->save();
  $this
    ->drupalGet('admin/tmgmt/jobs/' . $job
    ->id());
  $this
    ->submitForm([
    'target_language' => 'de',
  ], 'Submit to provider');
  $this
    ->assertSession()
    ->pageTextContains('Test provider can not translate from English to German.');

  // Test for Unavailable/Unconfigured Translators.
  $this->default_translator
    ->setSetting('action', 'not_available');
  $this->default_translator
    ->save();
  $this
    ->drupalGet('admin/tmgmt/jobs/' . $job
    ->id());
  $this
    ->assertSession()
    ->pageTextContains('Test provider is not available. Make sure it is properly configured.');
  $this
    ->submitForm([], 'Submit to provider');
  $this
    ->assertSession()
    ->pageTextContains(t('@translator is not available. Make sure it is properly configured.', array(
    '@translator' => 'Test provider',
  )));

  // Login as translator with permission to delete inactive job.
  $this
    ->loginAsTranslator([
    'delete translation jobs',
  ]);
  $this
    ->drupalGet('admin/tmgmt/jobs', array(
    'query' => array(
      'state' => 'All',
    ),
  ));

  // Translated languages should now be listed as Needs review.
  $start_rows = $this
    ->xpath('//tbody/tr');
  $this
    ->assertCount(4, $start_rows);
  $this
    ->drupalGet($job4
    ->toUrl('delete-form'));
  $this
    ->assertSession()
    ->pageTextContains('Are you sure you want to delete the translation job test_source:test:11 and 2 more?');
  $this
    ->submitForm([], 'Delete');
  $this
    ->drupalGet('admin/tmgmt/jobs', array(
    'query' => array(
      'state' => 'All',
    ),
  ));
  $end_rows = $this
    ->xpath('//tbody/tr');
  $this
    ->assertCount(3, $end_rows);
  $this
    ->drupalGet('admin/tmgmt/items/' . $item4
    ->id());
  $this
    ->clickLink('Abort');
  $this
    ->submitForm([], 'Confirm');
  $this
    ->assertSession()
    ->pageTextContains('Aborted');
  $this
    ->assertSession()
    ->linkNotExists('Abort');

  // Create active job.
  $job_active = $this
    ->createJob();
  $job_active
    ->save();
  $job_active
    ->setState(Job::STATE_ACTIVE);

  // Even if 'delete translation jobs' permission is granted active job
  // cannot be deleted.
  $this
    ->drupalGet($job_active
    ->toUrl('delete-form'));
  $this
    ->assertSession()
    ->statusCodeEquals(403);
}