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