‪TYPO3CMS  9.5
ExternalLinktypeTest.php
Go to the documentation of this file.
1 <?php
2 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 
18 use GuzzleHttp\Cookie\CookieJar;
19 use GuzzleHttp\Exception\ClientException;
20 use GuzzleHttp\Psr7\Response;
21 use Prophecy\Argument;
22 use Prophecy\Prophecy\ObjectProphecy;
27 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
28 
29 class ‪ExternalLinktypeTest extends UnitTestCase
30 {
31  protected function ‪setUp(): void
32  {
33  parent::setUp();
34  ‪$GLOBALS['LANG'] = $this->‪buildLanguageServiceProphecy()->reveal();
35  }
36 
37  private function ‪buildLanguageServiceProphecy(): ObjectProphecy
38  {
39  $languageServiceProphecy = $this->prophesize(LanguageService::class);
40  $languageServiceProphecy
41  ->includeLLFile('EXT:linkvalidator/Resources/Private/Language/Module/locallang.xlf');
42  $languageServiceProphecy->getLL(Argument::any())->willReturn('translation string');
43  return $languageServiceProphecy;
44  }
45 
50  {
51  $responseProphecy = $this->prophesize(Response::class);
52  $responseProphecy->getStatusCode()->willReturn(404);
53 
54  $exceptionProphecy = $this->prophesize(ClientException::class);
55  $exceptionProphecy->hasResponse()
56  ->willReturn(true);
57  $exceptionProphecy->getResponse()
58  ->willReturn($responseProphecy->reveal());
59 
60  $url = 'https://example.org/~not-existing-url';
61  $options = $this->‪getRequestHeaderOptions();
62  $requestFactoryProphecy = $this->prophesize(RequestFactory::class);
63  $requestFactoryProphecy->request($url, 'HEAD', $options)
64  ->willThrow($exceptionProphecy->reveal());
65 
66  $optionsSecondTryWithGET = array_merge_recursive($options, ['headers' => ['Range' => 'bytes=0-4048']]);
67  $requestFactoryProphecy->request($url, 'GET', $optionsSecondTryWithGET)
68  ->willThrow($exceptionProphecy->reveal());
69  $subject = new ‪ExternalLinktype($requestFactoryProphecy->reveal());
70 
71  $result = $subject->checkLink($url, null, null);
72 
73  self::assertSame(false, $result);
74  }
75 
80  {
81  $responseProphecy = $this->prophesize(Response::class);
82  $responseProphecy->getStatusCode()->willReturn(404);
83 
84  $exceptionProphecy = $this->prophesize(ClientException::class);
85  $exceptionProphecy->hasResponse()
86  ->willReturn(true);
87  $exceptionProphecy->getResponse()
88  ->willReturn($responseProphecy->reveal());
89 
90  $options = $this->‪getRequestHeaderOptions();
91 
92  $url = 'https://example.org/~not-existing-url';
93  $requestFactoryProphecy = $this->prophesize(RequestFactory::class);
94  $requestFactoryProphecy->request($url, 'HEAD', $options)
95  ->willThrow($exceptionProphecy->reveal());
96  $optionsSecondTryWithGET = array_merge_recursive($options, ['headers' => ['Range' => 'bytes=0-4048']]);
97  $requestFactoryProphecy->request($url, 'GET', $optionsSecondTryWithGET)
98  ->willThrow($exceptionProphecy->reveal());
99  $subject = new ‪ExternalLinktype($requestFactoryProphecy->reveal());
100 
101  $subject->checkLink($url, null, null);
102  $result = $subject->getErrorParams()['errorType'];
103 
104  self::assertSame(404, $result);
105  }
106 
107  private function ‪getCookieJarProphecy(): CookieJar
108  {
109  $cookieJar = $this->prophesize(CookieJar::class);
110  $cookieJar = $cookieJar->reveal();
111  GeneralUtility::addInstance(CookieJar::class, $cookieJar);
112  return $cookieJar;
113  }
114 
115  private function ‪getRequestHeaderOptions(): array
116  {
117  return [
118  'cookies' => $this->‪getCookieJarProphecy(),
119  'allow_redirects' => ['strict' => true],
120  'headers' => [
121  'User-Agent' => 'TYPO3 linkvalidator',
122  'Accept' => '*/*',
123  'Accept-Language' => '*',
124  'Accept-Encoding' => '*'
125  ]
126  ];
127  }
128 
130  {
131  // regression test for issue #92230: handle incomplete or faulty URLs gracefully
132  yield 'faulty URL with mailto' => [
133  'mailto:http://example.org',
134  'mailto:http://example.org'
135  ];
136  yield 'Relative URL' => [
137  '/abc',
138  '/abc'
139  ];
140 
141  // regression tests for issues #89488, #89682
142  yield 'URL with query parameter and ampersand' => [
143  'https://standards.cen.eu/dyn/www/f?p=204:6:0::::FSP_ORG_ID,FSP_LANG_ID:,22&cs=1A3FFBC44FAB6B2A181C9525249C3A829',
144  'https://standards.cen.eu/dyn/www/f?p=204:6:0::::FSP_ORG_ID,FSP_LANG_ID:,22&cs=1A3FFBC44FAB6B2A181C9525249C3A829'
145  ];
146  yield 'URL with query parameter and ampersand with HTML entities' => [
147  'https://standards.cen.eu/dyn/www/f?p=204:6:0::::FSP_ORG_ID,FSP_LANG_ID:,22&amp;cs=1A3FFBC44FAB6B2A181C9525249C3A829',
148  'https://standards.cen.eu/dyn/www/f?p=204:6:0::::FSP_ORG_ID,FSP_LANG_ID:,22&cs=1A3FFBC44FAB6B2A181C9525249C3A829'
149  ];
150 
151  // regression tests for #89378
152  yield 'URL with path with dashes' => [
153  'https://example.com/Unternehmen/Ausbildung-Qualifikation/Weiterbildung-in-Niedersachsen/',
154  'https://example.com/Unternehmen/Ausbildung-Qualifikation/Weiterbildung-in-Niedersachsen/'
155  ];
156  yield 'URL with path with dashes (2)' => [
157  'https://example.com/startseite/wirtschaft/wirtschaftsfoerderung/beratung-foerderung/gruenderberatung/gruenderforen.html',
158  'https://example.com/startseite/wirtschaft/wirtschaftsfoerderung/beratung-foerderung/gruenderberatung/gruenderforen.html'
159  ];
160  yield 'URL with path with dashes (3)' => [
161  'http://example.com/universitaet/die-uni-im-ueberblick/lageplan/gebaeude/building/120',
162  'http://example.com/universitaet/die-uni-im-ueberblick/lageplan/gebaeude/building/120'
163  ];
164  yield 'URL with path and query parameters (including &, ~,; etc.)' => [
165  'http://example.com/tv?bcpid=1701167454001&amp;amp;amp;bckey=AQ~~,AAAAAGL7LqU~,aXlKNnCf9d9Tmck-kOc4PGFfCgHjM5JR&amp;amp;amp;bctid=1040702768001',
166  'http://example.com/tv?bcpid=1701167454001&amp;amp;bckey=AQ~~,AAAAAGL7LqU~,aXlKNnCf9d9Tmck-kOc4PGFfCgHjM5JR&amp;amp;bctid=1040702768001'
167  ];
168 
169  // make sure we correctly handle URLs with query parameters and fragment etc.
170  yield 'URL with query parameters, fragment, user, pass, port etc.' => [
171  'http://usr:pss@example.com:81/mypath/myfile.html?a=b&b[]=2&b[]=3#myfragment',
172  'http://usr:pss@example.com:81/mypath/myfile.html?a=b&b[]=2&b[]=3#myfragment'
173  ];
174  yield 'domain with special characters, URL with query parameters, fragment, user, pass, port etc.' => [
175  'http://usr:pss@äxample.com:81/mypath/myfile.html?a=b&b[]=2&b[]=3#myfragment',
176  'http://usr:pss@xn--xample-9ta.com:81/mypath/myfile.html?a=b&b[]=2&b[]=3#myfragment'
177  ];
178 
179  // domains with special characters: should be converted to punycode
180  yield 'domain with special characters' => [
181  'https://www.grün-example.org',
182  'https://www.xn--grn-example-uhb.org'
183  ];
184  yield 'domain with special characters and path' => [
185  'https://www.grün-example.org/a/bcd-efg/sfsfsfsfsf',
186  'https://www.xn--grn-example-uhb.org/a/bcd-efg/sfsfsfsfsf'
187  ];
188  }
189 
194  public function ‪preprocessUrlReturnsCorrectString(string $inputUrl, $expectedResult)
195  {
196  $subject = new ‪ExternalLinktype();
197  $method = new \ReflectionMethod($subject, 'preprocessUrl');
198  $method->setAccessible(true);
199  $result = $method->invokeArgs($subject, [$inputUrl]);
200  $this->assertEquals($result, $expectedResult);
201  }
202 }
‪TYPO3\CMS\Linkvalidator\Tests\Unit\Linktype\ExternalLinktypeTest\preprocessUrlsDataProvider
‪preprocessUrlsDataProvider()
Definition: ExternalLinktypeTest.php:129
‪TYPO3\CMS\Linkvalidator\Tests\Unit\Linktype\ExternalLinktypeTest\checkLinkWithExternalUrlNotFoundResultsNotFoundErrorType
‪checkLinkWithExternalUrlNotFoundResultsNotFoundErrorType()
Definition: ExternalLinktypeTest.php:79
‪TYPO3\CMS\Linkvalidator\Tests\Unit\Linktype\ExternalLinktypeTest\preprocessUrlReturnsCorrectString
‪preprocessUrlReturnsCorrectString(string $inputUrl, $expectedResult)
Definition: ExternalLinktypeTest.php:194
‪TYPO3\CMS\Linkvalidator\Tests\Unit\Linktype\ExternalLinktypeTest\setUp
‪setUp()
Definition: ExternalLinktypeTest.php:31
‪TYPO3\CMS\Linkvalidator\Tests\Unit\Linktype\ExternalLinktypeTest
Definition: ExternalLinktypeTest.php:30
‪TYPO3\CMS\Linkvalidator\Tests\Unit\Linktype
Definition: ExternalLinktypeTest.php:3
‪TYPO3\CMS\Linkvalidator\Linktype\ExternalLinktype
Definition: ExternalLinktype.php:26
‪TYPO3\CMS\Core\Http\RequestFactory
Definition: RequestFactory.php:27
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Linkvalidator\Tests\Unit\Linktype\ExternalLinktypeTest\buildLanguageServiceProphecy
‪buildLanguageServiceProphecy()
Definition: ExternalLinktypeTest.php:37
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:29
‪TYPO3\CMS\Linkvalidator\Tests\Unit\Linktype\ExternalLinktypeTest\getRequestHeaderOptions
‪getRequestHeaderOptions()
Definition: ExternalLinktypeTest.php:115
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Linkvalidator\Tests\Unit\Linktype\ExternalLinktypeTest\checkLinkWithExternalUrlNotFoundReturnsFalse
‪checkLinkWithExternalUrlNotFoundReturnsFalse()
Definition: ExternalLinktypeTest.php:49
‪TYPO3\CMS\Linkvalidator\Tests\Unit\Linktype\ExternalLinktypeTest\getCookieJarProphecy
‪getCookieJarProphecy()
Definition: ExternalLinktypeTest.php:107