diff --git a/lingotek.module b/lingotek.module index c81b75eb..3e43bea2 100644 --- a/lingotek.module +++ b/lingotek.module @@ -5,6 +5,8 @@ * Implements Drupal-related hooks for the Lingotek Translation module. */ +use Drupal\Core\Entity\Entity\EntityFormDisplay; +use Drupal\Core\Entity\Entity\EntityViewDisplayDisplay; use Drupal\Core\Language\LanguageInterface; use Drupal\field\Entity\FieldConfig; use Drupal\Core\Config\Entity\ConfigEntityInterface; @@ -86,6 +88,12 @@ function lingotek_entity_insert(EntityInterface $entity) { if ($entity instanceof FieldConfig) { $entity_type_id = $entity->getTargetEntityTypeId() . '_fields'; } + if ($entity instanceof EntityFormDisplay) { + $entity_type_id = $entity->getTargetEntityTypeId() . '_form_display'; + } + if ($entity instanceof EntityViewDisplay) { + $entity_type_id = $entity->getTargetEntityTypeId() . '_view_display'; + } if ($translation_service->isEnabled($entity_type_id) && !in_array($entity->language()->getId(), [LanguageInterface::LANGCODE_NOT_SPECIFIED, LanguageInterface::LANGCODE_NOT_APPLICABLE])) { $profile = $configuration_service->getConfigEntityProfile($entity); if ($profile->id() === Lingotek::PROFILE_DISABLED) { @@ -251,6 +259,12 @@ function lingotek_entity_update(EntityInterface $entity) { if ($entity instanceof FieldConfig) { $entity_type_id = $entity->getTargetEntityTypeId() . '_fields'; } + if ($entity instanceof EntityFormDisplay) { + $entity_type_id = $entity->getTargetEntityTypeId() . '_form_display'; + } + if ($entity instanceof EntityViewDisplay) { + $entity_type_id = $entity->getTargetEntityTypeId() . '_view_display'; + } if ($translation_service->isEnabled($entity_type_id) && !in_array($entity->language()->getId(), [LanguageInterface::LANGCODE_NOT_SPECIFIED, LanguageInterface::LANGCODE_NOT_APPLICABLE])) { $profile = $configuration_service->getConfigEntityProfile($entity); if ($profile->id() === Lingotek::PROFILE_DISABLED) { diff --git a/src/Controller/LingotekConfigTranslationController.php b/src/Controller/LingotekConfigTranslationController.php index 2c555447..7c3fb176 100644 --- a/src/Controller/LingotekConfigTranslationController.php +++ b/src/Controller/LingotekConfigTranslationController.php @@ -616,16 +616,14 @@ class LingotekConfigTranslationController extends ConfigTranslationController { $id = $display->getTargetEntityTypeId(); $mapper = $mappers[$id . '_form_display']; $mapper->setEntity($display); - $entity_definition = $this->entityManager->getDefinition($id); - $uri = Url::fromRoute($mapper->getOverviewRouteName(), [$entity_type => $entity_id, 'form_mode_name' => $display->getMode(), $entity_definition->getBundleEntityType() => $display->getTargetBundle()]); + $uri = Url::fromRoute($mapper->getOverviewRouteName(), $mapper->getOverviewRouteParameters()); } elseif ($entity_type == 'entity_view_display') { $display = EntityViewDisplay::load($entity_id); $id = $display->getTargetEntityTypeId(); $mapper = $mappers[$id . '_form_display']; $mapper->setEntity($display); - $entity_definition = $this->entityManager->getDefinition($id); - $uri = Url::fromRoute($mapper->getOverviewRouteName(), [$entity_type => $entity_id, 'view_mode_name' => $display->getMode(), $entity_definition->getBundleEntityType() => $display->getTargetBundle()]); + $uri = Url::fromRoute($mapper->getOverviewRouteName(), $mapper->getOverviewRouteParameters()); } else { $mapper = $mappers[$entity_type]; diff --git a/src/LingotekConfigurationService.php b/src/LingotekConfigurationService.php index fdacf7c2..34f13215 100644 --- a/src/LingotekConfigurationService.php +++ b/src/LingotekConfigurationService.php @@ -4,6 +4,8 @@ namespace Drupal\lingotek; use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\Core\Entity\ContentEntityInterface; +use Drupal\Core\Entity\Entity\EntityFormDisplay; +use Drupal\Core\Entity\Entity\EntityViewDisplay; use Drupal\field\Entity\FieldConfig; use Drupal\language\ConfigurableLanguageInterface; use Drupal\lingotek\Entity\LingotekConfigMetadata; @@ -156,6 +158,12 @@ class LingotekConfigurationService implements LingotekConfigurationServiceInterf if ($entity instanceof FieldConfig) { $mapper_id = $entity->getTargetEntityTypeId() . '_fields'; } + if ($entity instanceof EntityFormDisplay) { + $mapper_id = $entity->getTargetEntityTypeId() . '_form_display'; + } + if ($entity instanceof EntityViewDisplay) { + $mapper_id = $entity->getTargetEntityTypeId() . '_view_display'; + } $profile_id = $this->getConfigEntityDefaultProfileId($mapper_id, $provide_default); } return $profile_id ? LingotekProfile::load($profile_id) : NULL; diff --git a/tests/modules/lingotek_test/document_responses/content_form_display.json b/tests/modules/lingotek_test/document_responses/content_form_display.json new file mode 100644 index 00000000..3f83d32b --- /dev/null +++ b/tests/modules/lingotek_test/document_responses/content_form_display.json @@ -0,0 +1,5 @@ +{ + "content.body.settings.placeholder": "ES Cuerpo placeholder", + "content.title.settings.placeholder": "ES Titulo placeholder", + "content.uid.settings.placeholder": "UID Titulo placeholder" +} diff --git a/tests/modules/lingotek_test/document_responses/content_view_display.json b/tests/modules/lingotek_test/document_responses/content_view_display.json new file mode 100644 index 00000000..3f83d32b --- /dev/null +++ b/tests/modules/lingotek_test/document_responses/content_view_display.json @@ -0,0 +1,5 @@ +{ + "content.body.settings.placeholder": "ES Cuerpo placeholder", + "content.title.settings.placeholder": "ES Titulo placeholder", + "content.uid.settings.placeholder": "UID Titulo placeholder" +} diff --git a/tests/src/Functional/LingotekContentFormDisplayBulkTranslationTest.php b/tests/src/Functional/LingotekContentFormDisplayBulkTranslationTest.php new file mode 100644 index 00000000..6227d31e --- /dev/null +++ b/tests/src/Functional/LingotekContentFormDisplayBulkTranslationTest.php @@ -0,0 +1,1524 @@ +drupalPlaceBlock('page_title_block', [ + 'region' => 'header', + 'weight' => -5 + ]); + $this->drupalPlaceBlock('local_tasks_block', [ + 'region' => 'header', + 'weight' => -10, + 'primary' => TRUE, + 'secondary' => TRUE, + ]); + + // Create content type. + $this->drupalCreateContentType([ + 'type' => 'article', + 'name' => 'Article', + ]); + + // Add a language. + ConfigurableLanguage::createFromLangcode('es') + ->setThirdPartySetting('lingotek', 'locale', 'es_MX') + ->save(); + + // This is a hack for avoiding writing different lingotek endpoint mocks. + \Drupal::state() + ->set('lingotek.uploaded_content_type', 'content_form_display'); + } + + /** + * Tests that a config can be translated using the links on the management page. + */ + public function testContentFormDisplayTranslationUsingLinks() { + // Login as admin. + $this->drupalLogin($this->rootUser); + + // Go to the bulk config management page. + $this->goToConfigBulkManagementForm('node_form_display'); + + $basepath = \Drupal::request()->getBasePath(); + + // Clicking English must init the upload of content. + $this->assertLingotekUploadLink(); + + // And we cannot request yet a translation. + $this->assertNoLingotekRequestTranslationLink('es_MX'); + $this->clickLink('EN'); + $this->assertText(t(' uploaded successfully')); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // There is a link for checking status. + $this->assertLingotekCheckSourceStatusLink(); + // And we can already request a translation. + $this->assertLingotekRequestTranslationLink('es_MX'); + $this->clickLink('EN'); + $this->assertText(' status checked successfully'); + + // Request the Spanish translation. + $this->assertLingotekRequestTranslationLink('es_MX'); + $this->clickLink('ES'); + $this->assertText("Translation to es_MX requested successfully"); + $this->assertIdentical('es_MX', \Drupal::state() + ->get('lingotek.added_target_locale')); + + // Check status of the Spanish translation. + $this->assertLingotekCheckTargetStatusLink('es_MX'); + $this->clickLink('ES'); + $this->assertIdentical('es_MX', \Drupal::state() + ->get('lingotek.checked_target_locale')); + $this->assertText("Translation to es_MX status checked successfully"); + + // Download the Spanish translation. + $this->assertLingotekDownloadTargetLink('es_MX'); + $this->clickLink('ES'); + $this->assertText('Translation to es_MX downloaded successfully'); + $this->assertIdentical('es_MX', \Drupal::state() + ->get('lingotek.downloaded_locale')); + + // Now the link is to the workbench, and it opens in a new tab. + $this->assertLingotekWorkbenchLink('es_MX'); + } + + /** + * Tests that a config can be translated using the actions on the management page. + */ + public function testContentFormDisplayTranslationUsingActions() { + // Login as admin. + $this->drupalLogin($this->rootUser); + + // Add a language. + ConfigurableLanguage::createFromLangcode('de') + ->setThirdPartySetting('lingotek', 'locale', 'de_AT') + ->save(); + + // Go to the bulk config management page. + $this->goToConfigBulkManagementForm('node_form_display'); + + $basepath = \Drupal::request()->getBasePath(); + + // I can init the upload of content. + $this->assertLingotekUploadLink(); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // I can check current status. + $this->assertLingotekCheckSourceStatusLink(); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForCheckUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + // Request the German (AT) translation. + $this->assertLingotekRequestTranslationLink('de_AT'); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForRequestTranslation('de', 'node_type'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('de_AT', \Drupal::state() + ->get('lingotek.added_target_locale')); + + // Check status of the German (AT) translation. + $this->assertLingotekCheckTargetStatusLink('de_AT'); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForCheckTranslation('de', 'node_type'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('de_AT', \Drupal::state() + ->get('lingotek.checked_target_locale')); + + // Download the German translation. + $this->assertLingotekDownloadTargetLink('de_AT'); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => 'download:de', + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('de_AT', \Drupal::state() + ->get('lingotek.downloaded_locale')); + + // Now the link is to the workbench, and it opens in a new tab. + $this->assertLingotekWorkbenchLink('de_AT'); + } + + /** + * Test that we handle errors in upload. + */ + public function testUploadingWithAnError() { + \Drupal::state()->set('lingotek.must_error_in_upload', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // Upload the document, which must fail. + $this->clickLink('EN'); + $this->assertText(' upload failed. Please try again.'); + + // Check the right class is added. + $this->assertSourceStatus('EN', Lingotek::STATUS_ERROR); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state()->set('lingotek.must_error_in_upload', FALSE); + $this->clickLink('EN'); + $this->assertText(' uploaded successfully'); + } + + /** + * Test that we handle errors in upload. + */ + public function testUploadingWithAPaymentRequiredError() { + \Drupal::state() + ->set('lingotek.must_payment_required_error_in_upload', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // Upload the document, which must fail. + $this->clickLink('EN'); + $this->assertText('Community has been disabled. Please contact support@lingotek.com to re-enable your community.'); + + // Check the right class is added. + $this->assertSourceStatus('EN', Lingotek::STATUS_ERROR); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state() + ->set('lingotek.must_payment_required_error_in_upload', FALSE); + $this->clickLink('EN'); + $this->assertText(' uploaded successfully'); + } + + /** + * Test that we handle errors in update. + */ + public function testUpdatingWithAnError() { + // Set upload as manual. + $this->saveLingotekConfigTranslationSettings([ + 'node_form_display' => 'manual', + ]); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // Upload the document, which must succeed. + $this->clickLink('EN'); + $this->assertText(' uploaded successfully'); + + // Check upload. + $this->clickLink('EN'); + + // Edit the form display. + $this->drupalPostForm('/admin/structure/types/manage/article/form-display/default', [], t('Save')); + $this->assertText('Your settings have been saved.'); + + \Drupal::state()->set('lingotek.must_error_in_upload', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // Update the document, which must fail. + $this->clickLink('EN'); + $this->assertText(' update failed. Please try again.'); + + // Check the right class is added. + $this->assertSourceStatus('EN', Lingotek::STATUS_ERROR); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state()->set('lingotek.must_error_in_upload', FALSE); + $this->clickLink('EN'); + $this->assertText(' has been updated.'); + } + + /** + * Test that we handle errors in update. + */ + public function testUpdatingWithAPaymentRequiredError() { + // Set upload as manual. + $this->saveLingotekConfigTranslationSettings([ + 'node_form_display' => 'manual', + ]); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // Upload the document, which must succeed. + $this->clickLink('EN'); + $this->assertText(' uploaded successfully'); + + // Check upload. + $this->clickLink('EN'); + + // Edit the form display. + $this->drupalPostForm('/admin/structure/types/manage/article/form-display/default', [], t('Save')); + $this->assertText('Your settings have been saved.'); + + \Drupal::state() + ->set('lingotek.must_payment_required_error_in_update', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // Update the document, which must fail. + $this->clickLink('EN'); + $this->assertText('Community has been disabled. Please contact support@lingotek.com to re-enable your community.'); + + // Check the right class is added. + $this->assertSourceStatus('EN', Lingotek::STATUS_ERROR); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state() + ->set('lingotek.must_payment_required_error_in_update', FALSE); + $this->clickLink('EN'); + $this->assertText(' has been updated.'); + } + + /** + * Test that we handle errors in update. + */ + public function testUpdatingWithADocumentArchivedError() { + // Set upload as manual. + $this->saveLingotekConfigTranslationSettings([ + 'node_form_display' => 'manual', + ]); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // Upload the document, which must succeed. + $this->clickLink('EN'); + $this->assertText(' uploaded successfully'); + + // Check upload. + $this->clickLink('EN'); + + // Edit the form display. + $this->drupalPostForm('/admin/structure/types/manage/article/form-display/default', [], t('Save')); + $this->assertText('Your settings have been saved.'); + + \Drupal::state() + ->set('lingotek.must_document_archived_error_in_update', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // Update the document, which must fail. + $this->clickLink('EN'); + $this->assertText('Document entity_form_display has been archived. Please upload again.'); + + // Check the right class is added. + $this->assertSourceStatus('EN', Lingotek::STATUS_UNTRACKED); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_UNTRACKED, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state() + ->set('lingotek.must_document_archived_error_in_update', FALSE); + $this->clickLink('EN'); + $this->assertText(' uploaded successfully'); + } + + /** + * Test that we handle errors in update. + */ + public function testUpdatingWithADocumentLockedError() { + // Set upload as manual. + $this->saveLingotekConfigTranslationSettings([ + 'node_form_display' => 'manual', + ]); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // Upload the document, which must succeed. + $this->clickLink('EN'); + $this->assertText(' uploaded successfully'); + + // Check upload. + $this->clickLink('EN'); + + // Edit the form display. + $this->drupalPostForm('/admin/structure/types/manage/article/form-display/default', [], t('Save')); + $this->assertText('Your settings have been saved.'); + + \Drupal::state() + ->set('lingotek.must_document_locked_error_in_update', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // Update the document, which must fail. + $this->clickLink('EN'); + $this->assertText('Document entity_form_display has a new version. The document id has been updated for all future interactions. Please try again.'); + + // Check the right class is added. + $this->assertSourceStatus('EN', Lingotek::STATUS_EDITED); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_EDITED, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state() + ->set('lingotek.must_document_locked_error_in_update', FALSE); + $this->clickLink('EN'); + $this->assertText(' has been updated.'); + } + + /** + * Test that we handle errors in upload. + */ + public function testUploadingWithAnErrorUsingActions() { + // Set upload as manual. + $this->saveLingotekConfigTranslationSettings([ + 'node_form_display' => 'manual', + ]); + + \Drupal::state()->set('lingotek.must_error_in_upload', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // Upload the document, which must fail. + $this->assertLingotekUploadLink(); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertText(' upload failed. Please try again.'); + + // Check the right class is added. + $this->assertSourceStatus('EN', Lingotek::STATUS_ERROR); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state()->set('lingotek.must_error_in_upload', FALSE); + $this->clickLink('EN'); + $this->assertText(' uploaded successfully'); + } + + /** + * Test that we handle errors in upload. + */ + public function testUploadingWithAPaymentRequiredErrorUsingActions() { + // Set upload as manual. + $this->saveLingotekConfigTranslationSettings([ + 'node_form_display' => 'manual', + ]); + + \Drupal::state() + ->set('lingotek.must_payment_required_error_in_upload', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // Upload the document, which must fail. + $basepath = \Drupal::request()->getBasePath(); + $this->assertLingotekUploadLink(); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertText('Community has been disabled. Please contact support@lingotek.com to re-enable your community.'); + + // Check the right class is added. + $this->assertSourceStatus('EN', Lingotek::STATUS_ERROR); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state() + ->set('lingotek.must_payment_required_error_in_upload', FALSE); + $this->clickLink('EN'); + $this->assertText(' uploaded successfully'); + } + + /** + * Test that we handle errors in update. + */ + public function testUpdatingWithAnErrorUsingActions() { + // Set upload as manual. + $this->saveLingotekConfigTranslationSettings([ + 'node_form_display' => 'manual', + ]); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // Upload the document, which must succeed. + $basepath = \Drupal::request()->getBasePath(); + $this->assertLingotekUploadLink(); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertText('Operations completed.'); + + // Check upload. + $this->clickLink('EN'); + + // Edit the form display. + $this->drupalPostForm('/admin/structure/types/manage/article/form-display/default', [], t('Save')); + $this->assertText('Your settings have been saved.'); + + \Drupal::state()->set('lingotek.must_error_in_upload', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + $this->assertText(' update failed. Please try again.'); + + // Check the right class is added. + $this->assertSourceStatus('EN', Lingotek::STATUS_ERROR); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state()->set('lingotek.must_error_in_upload', FALSE); + $this->clickLink('EN'); + $this->assertText(' has been updated.'); + } + + /** + * Test that we handle errors in update. + */ + public function testUpdatingWithADocumentLockedErrorUsingActions() { + // Set upload as manual. + $this->saveLingotekConfigTranslationSettings([ + 'node_form_display' => 'manual', + ]); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // Upload the document, which must succeed. + $basepath = \Drupal::request()->getBasePath(); + $this->assertLingotekUploadLink(); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertText('Operations completed.'); + + // Check upload. + $this->clickLink('EN'); + + // Edit the form display. + $this->drupalPostForm('/admin/structure/types/manage/article/form-display/default', [], t('Save')); + $this->assertText('Your settings have been saved.'); + + \Drupal::state() + ->set('lingotek.must_document_locked_error_in_update', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + $this->assertText('Document entity_form_display has a new version. The document id has been updated for all future interactions. Please try again.'); + + // Check the right class is added. + $this->assertSourceStatus('EN', Lingotek::STATUS_EDITED); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_EDITED, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state() + ->set('lingotek.must_document_locked_error_in_update', FALSE); + $this->clickLink('EN'); + $this->assertText(' has been updated.'); + } + + /** + * Test that we handle errors in update. + */ + public function testUpdatingWithAPaymentRequiredErrorUsingActions() { + // Set upload as manual. + $this->saveLingotekConfigTranslationSettings([ + 'node_form_display' => 'manual', + ]); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // Upload the document, which must succeed. + $basepath = \Drupal::request()->getBasePath(); + $this->assertLingotekUploadLink(); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertText('Operations completed.'); + + // Check upload. + $this->clickLink('EN'); + + // Edit the form display. + $this->drupalPostForm('/admin/structure/types/manage/article/form-display/default', [], t('Save')); + $this->assertText('Your settings have been saved.'); + + \Drupal::state() + ->set('lingotek.must_payment_required_error_in_update', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + $this->assertText('Community has been disabled. Please contact support@lingotek.com to re-enable your community.'); + + // Check the right class is added. + $this->assertSourceStatus('EN', Lingotek::STATUS_ERROR); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state() + ->set('lingotek.must_payment_required_error_in_update', FALSE); + $this->clickLink('EN'); + $this->assertText(' has been updated.'); + } + + /** + * Test that we handle errors in update. + */ + public function testUpdatingWithADocumentArchivedErrorUsingActions() { + // Set upload as manual. + $this->saveLingotekConfigTranslationSettings([ + 'node_form_display' => 'manual', + ]); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // Upload the document, which must succeed. + $basepath = \Drupal::request()->getBasePath(); + $this->assertLingotekUploadLink(); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertText('Operations completed.'); + + // Check upload. + $this->clickLink('EN'); + + // Edit the form display. + $this->drupalPostForm('/admin/structure/types/manage/article/form-display/default', [], t('Save')); + $this->assertText('Your settings have been saved.'); + + \Drupal::state() + ->set('lingotek.must_document_archived_error_in_update', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + $this->assertText('Document entity_form_display has been archived. Please upload again.'); + + // Check the right class is added. + $this->assertSourceStatus('EN', Lingotek::STATUS_UNTRACKED); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_UNTRACKED, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state() + ->set('lingotek.must_document_archived_error_in_update', FALSE); + $this->clickLink('EN'); + $this->assertText(' uploaded successfully'); + } + + /** + * Tests that we manage errors when using the request all translations action. + */ + public function testRequestAllTranslationsWithActionWithAnError() { + \Drupal::state()->set('lingotek.must_error_in_request_translation', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // I can init the upload of content. + $this->assertLingotekUploadLink(); + $key = $this->getBulkSelectionKey('en', 1); + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // I can check current status. + $this->assertLingotekCheckSourceStatusLink();; + // I can request a translation + $this->assertLingotekRequestTranslationLink('es_MX'); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForRequestTranslations('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + // We failed at requesting a translation, but we don't know what happened. + // So we don't mark as error but keep it on request. + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + $this->assertText('Document entity_form_display translations request failed. Please try again.'); + } + + /** + * Tests that we manage errors when using the request all translations action. + */ + public function testRequestAllTranslationsWithActionWithADocumentArchivedError() { + \Drupal::state() + ->set('lingotek.must_document_archived_error_in_request_translation', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // I can init the upload of content. + $this->assertLingotekUploadLink(); + $key = $this->getBulkSelectionKey('en', 1); + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // I can check current status. + $this->assertLingotekCheckSourceStatusLink();; + // I can request a translation + $this->assertLingotekRequestTranslationLink('es_MX'); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForRequestTranslations('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + $this->assertSourceStatus('EN', Lingotek::STATUS_UNTRACKED); + $this->assertNoLingotekRequestTranslationLink('es_MX'); + $this->assertText('Document entity_form_display has been archived. Please upload again.'); + } + + /** + * Tests that we manage errors when using the request all translations action. + */ + public function testRequestAllTranslationsWithActionWithADocumentLockedError() { + \Drupal::state() + ->set('lingotek.must_document_locked_error_in_request_translation', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // I can init the upload of content. + $this->assertLingotekUploadLink(); + $key = $this->getBulkSelectionKey('en', 1); + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // I can check current status. + $this->assertLingotekCheckSourceStatusLink();; + // I can request a translation + $this->assertLingotekRequestTranslationLink('es_MX'); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForRequestTranslations('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + $this->assertSourceStatus('EN', Lingotek::STATUS_IMPORTING); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + $this->assertText('Document entity_form_display has a new version. The document id has been updated for all future interactions. Please try again.'); + } + + /** + * Tests that we manage errors when using the request all translations action. + */ + public function testRequestAllTranslationsWithActionWithAPaymentRequiredError() { + \Drupal::state() + ->set('lingotek.must_payment_required_error_in_request_translation', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // I can init the upload of content. + $this->assertLingotekUploadLink(); + $key = $this->getBulkSelectionKey('en', 1); + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // I can check current status. + $this->assertLingotekCheckSourceStatusLink();; + // I can request a translation + $this->assertLingotekRequestTranslationLink('es_MX'); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForRequestTranslations('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + $this->assertSourceStatus('EN', Lingotek::STATUS_IMPORTING); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + $this->assertText('Community has been disabled. Please contact support@lingotek.com to re-enable your community.'); + } + + /** + * Tests that we manage errors when using the request translation link. + */ + public function testRequestTranslationWithAnError() { + \Drupal::state()->set('lingotek.must_error_in_request_translation', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // I can init the upload of content. + $this->assertLingotekUploadLink(); + $key = $this->getBulkSelectionKey('en', 1); + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // I can check current status. + $this->assertLingotekCheckSourceStatusLink();; + // I can request a translation + $this->assertLingotekRequestTranslationLink('es_MX'); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + + $this->clickLink('ES'); + + // We failed at requesting a translation, but we don't know what happened. + // So we don't mark as error but keep it on request. + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + $this->assertText(' es_MX translation request failed. Please try again.'); + } + + /** + * Tests that we manage errors when using the request translation link. + */ + public function testRequestTranslationWithAPaymentRequiredError() { + \Drupal::state() + ->set('lingotek.must_payment_required_error_in_request_translation', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // I can init the upload of content. + $this->assertLingotekUploadLink(); + $key = $this->getBulkSelectionKey('en', 1); + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // I can check current status. + $this->assertLingotekCheckSourceStatusLink();; + // I can request a translation + $this->assertLingotekRequestTranslationLink('es_MX'); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + + $this->clickLink('ES'); + + $this->assertSourceStatus('EN', Lingotek::STATUS_IMPORTING); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + $this->assertText('Community has been disabled. Please contact support@lingotek.com to re-enable your community.'); + } + + /** + * Tests that we manage errors when using the request translation link. + */ + public function testRequestTranslationWithADocumentArchivedError() { + \Drupal::state() + ->set('lingotek.must_document_archived_error_in_request_translation', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // I can init the upload of content. + $this->assertLingotekUploadLink(); + $key = $this->getBulkSelectionKey('en', 1); + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // I can check current status. + $this->assertLingotekCheckSourceStatusLink();; + // I can request a translation + $this->assertLingotekRequestTranslationLink('es_MX'); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + + $this->clickLink('ES'); + + $this->assertSourceStatus('EN', Lingotek::STATUS_UNTRACKED); + $this->assertNoLingotekRequestTranslationLink('es_MX'); + $this->assertText('Document entity_form_display has been archived. Please upload again.'); + } + + /** + * Tests that we manage errors when using the request translation link. + */ + public function testRequestTranslationWithADocumentLockedError() { + \Drupal::state() + ->set('lingotek.must_document_locked_error_in_request_translation', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // I can init the upload of content. + $this->assertLingotekUploadLink(); + $key = $this->getBulkSelectionKey('en', 1); + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // I can check current status. + $this->assertLingotekCheckSourceStatusLink();; + // I can request a translation + $this->assertLingotekRequestTranslationLink('es_MX'); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + + $this->clickLink('ES'); + + $this->assertSourceStatus('EN', Lingotek::STATUS_IMPORTING); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + $this->assertText('Document entity_form_display has a new version. The document id has been updated for all future interactions. Please try again.'); + } + + /** + * Tests that we manage errors when using the request translation action. + */ + public function testRequestTranslationWithActionWithAnError() { + \Drupal::state()->set('lingotek.must_error_in_request_translation', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // I can init the upload of content. + $this->assertLingotekUploadLink(); + $key = $this->getBulkSelectionKey('en', 1); + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // I can check current status. + $this->assertLingotekCheckSourceStatusLink();; + // I can request a translation + $this->assertLingotekRequestTranslationLink('es_MX'); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForRequestTranslation('es', 'node'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + // We failed at requesting a translation, but we don't know what happened. + // So we don't mark as error but keep it on request. + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + $this->assertText('Document entity_form_display es_MX translation request failed. Please try again.'); + } + + /** + * Tests that we manage errors when using the request translation action. + */ + public function testRequestTranslationWithActionWithADocumentArchivedError() { + \Drupal::state() + ->set('lingotek.must_document_archived_error_in_request_translation', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // I can init the upload of content. + $this->assertLingotekUploadLink(); + $key = $this->getBulkSelectionKey('en', 1); + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // I can check current status. + $this->assertLingotekCheckSourceStatusLink();; + // I can request a translation + $this->assertLingotekRequestTranslationLink('es_MX'); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForRequestTranslation('es', 'node'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + $this->assertSourceStatus('EN', Lingotek::STATUS_UNTRACKED); + $this->assertNoLingotekRequestTranslationLink('es_MX'); + $this->assertText('Document entity_form_display has been archived. Please upload again.'); + } + + /** + * Tests that we manage errors when using the request translation action. + */ + public function testRequestTranslationWithActionWithADocumentLockedError() { + \Drupal::state() + ->set('lingotek.must_document_locked_error_in_request_translation', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // I can init the upload of content. + $this->assertLingotekUploadLink(); + $key = $this->getBulkSelectionKey('en', 1); + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // I can check current status. + $this->assertLingotekCheckSourceStatusLink();; + // I can request a translation + $this->assertLingotekRequestTranslationLink('es_MX'); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForRequestTranslation('es', 'node'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + $this->assertSourceStatus('EN', Lingotek::STATUS_IMPORTING); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + $this->assertText('Document entity_form_display has a new version. The document id has been updated for all future interactions. Please try again.'); + } + + /** + * Tests that we manage errors when using the request translation action. + */ + public function testRequestTranslationWithActionWithAPaymentRequiredError() { + \Drupal::state() + ->set('lingotek.must_payment_required_error_in_request_translation', TRUE); + + $this->goToConfigBulkManagementForm('node_form_display'); + + // I can init the upload of content. + $this->assertLingotekUploadLink(); + $key = $this->getBulkSelectionKey('en', 1); + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // I can check current status. + $this->assertLingotekCheckSourceStatusLink();; + // I can request a translation + $this->assertLingotekRequestTranslationLink('es_MX'); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + + $edit = [ + $key => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForRequestTranslation('es', 'node'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + $this->assertSourceStatus('EN', Lingotek::STATUS_IMPORTING); + $this->assertTargetStatus('ES', Lingotek::STATUS_REQUEST); + $this->assertText('Community has been disabled. Please contact support@lingotek.com to re-enable your community.'); + } + + /** + * Tests that all the statuses are set when using the Check Translations action. + */ + public function testCheckTranslationsAction() { + // Add a couple of languages. + ConfigurableLanguage::create([ + 'id' => 'de_AT', + 'label' => 'German (Austria)' + ])->setThirdPartySetting('lingotek', 'locale', 'de_AT')->save(); + ConfigurableLanguage::createFromLangcode('ca') + ->setThirdPartySetting('lingotek', 'locale', 'ca_ES') + ->save(); + ConfigurableLanguage::createFromLangcode('it') + ->setThirdPartySetting('lingotek', 'locale', 'it_IT') + ->save(); + + $this->goToConfigBulkManagementForm('node_form_display'); + + $basepath = \Drupal::request()->getBasePath(); + + // I can init the upload of content. + $this->assertLingotekUploadLink(); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // I can check current status. + $this->assertLingotekCheckSourceStatusLink(); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForCheckUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + // Assert that I could request translations. + $this->assertLingotekRequestTranslationLink('de_AT'); + + // Check statuses, that may been requested externally. + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForCheckTranslations('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + // Now Drupal knows that there are translations ready. + $this->assertLingotekDownloadTargetLink('de_AT'); + $this->assertLingotekDownloadTargetLink('es_MX'); + + // Even if I just add a new language. + ConfigurableLanguage::createFromLangcode('de') + ->setThirdPartySetting('lingotek', 'locale', 'de_DE') + ->save(); + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertLingotekDownloadTargetLink('de_AT'); + + // Ensure locales are handled correctly by setting manual values. + \Drupal::state() + ->set('lingotek.document_completion_statuses', [ + 'de-AT' => 50, + 'de-DE' => 100, + 'es-MX' => 10 + ]); + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + // Now Drupal knows which translations are ready. + $this->assertNoLingotekDownloadTargetLink('de_AT'); + $this->assertLingotekDownloadTargetLink('de_DE'); + $this->assertNoLingotekDownloadTargetLink('es_MX'); + $this->assertLingotekRequestTranslationLink('ca_ES'); + $this->assertLingotekRequestTranslationLink('it_IT'); + + \Drupal::state() + ->set('lingotek.document_completion_statuses', [ + 'it-IT' => 100, + 'de-DE' => 50, + 'es-MX' => 10 + ]); + // Check all statuses again. + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + // All translations must be updated according exclusively with the + // information from the TMS. + $this->assertLingotekRequestTranslationLink('de_AT'); + $this->assertLingotekCheckTargetStatusLink('de_DE'); + $this->assertLingotekCheckTargetStatusLink('es_MX'); + $this->assertLingotekRequestTranslationLink('ca_ES'); + $this->assertLingotekDownloadTargetLink('it_IT'); + + // Source status must be kept too. + $this->assertSourceStatusStateCount(Lingotek::STATUS_CURRENT, 'EN', 1); + } + + /** + * Tests that unrequested locales are not marked as error when downloading all. + */ + public function testTranslationDownloadWithUnrequestedLocales() { + ConfigurableLanguage::createFromLangcode('de') + ->setThirdPartySetting('lingotek', 'locale', 'de_DE') + ->save(); + ConfigurableLanguage::createFromLangcode('it') + ->setThirdPartySetting('lingotek', 'locale', 'it_IT') + ->save(); + + $this->goToConfigBulkManagementForm('node_form_display'); + + $basepath = \Drupal::request()->getBasePath(); + + // I can init the upload of content. + $this->assertLingotekUploadLink(); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // I can check current status. + $this->assertLingotekCheckSourceStatusLink(); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForCheckUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + // Request the Spanish translation. + $this->assertLingotekRequestTranslationLink('es_MX'); + $this->clickLink('ES'); + $this->assertText("Translation to es_MX requested successfully"); + $this->assertIdentical('es_MX', \Drupal::state() + ->get('lingotek.added_target_locale')); + + // Check status of the Spanish translation. + $this->assertLingotekCheckTargetStatusLink('es_MX'); + $this->clickLink('ES'); + $this->assertIdentical('es_MX', \Drupal::state() + ->get('lingotek.checked_target_locale')); + $this->assertText("Translation to es_MX status checked successfully"); + + // Download all the translations. + $this->assertLingotekDownloadTargetLink('es_MX'); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForDownloadTranslations('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + // The translations not requested shouldn't change its status. + $this->assertLingotekRequestTranslationLink('de_DE'); + $this->assertLingotekRequestTranslationLink('it_IT'); + + // They aren't marked as error. + $this->assertNoConfigTargetError('Article', 'DE', 'de_DE'); + $this->assertNoConfigTargetError('Article', 'IT', 'it_IT'); + } + + /** + * Tests that current locales are not cleared when checking statuses. + */ + public function testCheckTranslationsWithDownloadedLocales() { + ConfigurableLanguage::createFromLangcode('de') + ->setThirdPartySetting('lingotek', 'locale', 'de_DE') + ->save(); + ConfigurableLanguage::createFromLangcode('it') + ->setThirdPartySetting('lingotek', 'locale', 'it_IT') + ->save(); + + $this->goToConfigBulkManagementForm('node_form_display'); + + $basepath = \Drupal::request()->getBasePath(); + + // I can init the upload of content. + $this->assertLingotekUploadLink(); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + $this->assertIdentical('en_US', \Drupal::state() + ->get('lingotek.uploaded_locale')); + + // I can check current status. + $this->assertLingotekCheckSourceStatusLink(); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForCheckUpload('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + // Request the Spanish translation. + $this->assertLingotekRequestTranslationLink('es_MX'); + $this->clickLink('ES'); + $this->assertText("Translation to es_MX requested successfully"); + $this->assertIdentical('es_MX', \Drupal::state() + ->get('lingotek.added_target_locale')); + + \Drupal::state()->resetCache(); + + // Request italian. + $this->assertLingotekRequestTranslationLink('it_IT'); + $this->clickLink('IT'); + $this->assertText("Translation to it_IT requested successfully"); + $this->assertIdentical('it_IT', \Drupal::state() + ->get('lingotek.added_target_locale')); + + // Check status of the Spanish translation. + $this->assertLingotekCheckTargetStatusLink('es_MX'); + $this->clickLink('ES'); + $this->assertIdentical('es_MX', \Drupal::state() + ->get('lingotek.checked_target_locale')); + $this->assertText("Translation to es_MX status checked successfully"); + + \Drupal::state()->resetCache(); + + // Check status of the Italian translation. + $this->assertLingotekCheckTargetStatusLink('it_IT'); + $this->clickLink('IT'); + $this->assertIdentical('it_IT', \Drupal::state() + ->get('lingotek.checked_target_locale')); + $this->assertText("Translation to it_IT status checked successfully"); + + // Download all the translations. + $this->assertLingotekDownloadTargetLink('es_MX'); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForDownloadTranslations('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + // They are marked with the right status. + $this->assertTargetStatus('ES', Lingotek::STATUS_CURRENT); + $this->assertTargetStatus('IT', Lingotek::STATUS_CURRENT); + $this->assertTargetStatus('DE', Lingotek::STATUS_REQUEST); + + // We check all translations. + \Drupal::state() + ->set('lingotek.document_completion_statuses', [ + 'es-ES' => 100, + 'it-IT' => 100 + ]); + $edit = [ + $this->getBulkSelectionKey() => TRUE, + $this->getBulkOperationFormName() => $this->getBulkOperationNameForCheckTranslations('node_form_display'), + ]; + $this->drupalPostForm(NULL, $edit, $this->getApplyActionsButtonLabel()); + + // And statuses should remain the same. + $this->assertTargetStatus('ES', Lingotek::STATUS_CURRENT); + $this->assertTargetStatus('IT', Lingotek::STATUS_CURRENT); + $this->assertTargetStatus('DE', Lingotek::STATUS_REQUEST); + } + + /** + * Tests that we update the statuses when a translation is deleted. + */ + public function testDeleteTranslationUpdatesStatuses() { + $this->markTestSkipped('Needs to be fixed'); + // TODO: FIX THIS. + $this->testContentFormDisplayTranslationUsingActions(); + + $this->goToConfigBulkManagementForm('node_form_display'); + $this->assertTargetStatus('DE', Lingotek::STATUS_CURRENT); + + $this->drupalGet('admin/config/regional/config-translation/node_form_display'); + $this->clickLink(t('Translate')); + $this->clickLink('Delete'); + $this->drupalPostForm(NULL, [], t('Delete')); + + $this->goToConfigBulkManagementForm('node_form_display'); + $this->assertTargetStatus('DE', Lingotek::STATUS_READY); + } + + protected function getBulkSelectionKey($langcode = 'en', $revision_id = 1, $entity_type_id = 'node.article.default') { + return 'table[' . $entity_type_id . ']'; + } + + /** + * Asserts there is a link for uploading the content. + * + * @param int|string $entity_id + * The entity ID. Optional, defaults to 1. + * @param string $entity_type_id + * The entity type ID. Optional, defaults to node. + * @param string|null $prefix + * Language prefix if any. Optional, defaults to NULL. + */ + protected function assertLingotekUploadLink($entity_id = 'node.article.default', $entity_type_id = 'node_form_display', $prefix = NULL, $destination_entity_type_id = NULL, $destination_entity_id = NULL) { + $basepath = \Drupal::request()->getBasePath(); + $languagePrefix = ($prefix === NULL ? '' : '/' . $prefix); + $destination_entity_type_id = $destination_entity_type_id ?: $entity_type_id; + $href = $basepath . $languagePrefix . '/admin/lingotek/config/upload/' . $entity_type_id . '/' . $entity_id; + if ($destination = $this->getDestination($destination_entity_type_id, $prefix)) { + $href .= $destination; + } + $this->assertLinkByHref($href); + } + + protected function assertLingotekCheckSourceStatusLink($document_id = 'node.article.default', $entity_type_id = 'node_form_display', $prefix = NULL, $destination_entity_type_id = NULL, $destination_entity_id = NULL) { + $basepath = \Drupal::request()->getBasePath(); + $languagePrefix = ($prefix === NULL ? '' : '/' . $prefix); + $destination_entity_type_id = $destination_entity_type_id ?: $entity_type_id; + $href = $basepath . $languagePrefix . '/admin/lingotek/config/check_upload/' . $entity_type_id . '/' . $document_id; + if ($destination = $this->getDestination($destination_entity_type_id, $prefix)) { + $href .= $destination; + } + $this->assertLinkByHref($href); + } + + protected function assertLingotekRequestTranslationLink($locale, $document_id = 'node.article.default', $entity_type_id = 'node_form_display', $prefix = NULL, $destination_entity_type_id = NULL, $destination_entity_id = NULL) { + $basepath = \Drupal::request()->getBasePath(); + $languagePrefix = ($prefix === NULL ? '' : '/' . $prefix); + $destination_entity_type_id = $destination_entity_type_id ?: $entity_type_id; + $href = $basepath . $languagePrefix . '/admin/lingotek/config/request/' . $entity_type_id . '/' . $document_id . '/' . $locale; + if ($destination = $this->getDestination($destination_entity_type_id, $prefix)) { + $href .= $destination; + } + $this->assertLinkByHref($href); + } + + protected function assertNoLingotekRequestTranslationLink($locale, $document_id = 'node.article.default', $entity_type_id = 'node_form_display', $prefix = NULL, $destination_entity_type_id = NULL, $destination_entity_id = NULL) { + $basepath = \Drupal::request()->getBasePath(); + $languagePrefix = ($prefix === NULL ? '' : '/' . $prefix); + $destination_entity_type_id = $destination_entity_type_id ?: $entity_type_id; + $href = $basepath . $languagePrefix . '/admin/lingotek/config/request/' . $entity_type_id . '/' . $document_id . '/' . $locale; + if ($destination = $this->getDestination($destination_entity_type_id, $prefix)) { + $href .= $destination; + } + $this->assertNoLinkByHref($href); + } + + protected function assertLingotekCheckTargetStatusLink($locale, $document_id = 'node.article.default', $entity_type_id = 'node_form_display', $prefix = NULL, $destination_entity_type_id = NULL, $destination_entity_id = NULL) { + $basepath = \Drupal::request()->getBasePath(); + $languagePrefix = ($prefix === NULL ? '' : '/' . $prefix); + $destination_entity_type_id = $destination_entity_type_id ?: $entity_type_id; + $href = $basepath . $languagePrefix . '/admin/lingotek/config/check_download/' . $entity_type_id . '/' . $document_id . '/' . $locale; + if ($destination = $this->getDestination($destination_entity_type_id, $prefix)) { + $href .= $destination; + } + $this->assertLinkByHref($href); + } + + protected function assertLingotekDownloadTargetLink($locale, $document_id = 'node.article.default', $entity_type_id = 'node_form_display', $prefix = NULL, $destination_entity_type_id = NULL, $destination_entity_id = NULL) { + $basepath = \Drupal::request()->getBasePath(); + $languagePrefix = ($prefix === NULL ? '' : '/' . $prefix); + $destination_entity_type_id = $destination_entity_type_id ?: $entity_type_id; + $href = $basepath . $languagePrefix . '/admin/lingotek/config/download/' . $entity_type_id . '/' . $document_id . '/' . $locale; + if ($destination = $this->getDestination($destination_entity_type_id, $prefix)) { + $href .= $destination; + } + $this->assertLinkByHref($href); + } + + protected function getDestination($entity_type_id = 'node_form_display', $prefix = NULL) { + $basepath = \Drupal::request()->getBasePath(); + return '?destination=' . $basepath . $this->getConfigBulkManagementFormUrl($entity_type_id, $prefix); + } + + protected function getConfigBulkManagementFormUrl($entity_type_id = 'node_form_display', $prefix = NULL) { + return ($prefix === NULL ? '' : '/' . $prefix) . '/admin/lingotek/config/manage'; + } + +} diff --git a/tests/src/Functional/LingotekContentFormDisplayTranslationTest.php b/tests/src/Functional/LingotekContentFormDisplayTranslationTest.php new file mode 100644 index 00000000..a0fe2907 --- /dev/null +++ b/tests/src/Functional/LingotekContentFormDisplayTranslationTest.php @@ -0,0 +1,346 @@ +drupalPlaceBlock('page_title_block', ['region' => 'header', 'weight' => -5]); + $this->drupalPlaceBlock('local_tasks_block', [ + 'region' => 'header', + 'weight' => -10, + 'primary' => TRUE, + 'secondary' => TRUE, + ]); + + // Create content type. + $this->drupalCreateContentType([ + 'type' => 'article', + 'name' => 'Article', + ]); + + // Add a language. + ConfigurableLanguage::createFromLangcode('es')->setThirdPartySetting('lingotek', 'locale', 'es_MX')->save(); + } + + /** + * Tests that a node can be translated. + */ + public function testTranslation() { + // This is a hack for avoiding writing different lingotek endpoint mocks. + \Drupal::state()->set('lingotek.uploaded_content_type', 'content_form_display'); + + // Login as admin. + $this->drupalLogin($this->rootUser); + + $this->drupalGet('/admin/config/regional/config-translation'); + $this->drupalGet('admin/config/regional/config-translation/node_form_display'); + $this->clickLink(t('Translate')); + + $this->clickLink(t('Upload')); + // ToDo: Fix this. + // $this->assertText(t('Article Default form display uploaded successfully')); + $this->assertText(t(' uploaded successfully')); + + // Check that only the translatable fields have been uploaded. + $data = json_decode(\Drupal::state()->get('lingotek.uploaded_content', '[]'), TRUE); + $this->assertEqual(3, count($data)); + $this->assertTrue(array_key_exists('content.body.settings.placeholder', $data)); + // Cannot use isset, the key exists but we are not providing values, so NULL. + $this->assertTrue(array_key_exists('content.title.settings.placeholder', $data)); + $this->assertTrue(array_key_exists('content.uid.settings.placeholder', $data)); + + // Check that the profile used was the right one. + $used_profile = \Drupal::state()->get('lingotek.used_profile'); + $this->assertIdentical('automatic', $used_profile, 'The automatic profile was used.'); + + $this->clickLink(t('Check upload status')); + $this->assertText(t(' status checked successfully')); + + $this->clickLink(t('Request translation')); + $this->assertText(t('Translation to es_MX requested successfully')); + $this->assertIdentical('es_MX', \Drupal::state()->get('lingotek.added_target_locale')); + + $this->clickLink(t('Check Download')); + $this->assertText(t('Translation to es_MX status checked successfully')); + + $this->clickLink('Download'); + $this->assertText(t('Translation to es_MX downloaded successfully')); + + // Check that the edit link is there. + $basepath = \Drupal::request()->getBasePath(); + $this->assertLinkByHref($basepath . '/admin/structure/types/manage/article/form-display/default/translate/es/edit'); + + $this->drupalGet('/es/node/add/article'); + $placeholder = $this->xpath("//input[@placeholder='ES Titulo placeholder']"); + $this->assertCount(1, $placeholder); + } + + /** + * Test that we handle errors in upload. + */ + public function testUploadingWithAnError() { + \Drupal::state()->set('lingotek.must_error_in_upload', TRUE); + + // Check that the translate tab is in the form display. + $this->drupalGet('admin/config/regional/config-translation/node_form_display'); + $this->clickLink(t('Translate')); + + // Upload the document, which must fail. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' upload failed. Please try again.'); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state()->set('lingotek.must_error_in_upload', FALSE); + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' uploaded successfully'); + } + + /** + * Test that we handle errors in upload. + */ + public function testUploadingWithAPaymentRequiredError() { + \Drupal::state()->set('lingotek.must_payment_required_error_in_upload', TRUE); + + // Check that the translate tab is in the form display. + $this->drupalGet('admin/config/regional/config-translation/node_form_display'); + $this->clickLink(t('Translate')); + + // Upload the document, which must fail. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText('Community has been disabled. Please contact support@lingotek.com to re-enable your community.'); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state()->set('lingotek.must_payment_required_error_in_upload', FALSE); + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' uploaded successfully'); + } + + /** + * Test that we handle errors in upload. + */ + public function testUpdatingWithAPaymentRequiredError() { + // Check that the translate tab is in the form display. + $this->drupalGet('/admin/config/regional/config-translation'); + $this->drupalGet('admin/config/regional/config-translation/node_form_display'); + $this->clickLink(t('Translate')); + + // Upload the document, which must succeed. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' uploaded successfully'); + + // Check that the upload succeeded. + $this->clickLink('Check upload status'); + $this->assertText(' status checked successfully'); + + // Edit the form display. + $this->drupalPostForm('/admin/structure/types/manage/article/form-display/default', [], t('Save')); + $this->assertText('Your settings have been saved.'); + + // Go back to the form. + $this->drupalGet('admin/config/regional/config-translation/node_form_display'); + $this->clickLink(t('Translate')); + + \Drupal::state()->set('lingotek.must_payment_required_error_in_update', TRUE); + + // Re-upload. Must fail now. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText('Community has been disabled. Please contact support@lingotek.com to re-enable your community.'); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state()->set('lingotek.must_payment_required_error_in_update', FALSE); + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' has been updated.'); + } + + /** + * Test that we handle errors in update. + */ + public function testUpdatingWithAnError() { + // Check that the translate tab is in the form display. + $this->drupalGet('/admin/config/regional/config-translation'); + $this->drupalGet('admin/config/regional/config-translation/node_form_display'); + $this->clickLink(t('Translate')); + + // Upload the document, which must succeed. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' uploaded successfully'); + + // Check that the upload succeeded. + $this->clickLink('Check upload status'); + $this->assertText(' status checked successfully'); + + // Edit the form display. + $this->drupalPostForm('/admin/structure/types/manage/article/form-display/default', [], t('Save')); + $this->assertText('Your settings have been saved.'); + + // Go back to the form. + $this->drupalGet('admin/config/regional/config-translation/node_form_display'); + $this->clickLink(t('Translate')); + + \Drupal::state()->set('lingotek.must_error_in_upload', TRUE); + + // Re-upload. Must fail now. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' update failed. Please try again.'); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state()->set('lingotek.must_error_in_upload', FALSE); + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' has been updated.'); + } + + /** + * Test that we handle errors in update. + */ + public function testUpdatingWithADocumentArchivedError() { + // Check that the translate tab is in the form display. + $this->drupalGet('/admin/config/regional/config-translation'); + $this->drupalGet('admin/config/regional/config-translation/node_form_display'); + $this->clickLink(t('Translate')); + + // Upload the document, which must succeed. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' uploaded successfully'); + + // Check that the upload succeeded. + $this->clickLink('Check upload status'); + $this->assertText(' status checked successfully'); + + // Edit the form display. + $this->drupalPostForm('/admin/structure/types/manage/article/form-display/default', [], t('Save')); + $this->assertText('Your settings have been saved.'); + + // Go back to the form. + $this->drupalGet('admin/config/regional/config-translation/node_form_display'); + $this->clickLink(t('Translate')); + + \Drupal::state()->set('lingotek.must_document_archived_error_in_update', TRUE); + + // Re-upload. Must fail now. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText('Document has been archived. Please upload again.'); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_UNTRACKED, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state()->set('lingotek.must_document_archived_error_in_update', FALSE); + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' uploaded successfully'); + } + + /** + * Test that we handle errors in update. + */ + public function testUpdatingWithADocumentLockedError() { + // Check that the translate tab is in the form display. + $this->drupalGet('/admin/config/regional/config-translation'); + $this->drupalGet('admin/config/regional/config-translation/node_form_display'); + $this->clickLink(t('Translate')); + + // Upload the document, which must succeed. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' uploaded successfully'); + + // Check that the upload succeeded. + $this->clickLink('Check upload status'); + $this->assertText(' status checked successfully'); + + // Edit the form display. + $this->drupalPostForm('/admin/structure/types/manage/article/form-display/default', [], t('Save')); + $this->assertText('Your settings have been saved.'); + + // Go back to the form. + $this->drupalGet('admin/config/regional/config-translation/node_form_display'); + $this->clickLink(t('Translate')); + + \Drupal::state()->set('lingotek.must_document_locked_error_in_update', TRUE); + + // Re-upload. Must fail now. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText('Document entity_form_display has a new version. The document id has been updated for all future interactions. Please try again.'); + + // The form display has been marked with the error status. + $formDisplay = EntityFormDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_EDITED, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state()->set('lingotek.must_document_locked_error_in_update', FALSE); + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' has been updated.'); + } + +} diff --git a/tests/src/Functional/LingotekContentViewDisplayTranslationTest.php b/tests/src/Functional/LingotekContentViewDisplayTranslationTest.php new file mode 100644 index 00000000..4d895b89 --- /dev/null +++ b/tests/src/Functional/LingotekContentViewDisplayTranslationTest.php @@ -0,0 +1,346 @@ +drupalPlaceBlock('page_title_block', ['region' => 'header', 'weight' => -5]); + $this->drupalPlaceBlock('local_tasks_block', [ + 'region' => 'header', + 'weight' => -10, + 'primary' => TRUE, + 'secondary' => TRUE, + ]); + + // Create content type. + $this->drupalCreateContentType([ + 'type' => 'article', + 'name' => 'Article', + ]); + + // Add a language. + ConfigurableLanguage::createFromLangcode('es')->setThirdPartySetting('lingotek', 'locale', 'es_MX')->save(); + } + + /** + * Tests that a node can be translated. + */ + public function testTranslation() { + // This is a hack for avoiding writing different lingotek endpoint mocks. + \Drupal::state()->set('lingotek.uploaded_content_type', 'content_view_display'); + + // Login as admin. + $this->drupalLogin($this->rootUser); + + $this->drupalGet('/admin/config/regional/config-translation'); + $this->drupalGet('admin/config/regional/config-translation/node_view_display'); + $this->clickLink(t('Translate')); + + $this->clickLink(t('Upload')); + // ToDo: Fix this. + // $this->assertText(t('Article Default view display uploaded successfully')); + $this->assertText(t(' uploaded successfully')); + + // Check that only the translatable fields have been uploaded. + $data = json_decode(\Drupal::state()->get('lingotek.uploaded_content', '[]'), TRUE); + $this->assertEqual(3, count($data)); + $this->assertTrue(array_key_exists('content.body.settings.placeholder', $data)); + // Cannot use isset, the key exists but we are not providing values, so NULL. + $this->assertTrue(array_key_exists('content.title.settings.placeholder', $data)); + $this->assertTrue(array_key_exists('content.uid.settings.placeholder', $data)); + + // Check that the profile used was the right one. + $used_profile = \Drupal::state()->get('lingotek.used_profile'); + $this->assertIdentical('automatic', $used_profile, 'The automatic profile was used.'); + + $this->clickLink(t('Check upload status')); + $this->assertText(t(' status checked successfully')); + + $this->clickLink(t('Request translation')); + $this->assertText(t('Translation to es_MX requested successfully')); + $this->assertIdentical('es_MX', \Drupal::state()->get('lingotek.added_target_locale')); + + $this->clickLink(t('Check Download')); + $this->assertText(t('Translation to es_MX status checked successfully')); + + $this->clickLink('Download'); + $this->assertText(t('Translation to es_MX downloaded successfully')); + + // Check that the edit link is there. + $basepath = \Drupal::request()->getBasePath(); + $this->assertLinkByHref($basepath . '/admin/structure/types/manage/article/display/default/translate/es/edit'); + + $this->drupalGet('/es/node/add/article'); + $placeholder = $this->xpath("//input[@placeholder='ES Titulo placeholder']"); + $this->assertCount(1, $placeholder); + } + + /** + * Test that we handle errors in upload. + */ + public function xxxtestUploadingWithAnError() { + \Drupal::state()->set('lingotek.must_error_in_upload', TRUE); + + // Check that the translate tab is in the form display. + $this->drupalGet('admin/config/regional/config-translation/node_view_display'); + $this->clickLink(t('Translate')); + + // Upload the document, which must fail. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' upload failed. Please try again.'); + + // The form display has been marked with the error status. + $formDisplay = EntityViewDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state()->set('lingotek.must_error_in_upload', FALSE); + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' uploaded successfully'); + } + + /** + * Test that we handle errors in upload. + */ + public function xxxtestUploadingWithAPaymentRequiredError() { + \Drupal::state()->set('lingotek.must_payment_required_error_in_upload', TRUE); + + // Check that the translate tab is in the form display. + $this->drupalGet('admin/config/regional/config-translation/node_view_display'); + $this->clickLink(t('Translate')); + + // Upload the document, which must fail. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText('Community has been disabled. Please contact support@lingotek.com to re-enable your community.'); + + // The form display has been marked with the error status. + $formDisplay = EntityViewDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state()->set('lingotek.must_payment_required_error_in_upload', FALSE); + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' uploaded successfully'); + } + + /** + * Test that we handle errors in upload. + */ + public function xxxtestUpdatingWithAPaymentRequiredError() { + // Check that the translate tab is in the form display. + $this->drupalGet('/admin/config/regional/config-translation'); + $this->drupalGet('admin/config/regional/config-translation/node_view_display'); + $this->clickLink(t('Translate')); + + // Upload the document, which must succeed. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' uploaded successfully'); + + // Check that the upload succeeded. + $this->clickLink('Check upload status'); + $this->assertText(' status checked successfully'); + + // Edit the form display. + $this->drupalPostForm('/admin/structure/types/manage/article/display/default', [], t('Save')); + $this->assertText('Your settings have been saved.'); + + // Go back to the form. + $this->drupalGet('admin/config/regional/config-translation/node_view_display'); + $this->clickLink(t('Translate')); + + \Drupal::state()->set('lingotek.must_payment_required_error_in_update', TRUE); + + // Re-upload. Must fail now. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText('Community has been disabled. Please contact support@lingotek.com to re-enable your community.'); + + // The form display has been marked with the error status. + $formDisplay = EntityViewDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state()->set('lingotek.must_payment_required_error_in_update', FALSE); + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' has been updated.'); + } + + /** + * Test that we handle errors in update. + */ + public function xxxtestUpdatingWithAnError() { + // Check that the translate tab is in the form display. + $this->drupalGet('/admin/config/regional/config-translation'); + $this->drupalGet('admin/config/regional/config-translation/node_view_display'); + $this->clickLink(t('Translate')); + + // Upload the document, which must succeed. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' uploaded successfully'); + + // Check that the upload succeeded. + $this->clickLink('Check upload status'); + $this->assertText(' status checked successfully'); + + // Edit the form display. + $this->drupalPostForm('/admin/structure/types/manage/article/display/default', [], t('Save')); + $this->assertText('Your settings have been saved.'); + + // Go back to the form. + $this->drupalGet('admin/config/regional/config-translation/node_view_display'); + $this->clickLink(t('Translate')); + + \Drupal::state()->set('lingotek.must_error_in_upload', TRUE); + + // Re-upload. Must fail now. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' update failed. Please try again.'); + + // The form display has been marked with the error status. + $formDisplay = EntityViewDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_ERROR, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state()->set('lingotek.must_error_in_upload', FALSE); + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' has been updated.'); + } + + /** + * Test that we handle errors in update. + */ + public function xxxtestUpdatingWithADocumentArchivedError() { + // Check that the translate tab is in the form display. + $this->drupalGet('/admin/config/regional/config-translation'); + $this->drupalGet('admin/config/regional/config-translation/node_view_display'); + $this->clickLink(t('Translate')); + + // Upload the document, which must succeed. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' uploaded successfully'); + + // Check that the upload succeeded. + $this->clickLink('Check upload status'); + $this->assertText(' status checked successfully'); + + // Edit the form display. + $this->drupalPostForm('/admin/structure/types/manage/article/display/default', [], t('Save')); + $this->assertText('Your settings have been saved.'); + + // Go back to the form. + $this->drupalGet('admin/config/regional/config-translation/node_view_display'); + $this->clickLink(t('Translate')); + + \Drupal::state()->set('lingotek.must_document_archived_error_in_update', TRUE); + + // Re-upload. Must fail now. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText('Document has been archived. Please upload again.'); + + // The form display has been marked with the error status. + $formDisplay = EntityViewDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_UNTRACKED, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state()->set('lingotek.must_document_archived_error_in_update', FALSE); + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' uploaded successfully'); + } + + /** + * Test that we handle errors in update. + */ + public function xxxtestUpdatingWithADocumentLockedError() { + // Check that the translate tab is in the form display. + $this->drupalGet('/admin/config/regional/config-translation'); + $this->drupalGet('admin/config/regional/config-translation/node_view_display'); + $this->clickLink(t('Translate')); + + // Upload the document, which must succeed. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' uploaded successfully'); + + // Check that the upload succeeded. + $this->clickLink('Check upload status'); + $this->assertText(' status checked successfully'); + + // Edit the form display. + $this->drupalPostForm('/admin/structure/types/manage/article/display/default', [], t('Save')); + $this->assertText('Your settings have been saved.'); + + // Go back to the form. + $this->drupalGet('admin/config/regional/config-translation/node_view_display'); + $this->clickLink(t('Translate')); + + \Drupal::state()->set('lingotek.must_document_locked_error_in_update', TRUE); + + // Re-upload. Must fail now. + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText('Document entity_view_display has a new version. The document id has been updated for all future interactions. Please try again.'); + + // The form display has been marked with the error status. + $formDisplay = EntityViewDisplay::load('node.article.default'); + /** @var \Drupal\lingotek\LingotekConfigTranslationServiceInterface $translation_service */ + $translation_service = \Drupal::service('lingotek.config_translation'); + $source_status = $translation_service->getSourceStatus($formDisplay); + $this->assertEqual(Lingotek::STATUS_EDITED, $source_status, 'The form display has been marked as error.'); + + // I can still re-try the upload. + \Drupal::state()->set('lingotek.must_document_locked_error_in_update', FALSE); + $this->clickLink('Upload'); + $this->checkForMetaRefresh(); + $this->assertText(' has been updated.'); + } + +}