Further Drupal 8.6.4 changes. Some core files were not committed before a commit...
[yaffs-website] / web / core / modules / system / tests / src / Functional / Theme / ThemeSuggestionsAlterTest.php
1 <?php
2
3 namespace Drupal\Tests\system\Functional\Theme;
4
5 use Drupal\Component\Utility\Xss;
6 use Drupal\Tests\BrowserTestBase;
7
8 /**
9  * Tests theme suggestion alter hooks.
10  *
11  * @group Theme
12  */
13 class ThemeSuggestionsAlterTest extends BrowserTestBase {
14
15   /**
16    * Modules to enable.
17    *
18    * @var array
19    */
20   public static $modules = ['theme_test'];
21
22   protected function setUp() {
23     parent::setUp();
24     \Drupal::service('theme_handler')->install(['test_theme']);
25   }
26
27   /**
28    * Tests that hooks to provide theme suggestions work.
29    */
30   public function testTemplateSuggestions() {
31     $this->drupalGet('theme-test/suggestion-provided');
32     $this->assertText('Template for testing suggestions provided by the module declaring the theme hook.');
33
34     // Install test_theme, it contains a template suggested by theme_test.module
35     // in theme_test_theme_suggestions_theme_test_suggestion_provided().
36     $this->config('system.theme')
37       ->set('default', 'test_theme')
38       ->save();
39
40     $this->drupalGet('theme-test/suggestion-provided');
41     $this->assertText('Template overridden based on suggestion provided by the module declaring the theme hook.');
42   }
43
44   /**
45    * Tests hook_theme_suggestions_alter().
46    */
47   public function testGeneralSuggestionsAlter() {
48     $this->drupalGet('theme-test/general-suggestion-alter');
49     $this->assertText('Original template for testing hook_theme_suggestions_alter().');
50
51     // Install test_theme and test that themes can alter template suggestions.
52     $this->config('system.theme')
53       ->set('default', 'test_theme')
54       ->save();
55     $this->drupalGet('theme-test/general-suggestion-alter');
56     $this->assertText('Template overridden based on new theme suggestion provided by the test_theme theme via hook_theme_suggestions_alter().');
57
58     // Enable the theme_suggestions_test module to test modules implementing
59     // suggestions alter hooks.
60     \Drupal::service('module_installer')->install(['theme_suggestions_test']);
61     $this->resetAll();
62     $this->drupalGet('theme-test/general-suggestion-alter');
63     $this->assertText('Template overridden based on new theme suggestion provided by a module via hook_theme_suggestions_alter().');
64   }
65
66   /**
67    * Tests that theme suggestion alter hooks work for templates.
68    */
69   public function testTemplateSuggestionsAlter() {
70     $this->drupalGet('theme-test/suggestion-alter');
71     $this->assertText('Original template for testing hook_theme_suggestions_HOOK_alter().');
72
73     // Install test_theme and test that themes can alter template suggestions.
74     $this->config('system.theme')
75       ->set('default', 'test_theme')
76       ->save();
77     $this->drupalGet('theme-test/suggestion-alter');
78     $this->assertText('Template overridden based on new theme suggestion provided by the test_theme theme via hook_theme_suggestions_HOOK_alter().');
79
80     // Enable the theme_suggestions_test module to test modules implementing
81     // suggestions alter hooks.
82     \Drupal::service('module_installer')->install(['theme_suggestions_test']);
83     $this->resetAll();
84     $this->drupalGet('theme-test/suggestion-alter');
85     $this->assertText('Template overridden based on new theme suggestion provided by a module via hook_theme_suggestions_HOOK_alter().');
86   }
87
88   /**
89    * Tests that theme suggestion alter hooks work for specific theme calls.
90    */
91   public function testSpecificSuggestionsAlter() {
92     // Test that the default template is rendered.
93     $this->drupalGet('theme-test/specific-suggestion-alter');
94     $this->assertText('Template for testing specific theme calls.');
95
96     $this->config('system.theme')
97       ->set('default', 'test_theme')
98       ->save();
99
100     // Test a specific theme call similar to '#theme' => 'node__article'.
101     $this->drupalGet('theme-test/specific-suggestion-alter');
102     $this->assertText('Template matching the specific theme call.');
103     $this->assertText('theme_test_specific_suggestions__variant', 'Specific theme call is added to the suggestions array.');
104
105     // Ensure that the base hook is used to determine the suggestion alter hook.
106     \Drupal::service('module_installer')->install(['theme_suggestions_test']);
107     $this->resetAll();
108     $this->drupalGet('theme-test/specific-suggestion-alter');
109     $this->assertText('Template overridden based on suggestion alter hook determined by the base hook.');
110     $raw_content = $this->getSession()->getPage()->getContent();
111     $this->assertTrue(strpos($raw_content, 'theme_test_specific_suggestions__variant') < strpos($raw_content, 'theme_test_specific_suggestions__variant__foo'), 'Specific theme call is added to the suggestions array before the suggestions alter hook.');
112   }
113
114   /**
115    * Tests that theme suggestion alter hooks work for theme functions.
116    */
117   public function testThemeFunctionSuggestionsAlter() {
118     $this->drupalGet('theme-test/function-suggestion-alter');
119     $this->assertText('Original theme function.');
120
121     // Install test_theme and test that themes can alter theme suggestions.
122     $this->config('system.theme')
123       ->set('default', 'test_theme')
124       ->save();
125     $this->drupalGet('theme-test/function-suggestion-alter');
126     $this->assertText('Theme function overridden based on new theme suggestion provided by the test_theme theme.');
127
128     // Enable the theme_suggestions_test module to test modules implementing
129     // suggestions alter hooks.
130     \Drupal::service('module_installer')->install(['theme_suggestions_test']);
131     $this->resetAll();
132     $this->drupalGet('theme-test/function-suggestion-alter');
133     $this->assertText('Theme function overridden based on new theme suggestion provided by a module.');
134   }
135
136   /**
137    * Tests that theme suggestion alter hooks work with theme hook includes.
138    */
139   public function testSuggestionsAlterInclude() {
140     // Check the original theme output.
141     $this->drupalGet('theme-test/suggestion-alter-include');
142     $this->assertText('Original function before altering theme suggestions.');
143
144     // Enable theme_suggestions_test module and make two requests to make sure
145     // the include file is always loaded. The file will always be included for
146     // the first request because the theme registry is being rebuilt.
147     \Drupal::service('module_installer')->install(['theme_suggestions_test']);
148     $this->resetAll();
149     $this->drupalGet('theme-test/suggestion-alter-include');
150     $this->assertText('Function suggested via suggestion alter hook found in include file.', 'Include file loaded for initial request.');
151     $this->drupalGet('theme-test/suggestion-alter-include');
152     $this->assertText('Function suggested via suggestion alter hook found in include file.', 'Include file loaded for second request.');
153   }
154
155   /**
156    * Tests execution order of theme suggestion alter hooks.
157    *
158    * Hook hook_theme_suggestions_alter() should fire before
159    * hook_theme_suggestions_HOOK_alter() within an extension (module or theme).
160    */
161   public function testExecutionOrder() {
162     // Install our test theme and module.
163     $this->config('system.theme')
164       ->set('default', 'test_theme')
165       ->save();
166     \Drupal::service('module_installer')->install(['theme_suggestions_test']);
167     $this->resetAll();
168
169     // Send two requests so that we get all the messages we've set via
170     // \Drupal\Core\Messenger\MessengerInterface::addStatus().
171     $this->drupalGet('theme-test/suggestion-alter');
172     // Ensure that the order is first by extension, then for a given extension,
173     // the hook-specific one after the generic one.
174     $expected_order = [
175       'theme_suggestions_test_theme_suggestions_alter() executed.',
176       'theme_suggestions_test_theme_suggestions_theme_test_suggestions_alter() executed.',
177       'theme_test_theme_suggestions_alter() executed for theme_test_suggestions.',
178       'theme_test_theme_suggestions_theme_test_suggestions_alter() executed.',
179       'test_theme_theme_suggestions_alter() executed.',
180       'test_theme_theme_suggestions_theme_test_suggestions_alter() executed.',
181     ];
182     $content = preg_replace('/\s+/', ' ', Xss::filter($this->getSession()->getPage()->getContent(), []));
183     $order = 0;
184     foreach ($expected_order as $expected_string) {
185       $this->assertGreaterThan($order, strpos($content, $expected_string));
186       $order = strpos($content, $expected_string);
187     }
188   }
189
190 }