BlockLanguageTest.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <?php
  2. namespace Drupal\Tests\block\Functional;
  3. use Drupal\Tests\BrowserTestBase;
  4. use Drupal\block\Entity\Block;
  5. /**
  6. * Tests if a block can be configured to be only visible on a particular
  7. * language.
  8. *
  9. * @group block
  10. */
  11. class BlockLanguageTest extends BrowserTestBase {
  12. /**
  13. * An administrative user to configure the test environment.
  14. */
  15. protected $adminUser;
  16. /**
  17. * Modules to install.
  18. *
  19. * @var array
  20. */
  21. public static $modules = ['language', 'block', 'content_translation'];
  22. protected function setUp() {
  23. parent::setUp();
  24. // Create a new user, allow him to manage the blocks and the languages.
  25. $this->adminUser = $this->drupalCreateUser(['administer blocks', 'administer languages']);
  26. $this->drupalLogin($this->adminUser);
  27. // Add predefined language.
  28. $edit = [
  29. 'predefined_langcode' => 'fr',
  30. ];
  31. $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
  32. $this->assertText('French', 'Language added successfully.');
  33. }
  34. /**
  35. * Tests the visibility settings for the blocks based on language.
  36. */
  37. public function testLanguageBlockVisibility() {
  38. // Check if the visibility setting is available.
  39. $default_theme = $this->config('system.theme')->get('default');
  40. $this->drupalGet('admin/structure/block/add/system_powered_by_block' . '/' . $default_theme);
  41. $this->assertField('visibility[language][langcodes][en]', 'Language visibility field is visible.');
  42. $this->assertNoField('visibility[language][context_mapping][language]', 'Language type field is not visible.');
  43. // Enable a standard block and set the visibility setting for one language.
  44. $edit = [
  45. 'visibility[language][langcodes][en]' => TRUE,
  46. 'id' => strtolower($this->randomMachineName(8)),
  47. 'region' => 'sidebar_first',
  48. ];
  49. $this->drupalPostForm('admin/structure/block/add/system_powered_by_block' . '/' . $default_theme, $edit, t('Save block'));
  50. // Change the default language.
  51. $edit = [
  52. 'site_default_language' => 'fr',
  53. ];
  54. $this->drupalPostForm('admin/config/regional/language', $edit, t('Save configuration'));
  55. // Check that a page has a block.
  56. $this->drupalGet('en');
  57. $this->assertText('Powered by Drupal', 'The body of the custom block appears on the page.');
  58. // Check that a page doesn't has a block for the current language anymore.
  59. $this->drupalGet('fr');
  60. $this->assertNoText('Powered by Drupal', 'The body of the custom block does not appear on the page.');
  61. }
  62. /**
  63. * Tests if the visibility settings are removed if the language is deleted.
  64. */
  65. public function testLanguageBlockVisibilityLanguageDelete() {
  66. // Enable a standard block and set the visibility setting for one language.
  67. $edit = [
  68. 'visibility' => [
  69. 'language' => [
  70. 'langcodes' => [
  71. 'fr' => 'fr',
  72. ],
  73. 'context_mapping' => ['language' => '@language.current_language_context:language_interface'],
  74. ],
  75. ],
  76. ];
  77. $block = $this->drupalPlaceBlock('system_powered_by_block', $edit);
  78. // Check that we have the language in config after saving the setting.
  79. $visibility = $block->getVisibility();
  80. $this->assertEqual('fr', $visibility['language']['langcodes']['fr'], 'Language is set in the block configuration.');
  81. // Delete the language.
  82. $this->drupalPostForm('admin/config/regional/language/delete/fr', [], t('Delete'));
  83. // Check that the language is no longer stored in the configuration after
  84. // it is deleted.
  85. $block = Block::load($block->id());
  86. $visibility = $block->getVisibility();
  87. $this->assertTrue(empty($visibility['language']['langcodes']['fr']), 'Language is no longer not set in the block configuration after deleting the block.');
  88. // Ensure that the block visibility for language is gone from the UI.
  89. $this->drupalGet('admin/structure/block');
  90. $this->clickLink('Configure');
  91. $elements = $this->xpath('//details[@id="edit-visibility-language"]');
  92. $this->assertTrue(empty($elements));
  93. }
  94. /**
  95. * Tests block language visibility with different language types.
  96. */
  97. public function testMultipleLanguageTypes() {
  98. // Customize content language detection to be different from interface
  99. // language detection.
  100. $edit = [
  101. // Interface language detection: only using session.
  102. 'language_interface[enabled][language-url]' => FALSE,
  103. 'language_interface[enabled][language-session]' => TRUE,
  104. // Content language detection: only using URL.
  105. 'language_content[configurable]' => TRUE,
  106. 'language_content[enabled][language-url]' => TRUE,
  107. 'language_content[enabled][language-interface]' => FALSE,
  108. ];
  109. $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
  110. // Check if the visibility setting is available with a type setting.
  111. $default_theme = $this->config('system.theme')->get('default');
  112. $this->drupalGet('admin/structure/block/add/system_powered_by_block' . '/' . $default_theme);
  113. $this->assertField('visibility[language][langcodes][en]', 'Language visibility field is visible.');
  114. $this->assertField('visibility[language][context_mapping][language]', 'Language type field is visible.');
  115. // Enable a standard block and set visibility to French only.
  116. $block_id = strtolower($this->randomMachineName(8));
  117. $edit = [
  118. 'visibility[language][context_mapping][language]' => '@language.current_language_context:language_interface',
  119. 'visibility[language][langcodes][fr]' => TRUE,
  120. 'id' => $block_id,
  121. 'region' => 'sidebar_first',
  122. ];
  123. $this->drupalPostForm('admin/structure/block/add/system_powered_by_block' . '/' . $default_theme, $edit, t('Save block'));
  124. // Interface negotiation depends on request arguments.
  125. $this->drupalGet('node', ['query' => ['language' => 'en']]);
  126. $this->assertNoText('Powered by Drupal', 'The body of the block does not appear on the page.');
  127. $this->drupalGet('node', ['query' => ['language' => 'fr']]);
  128. $this->assertText('Powered by Drupal', 'The body of the block appears on the page.');
  129. // Log in again in order to clear the interface language stored in the
  130. // session.
  131. $this->drupalLogout();
  132. $this->drupalLogin($this->adminUser);
  133. // Content language does not depend on session/request arguments.
  134. // It will fall back on English (site default) and not display the block.
  135. $this->drupalGet('en');
  136. $this->assertNoText('Powered by Drupal', 'The body of the block does not appear on the page.');
  137. $this->drupalGet('fr');
  138. $this->assertNoText('Powered by Drupal', 'The body of the block does not appear on the page.');
  139. // Change visibility to now depend on content language for this block.
  140. $edit = [
  141. 'visibility[language][context_mapping][language]' => '@language.current_language_context:language_content',
  142. ];
  143. $this->drupalPostForm('admin/structure/block/manage/' . $block_id, $edit, t('Save block'));
  144. // Content language negotiation does not depend on request arguments.
  145. // It will fall back on English (site default) and not display the block.
  146. $this->drupalGet('node', ['query' => ['language' => 'en']]);
  147. $this->assertNoText('Powered by Drupal', 'The body of the block does not appear on the page.');
  148. $this->drupalGet('node', ['query' => ['language' => 'fr']]);
  149. $this->assertNoText('Powered by Drupal', 'The body of the block does not appear on the page.');
  150. // Content language negotiation depends on path prefix.
  151. $this->drupalGet('en');
  152. $this->assertNoText('Powered by Drupal', 'The body of the block does not appear on the page.');
  153. $this->drupalGet('fr');
  154. $this->assertText('Powered by Drupal', 'The body of the block appears on the page.');
  155. }
  156. }