‪TYPO3CMS  11.5
HrefLangGeneratorTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
22 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerFactory;
23 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerWriter;
24 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
25 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
26 
27 class ‪HrefLangGeneratorTest extends FunctionalTestCase
28 {
30 
31  protected ‪$coreExtensionsToLoad = ['seo'];
32 
36  protected const ‪LANGUAGE_PRESETS = [
37  'EN' => ['id' => 0, 'title' => 'English', 'locale' => 'en_US.UTF8', 'iso' => 'en', 'hrefLang' => 'en-US', 'direction' => ''],
38  'DE' => ['id' => 1, 'title' => 'German', 'locale' => 'de_DE.UTF8', 'iso' => 'de', 'hrefLang' => 'de-DE', 'direction' => ''],
39  'DE-CH' => ['id' => 2, 'title' => 'Swiss German', 'locale' => 'de_CH.UTF8', 'iso' => 'de', 'hrefLang' => 'de-CH', 'direction' => ''],
40  'NL' => ['id' => 3, 'title' => 'Dutch', 'locale' => 'nl_NL.UTF8', 'iso' => 'nl', 'hrefLang' => '', 'direction' => ''],
41  'FR' => ['id' => 4, 'title' => 'French', 'locale' => 'fr_FR.UTF8', 'iso' => 'fr', 'hrefLang' => 'fr-FR', 'direction' => ''],
42  'DK' => ['id' => 5, 'title' => 'Danish', 'locale' => 'da_DK.UTF8', 'iso' => 'da', 'hrefLang' => 'da-DK', 'direction' => ''],
43  ];
44 
45  protected function ‪setUp(): void
46  {
47  parent::setUp();
48 
50  'acme-com',
51  $this->‪buildSiteConfiguration(1000, 'https://acme.com/'),
52  [
53  $this->‪buildDefaultLanguageConfiguration('EN', '/'),
54  $this->‪buildLanguageConfiguration('DE', '/de'),
55  $this->‪buildLanguageConfiguration('DE-CH', '/de-ch', ['DE'], 'fallback'),
56  $this->‪buildLanguageConfiguration('NL', '/nl'),
57  $this->‪buildLanguageConfiguration('FR', '/fr'),
58  $this->‪buildLanguageConfiguration('DK', '/dk', ['EN'], 'free'),
59  ]
60  );
61 
62  $this->‪setUpDatabaseWithYamlPayload(__DIR__ . '/../Fixtures/HrefLangScenario.yml');
63  }
64 
69  public function ‪checkHrefLangOutput(string $url, array $expectedTags, array $notExpectedTags): void
70  {
71  $this->setUpFrontendRootPage(
72  1000,
73  ['typo3/sysext/seo/Tests/Functional/Fixtures/HrefLang.typoscript']
74  );
75 
76  $response = $this->executeFrontendSubRequest(
77  new InternalRequest($url)
78  );
79  $stream = $response->getBody();
80  $stream->rewind();
81  $content = $stream->getContents();
82 
83  foreach ($expectedTags as $expectedTag) {
84  self::assertStringContainsString($expectedTag, $content);
85  }
86 
87  foreach ($notExpectedTags as $notExpectedTag) {
88  self::assertStringNotContainsString($notExpectedTag, $content);
89  }
90  }
91 
95  public function ‪checkHrefLangOutputDataProvider(): array
96  {
97  return [
98  'No translation available, so only hreflang tags expected for default language and fallback languages' => [
99  'https://acme.com/',
100  [
101  '<link rel="alternate" hreflang="en-US" href="https://acme.com/"/>',
102  '<link rel="alternate" hreflang="de-CH" href="https://acme.com/de-ch/"/>',
103  ],
104  [
105  '<link rel="alternate" hreflang="de-DE"',
106  ],
107  ],
108  'English page, with German translation' => [
109  'https://acme.com/hello',
110  [
111  '<link rel="alternate" hreflang="en-US" href="https://acme.com/hello"/>',
112  '<link rel="alternate" hreflang="de-DE" href="https://acme.com/de/willkommen"/>',
113  '<link rel="alternate" hreflang="x-default" href="https://acme.com/hello"/>',
114  ],
115  [],
116  ],
117  'German page, with English translation and English default' => [
118  'https://acme.com/de/willkommen',
119  [
120  '<link rel="alternate" hreflang="en-US" href="https://acme.com/hello"/>',
121  '<link rel="alternate" hreflang="de-DE" href="https://acme.com/de/willkommen"/>',
122  '<link rel="alternate" hreflang="x-default" href="https://acme.com/hello"/>',
123  ],
124  [],
125  ],
126  'English page, with German and Dutch translation, without Dutch hreflang config' => [
127  'https://acme.com/hello',
128  [
129  '<link rel="alternate" hreflang="en-US" href="https://acme.com/hello"/>',
130  '<link rel="alternate" hreflang="de-DE" href="https://acme.com/de/willkommen"/>',
131  '<link rel="alternate" hreflang="x-default" href="https://acme.com/hello"/>',
132  ],
133  [
134  '<link rel="alternate" hreflang="en-US" href="https://acme.com/nl/welkom"/>',
135  '<link rel="alternate" hreflang="" href="https://acme.com/nl/welkom"/>',
136  ],
137  ],
138  'Dutch page, with German and English translation, without Dutch hreflang config' => [
139  'https://acme.com/hello',
140  [
141  '<link rel="alternate" hreflang="en-US" href="https://acme.com/hello"/>',
142  '<link rel="alternate" hreflang="de-DE" href="https://acme.com/de/willkommen"/>',
143  '<link rel="alternate" hreflang="x-default" href="https://acme.com/hello"/>',
144  ],
145  [
146  '<link rel="alternate" hreflang="en-US" href="https://acme.com/nl/welkom"/>',
147  '<link rel="alternate" hreflang="" href="https://acme.com/nl/welkom"/>',
148  ],
149  ],
150  'English page with canonical' => [
151  'https://acme.com/contact',
152  [
153  '<link rel="alternate" hreflang="de-DE" href="https://acme.com/de/kontakt"/>',
154  '<link rel="alternate" hreflang="de-CH" href="https://acme.com/de-ch/kontakt"/>',
155  ],
156  [
157  '<link rel="alternate" hreflang="en-US" href="https://acme.com/contact"/>',
158  '<link rel="alternate" hreflang="x-default" href="https://acme.com/contact"/>',
159  ],
160  ],
161  'Swiss german page with canonical' => [
162  'https://acme.com/de-ch/uber',
163  [
164  '<link rel="alternate" hreflang="en-US" href="https://acme.com/about"/>',
165  '<link rel="alternate" hreflang="x-default" href="https://acme.com/about"/>',
166  '<link rel="alternate" hreflang="de-DE" href="https://acme.com/de/uber"/>',
167  ],
168  [
169  '<link rel="alternate" hreflang="de-CH" href="https://acme.com/de-ch/uber"/>',
170  ],
171  ],
172  'Swiss german page with fallback to German, without content' => [
173  'https://acme.com/de-ch/produkte',
174  [
175  '<link rel="alternate" hreflang="en-US" href="https://acme.com/products"/>',
176  '<link rel="alternate" hreflang="x-default" href="https://acme.com/products"/>',
177  '<link rel="alternate" hreflang="de-DE" href="https://acme.com/de/produkte"/>',
178  '<link rel="alternate" hreflang="de-CH" href="https://acme.com/de-ch/produkte"/>',
179  ],
180  [],
181  ],
182  'Languages with fallback should have hreflang even when page record is not translated, strict languages without translations shouldnt' => [
183  'https://acme.com/hello',
184  [
185  '<link rel="alternate" hreflang="de-CH" href="https://acme.com/de-ch/willkommen"/>',
186  ],
187  [
188  '<link rel="alternate" hreflang="fr-FR"',
189  ],
190  ],
191  'Pages with disabled hreflang generation should not render any hreflang tag' => [
192  'https://acme.com/no-hreflang',
193  [],
194  [
195  '<link rel="alternate" hreflang="',
196  ],
197  ],
198  'Translated pages with disabled hreflang generation in original language should not render any hreflang tag' => [
199  'https://acme.com/de/kein-hreflang',
200  [],
201  [
202  '<link rel="alternate" hreflang="',
203  ],
204  ],
205  'Languages with fallback type free should not have hreflang when page record is not translated' => [
206  'https://acme.com/no-translation',
207  [],
208  [
209  '<link rel="alternate" hreflang="',
210  ],
211  ],
212  ];
213  }
214 
219  protected function ‪setUpDatabaseWithYamlPayload(string $pathToYamlFile): void
220  {
221  $this->withDatabaseSnapshot(function () use ($pathToYamlFile) {
222  $backendUser = $this->setUpBackendUserFromFixture(1);
224 
225  $factory = DataHandlerFactory::fromYamlFile($pathToYamlFile);
226  $writer = DataHandlerWriter::withBackendUser($backendUser);
227  $writer->invokeFactory($factory);
228  static::failIfArrayIsNotEmpty(
229  $writer->getErrors()
230  );
231  });
232  }
233 
237  protected static function ‪failIfArrayIsNotEmpty(array $items): void
238  {
239  if (empty($items)) {
240  return;
241  }
242 
243  self::fail(
244  'Array was not empty as expected, but contained these items:' . LF
245  . '* ' . implode(LF . '* ', $items)
246  );
247  }
248 }
‪TYPO3\CMS\Seo\Tests\Functional\HrefLang\HrefLangGeneratorTest\LANGUAGE_PRESETS
‪const LANGUAGE_PRESETS
Definition: HrefLangGeneratorTest.php:35
‪TYPO3\CMS\Seo\Tests\Functional\HrefLang\HrefLangGeneratorTest
Definition: HrefLangGeneratorTest.php:28
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait
Definition: SiteBasedTestTrait.php:36
‪TYPO3\CMS\Seo\Tests\Functional\HrefLang\HrefLangGeneratorTest\$coreExtensionsToLoad
‪$coreExtensionsToLoad
Definition: HrefLangGeneratorTest.php:30
‪TYPO3\CMS\Seo\Tests\Functional\HrefLang
Definition: HrefLangGeneratorTest.php:18
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildLanguageConfiguration
‪array buildLanguageConfiguration(string $identifier, string $base, array $fallbackIdentifiers=[], string $fallbackType=null)
Definition: SiteBasedTestTrait.php:144
‪TYPO3\CMS\Seo\Tests\Functional\HrefLang\HrefLangGeneratorTest\checkHrefLangOutput
‪checkHrefLangOutput(string $url, array $expectedTags, array $notExpectedTags)
Definition: HrefLangGeneratorTest.php:68
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\writeSiteConfiguration
‪writeSiteConfiguration(string $identifier, array $site=[], array $languages=[], array $errorHandling=[])
Definition: SiteBasedTestTrait.php:58
‪TYPO3\CMS\Seo\Tests\Functional\HrefLang\HrefLangGeneratorTest\failIfArrayIsNotEmpty
‪static failIfArrayIsNotEmpty(array $items)
Definition: HrefLangGeneratorTest.php:236
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildDefaultLanguageConfiguration
‪array buildDefaultLanguageConfiguration(string $identifier, string $base)
Definition: SiteBasedTestTrait.php:126
‪TYPO3\CMS\Core\Core\Bootstrap\initializeLanguageObject
‪static initializeLanguageObject()
Definition: Bootstrap.php:598
‪TYPO3\CMS\Seo\Tests\Functional\HrefLang\HrefLangGeneratorTest\checkHrefLangOutputDataProvider
‪array checkHrefLangOutputDataProvider()
Definition: HrefLangGeneratorTest.php:94
‪TYPO3\CMS\Seo\Tests\Functional\HrefLang\HrefLangGeneratorTest\setUpDatabaseWithYamlPayload
‪setUpDatabaseWithYamlPayload(string $pathToYamlFile)
Definition: HrefLangGeneratorTest.php:218
‪TYPO3\CMS\Seo\Tests\Functional\HrefLang\HrefLangGeneratorTest\setUp
‪setUp()
Definition: HrefLangGeneratorTest.php:44
‪TYPO3\CMS\Core\Core\Bootstrap
Definition: Bootstrap.php:70
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildSiteConfiguration
‪array buildSiteConfiguration(int $rootPageId, string $base='')
Definition: SiteBasedTestTrait.php:111