Updated all the contrib modules to their latest versions.
[yaffs-website] / web / modules / contrib / metatag / src / Tests / MetatagTagsTestBase.php
1 <?php
2
3 namespace Drupal\metatag\Tests;
4
5 use Drupal\Component\Render\FormattableMarkup;
6 use Drupal\simpletest\WebTestBase;
7 use Symfony\Component\DependencyInjection\Container;
8
9 /**
10  * Base class to test all of the meta tags that are in a specific module.
11  */
12 abstract class MetatagTagsTestBase extends WebTestBase {
13
14   use MetatagHelperTrait;
15
16   /**
17    * {@inheritdoc}
18    */
19   public static $modules = [
20     // This is needed for the 'access content' permission.
21     'node',
22
23     // Dependencies.
24     'token',
25
26     // Metatag itself.
27     'metatag',
28
29     // This module will be used to load a static page which will inherit the
30     // global defaults, without loading values from other configs.
31     'metatag_test_custom_route',
32   ];
33
34   /**
35    * All of the meta tags defined by this module which will be tested.
36    *
37    * @var array
38    */
39   private $tags = [];
40
41   /**
42    * The tag to look for when testing the output.
43    *
44    * @var string
45    */
46   private $testTag = 'meta';
47
48   /**
49    * {@inheritdoc}
50    *
51    * @var string
52    */
53   private $testNameAttribute = 'name';
54
55   /**
56    * The attribute to look for when testing the output.
57    *
58    * @var string
59    */
60   private $testValueAttribute = 'content';
61
62   /**
63    * {@inheritdoc}
64    */
65   protected function setUp() {
66     parent::setUp();
67
68     // Use the test page as the front page.
69     $this->config('system.site')->set('page.front', '/test-page')->save();
70
71     // Initiate session with a user who can manage meta tags and access content.
72     $permissions = [
73       'administer site configuration',
74       'administer meta tags',
75       'access content',
76     ];
77     $account = $this->drupalCreateUser($permissions);
78     $this->drupalLogin($account);
79   }
80
81   /**
82    * Tests that this module's tags are available.
83    */
84   public function testTagsArePresent() {
85     // Load the global config.
86     $this->drupalGet('admin/config/search/metatag/global');
87     $this->assertResponse(200);
88
89     // Confirm the various meta tags are available.
90     foreach ($this->tags as $tag) {
91       // Look for a custom method named "{$tagname}TestFieldXpath", if found
92       // use that method to get the xpath definition for this meta tag,
93       // otherwise it defaults to just looking for a text input field.
94       $method = $this->getMethodFromTagCallback($tag, 'test_field_xpath');
95       if (method_exists($this, $method)) {
96         $xpath = $this->$method();
97       }
98       else {
99         $xpath = "//input[@name='{$tag}' and @type='text']";
100       }
101
102       $this->assertFieldByXPath($xpath, NULL, new FormattableMarkup('Found the @tag meta tag field.', ['@tag' => $tag]));
103     }
104
105     $this->drupalLogout();
106   }
107
108   /**
109    * Confirm that each tag can be saved and that the output is correct.
110    */
111   public function testTagsInputOutput() {
112     // Create a content type to test with.
113     $this->createContentType(['type' => 'page']);
114     $this->drupalCreateNode([
115       'title' => t('Hello, world!'),
116       'type' => 'page',
117     ]);
118
119     // Test a non-entity path and an entity path. The non-entity path inherits
120     // the global meta tags, the entity path inherits from its entity config.
121     $paths = [
122       [
123         'admin/config/search/metatag/global',
124         'metatag_test_custom_route',
125         'Saved the Global Metatag defaults.',
126       ],
127       [
128         'admin/config/search/metatag/node',
129         'node/1',
130         'Saved the Content Metatag defaults',
131       ],
132     ];
133
134     foreach ($paths as $item) {
135       list($path1, $path2, $save_message) = $item;
136
137       // Load the global config.
138       $this->drupalGet($path1);
139       $this->assertResponse(200);
140
141       // Update the Global defaults and test them.
142       $all_values = $values = [];
143       foreach ($this->tags as $tag_name) {
144         // Look for a custom method named "{$tagname}TestKey", if found use
145         // that method to get the test string for this meta tag, otherwise it
146         // defaults to the meta tag's name.
147         $method = $this->getMethodFromTagCallback($tag_name, 'TestKey');
148         if (method_exists($this, $method)) {
149           $test_key = $this->$method();
150         }
151         else {
152           $test_key = $tag_name;
153         }
154
155         // Look for a custom method named "{$tagname}TestValue", if found use
156         // that method to get the test string for this meta tag, otherwise it
157         // defaults to just generating a random string.
158         $method = $this->getMethodFromTagCallback($tag_name, 'TestValue');
159         if (method_exists($this, $method)) {
160           $test_value = $this->$method();
161         }
162         else {
163           // Generate a random string. Generating two words of 8 characters each
164           // with simple machine name -style strings.
165           $test_value = $this->randomMachineName() . ' ' . $this->randomMachineName();
166         }
167
168         $values[$test_key] = $test_value;
169         $all_values[$tag_name] = $test_value;
170       }
171       $this->drupalPostForm(NULL, $values, 'Save');
172       $this->assertText($save_message);
173
174       // Load the test page.
175       $this->drupalGet($path2);
176       $this->assertResponse(200);
177
178       // Look for the values.
179       foreach ($this->tags as $tag_name) {
180         // Look for a custom method named "{$tag_name}TestOutputXpath", if
181         // found use that method to get the xpath definition for this meta tag,
182         // otherwise it defaults to just looking for a meta tag matching:
183         // <$testTag $testNameAttribute=$tag_name $testValueAttribute=$value />
184         $method = $this->getMethodFromTagCallback($tag_name, 'TestOutputXpath');
185         if (method_exists($this, $method)) {
186           $xpath_string = $this->$method();
187         }
188         else {
189           // Look for a custom method named "{$tag_name}TestTag", if
190           // found use that method to get the xpath definition for this meta
191           // tag, otherwise it defaults to $this->testTag.
192           $method = $this->getMethodFromTagCallback($tag_name, 'TestTag');
193           if (method_exists($this, $method)) {
194             $xpath_tag = $this->$method();
195           }
196           else {
197             $xpath_tag = $this->testTag;
198           }
199
200           // Look for a custom method named "{$tag_name}TestNameAttribute",
201           // if found use that method to get the xpath definition for this meta
202           // tag, otherwise it defaults to $this->testNameAttribute.
203           $method = $this->getMethodFromTagCallback($tag_name, 'TestNameAttribute');
204           if (method_exists($this, $method)) {
205             $xpath_name_attribute = $this->$method();
206           }
207           else {
208             $xpath_name_attribute = $this->testNameAttribute;
209           }
210
211           // Look for a custom method named "{$tag_name}TestTagName", if
212           // found use that method to get the xpath definition for this meta
213           // tag, otherwise it defaults to $tag_name.
214           $method = $this->getMethodFromTagCallback($tag_name, 'TestTagName');
215           if (method_exists($this, $method)) {
216             $xpath_name_tag = $this->$method();
217           }
218           else {
219             $xpath_name_tag = $this->getTestTagName($tag_name);
220           }
221
222           // Compile the xpath.
223           $xpath_string = "//{$xpath_tag}[@{$xpath_name_attribute}='{$xpath_name_tag}']";
224         }
225
226         // Look for a custom method named "{$tag_name}TestValueAttribute", if
227         // found use that method to get the xpath definition for this meta tag,
228         // otherwise it defaults to $this->testValueAttribute.
229         $method = $this->getMethodFromTagCallback($tag_name, 'TestValueAttribute');
230         if (method_exists($this, $method)) {
231           $xpath_value_attribute = $this->$method();
232         }
233         else {
234           $xpath_value_attribute = $this->testValueAttribute;
235         }
236
237         // Extract the meta tag from the HTML.
238         $xpath = $this->xpath($xpath_string);
239         $this->assertEqual(count($xpath), 1, new FormattableMarkup('One @name tag found.', ['@name' => $tag_name]));
240         if (count($xpath) !== 1) {
241           $this->verbose($xpath, $tag_name . ': ' . $xpath_string);
242         }
243
244         // Run various tests on the output variables.
245         // Most meta tags have an attribute, but some don't.
246         if (!empty($xpath_value_attribute)) {
247           $this->assertTrue($xpath_value_attribute);
248           $this->assertTrue(isset($xpath[0][$xpath_value_attribute]));
249           // Help with debugging.
250           if (!isset($xpath[0][$xpath_value_attribute])) {
251             $this->verbose($xpath, $tag_name . ': ' . $xpath_string);
252           }
253           else {
254             if ((string) $xpath[0][$xpath_value_attribute] != $all_values[$tag_name]) {
255               $this->verbose($xpath, $tag_name . ': ' . $xpath_string);
256             }
257             $this->assertTrue($xpath[0][$xpath_value_attribute]);
258             $this->assertEqual($xpath[0][$xpath_value_attribute], $all_values[$tag_name], "The meta tag was found with the expected value.");
259           }
260         }
261         else {
262           $this->verbose($xpath, $tag_name . ': ' . $xpath_string);
263           $this->assertTrue((string) $xpath[0]);
264           $this->assertEqual((string) $xpath[0], $all_values[$tag_name], "The meta tag was found with the expected value.");
265         }
266       }
267     }
268
269     $this->drupalLogout();
270   }
271
272   /**
273    * Convert a tag's internal name to the string which is actually used in HTML.
274    *
275    * The meta tag internal name will be machine names, i.e. only contain a-z,
276    * A-Z, 0-9 and the underline character. Meta tag names will actually contain
277    * any possible character.
278    *
279    * @param string $tag_name
280    *   The tag name to be converted.
281    *
282    * @return string
283    *   The converted tag name.
284    */
285   private function getTestTagName($tag_name) {
286     return $tag_name;
287   }
288
289   /**
290    * Generate a random value for testing meta tag fields.
291    *
292    * As a reasonable default, this will generating two words of 8 characters
293    * each with simple machine name -style strings.
294    *
295    * @return string
296    *   A normal string.
297    */
298   private function getTestTagValue() {
299     return $this->randomMachineName() . ' ' . $this->randomMachineName();
300   }
301
302   /**
303    * Generate a URL for an image.
304    *
305    * @return string
306    *   An absolute URL to a non-existent image.
307    */
308   private function randomImageUrl() {
309     return 'http://www.example.com/images/' . $this->randomMachineName() . '.png';
310   }
311
312   /**
313    * Convert a tag name with a callback to a lowerCamelCase method name.
314    *
315    * @param string $tag_name
316    *   The meta tag name.
317    * @param string $callback
318    *   The callback that is to be used.
319    *
320    * @return string
321    *   The tag name and callback concatenated together and converted to
322    *   lowerCamelCase.
323    */
324   private function getMethodFromTagCallback($tag_name, $callback) {
325     return lcfirst(Container::camelize($tag_name . '_' . $callback));
326   }
327
328 }