‪TYPO3CMS  ‪main
LinkServiceTest.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 
20 use PHPUnit\Framework\Attributes\DataProvider;
21 use PHPUnit\Framework\Attributes\Test;
22 use Psr\EventDispatcher\EventDispatcherInterface;
23 use Symfony\Component\DependencyInjection\Container;
32 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
33 
34 final class ‪LinkServiceTest extends UnitTestCase
35 {
36  protected function ‪setUp(): void
37  {
38  parent::setUp();
39  $container = new Container();
40  $container->set(EventDispatcherInterface::class, new ‪NoopEventDispatcher());
41  GeneralUtility::setContainer($container);
42  }
43 
47  public static function ‪resolveParametersForNonFilesDataProvider(): array
48  {
49  return [
50  'simple page - old style' => [
51  // original input value
52  '13',
53  // splitted values
54  [
55  'type' => ‪LinkService::TYPE_PAGE,
56  'pageuid' => 13,
57  ],
58  // final unified URN
59  't3://page?uid=13',
60  ],
61  'page with type - old style' => [
62  '13,31',
63  [
64  'type' => ‪LinkService::TYPE_PAGE,
65  'pageuid' => 13,
66  'pagetype' => 31,
67  ],
68  't3://page?uid=13&type=31',
69  ],
70  'page with type and fragment - old style' => [
71  '13,31#uncool',
72  [
73  'type' => ‪LinkService::TYPE_PAGE,
74  'pageuid' => '13',
75  'pagetype' => '31',
76  'fragment' => 'uncool',
77  ],
78  't3://page?uid=13&type=31#uncool',
79  ],
80  'page with type and parameters and fragment - old style' => [
81  '13,31?unbel=ievable#uncool',
82  [
83  'type' => ‪LinkService::TYPE_PAGE,
84  'pageuid' => '13',
85  'pagetype' => '31',
86  'parameters' => 'unbel=ievable',
87  'fragment' => 'uncool',
88  ],
89  't3://page?uid=13&type=31&unbel=ievable#uncool',
90  ],
91  'http URL' => [
92  'http://www.have.you/ever?did=this',
93  [
94  'type' => ‪LinkService::TYPE_URL,
95  'url' => 'http://www.have.you/ever?did=this',
96  ],
97  'http://www.have.you/ever?did=this',
98  ],
99  'http URL without scheme' => [
100  'www.have.you/ever?did=this',
101  [
102  'type' => ‪LinkService::TYPE_URL,
103  'url' => 'http://www.have.you/ever?did=this',
104  ],
105  'http://www.have.you/ever?did=this',
106  ],
107  'https URL' => [
108  'https://www.have.you/ever?did=this',
109  [
110  'type' => ‪LinkService::TYPE_URL,
111  'url' => 'https://www.have.you/ever?did=this',
112  ],
113  'https://www.have.you/ever?did=this',
114  ],
115  'https URL with port' => [
116  'https://www.have.you:8088/ever?did=this',
117  [
118  'type' => ‪LinkService::TYPE_URL,
119  'url' => 'https://www.have.you:8088/ever?did=this',
120  ],
121  'https://www.have.you:8088/ever?did=this',
122  ],
123  'ftp URL' => [
124  'ftp://www.have.you/ever?did=this',
125  [
126  'type' => ‪LinkService::TYPE_URL,
127  'url' => 'ftp://www.have.you/ever?did=this',
128  ],
129  'ftp://www.have.you/ever?did=this',
130  ],
131  'afp URL' => [
132  'afp://www.have.you/ever?did=this',
133  [
134  'type' => ‪LinkService::TYPE_URL,
135  'url' => 'afp://www.have.you/ever?did=this',
136  ],
137  'afp://www.have.you/ever?did=this',
138  ],
139  'sftp URL' => [
140  'sftp://nice:andsecret@www.have.you:23/ever?did=this',
141  [
142  'type' => ‪LinkService::TYPE_URL,
143  'url' => 'sftp://nice:andsecret@www.have.you:23/ever?did=this',
144  ],
145  'sftp://nice:andsecret@www.have.you:23/ever?did=this',
146  ],
147  'email with protocol' => [
148  'mailto:one@love.com',
149  [
150  'type' => ‪LinkService::TYPE_EMAIL,
151  'email' => 'one@love.com',
152  ],
153  'mailto:one@love.com',
154  ],
155  'email without protocol' => [
156  'one@love.com',
157  [
158  'type' => ‪LinkService::TYPE_EMAIL,
159  'email' => 'one@love.com',
160  ],
161  'mailto:one@love.com',
162  ],
163  'email without protocol and subject parameter' => [
164  'email@mail.mail?subject=Anfrage:%20Text%20Text%20Lösungen',
165  [
166  'type' => ‪LinkService::TYPE_EMAIL,
167  'email' => 'email@mail.mail?subject=Anfrage:%20Text%20Text%20Lösungen',
168  ],
169  'mailto:email@mail.mail?subject=Anfrage:%20Text%20Text%20Lösungen',
170  ],
171  'current page - cool style' => [
172  't3://page?uid=current',
173  [
174  'type' => ‪LinkService::TYPE_PAGE,
175  'pageuid' => 'current',
176  ],
177  't3://page?uid=current',
178  ],
179  'current empty page - cool style' => [
180  't3://page',
181  [
182  'type' => ‪LinkService::TYPE_PAGE,
183  'pageuid' => 'current',
184  ],
185  't3://page?uid=current',
186  ],
187  'simple page - cool style' => [
188  't3://page?uid=13',
189  [
190  'type' => ‪LinkService::TYPE_PAGE,
191  'pageuid' => 13,
192  ],
193  't3://page?uid=13',
194  ],
195  ];
196  }
197 
198  #[DataProvider('resolveParametersForNonFilesDataProvider')]
199  #[Test]
200  public function ‪resolveReturnsSplitParameters(string $input, array $expected, string $finalString): void
201  {
202  $subject = new ‪LinkService();
203  self::assertEquals($expected, $subject->resolve($input));
204  }
205 
206  #[DataProvider('resolveParametersForNonFilesDataProvider')]
207  #[Test]
208  public function ‪splitParametersToUnifiedIdentifier(string $input, array $parameters, string $expected): void
209  {
210  $subject = new ‪LinkService();
211  self::assertEquals($expected, $subject->asString($parameters));
212  }
213 
214  #[Test]
216  {
217  $this->expectException(UnknownLinkHandlerException::class);
218  $this->expectExceptionCode(1460581769);
219 
220  (new ‪LinkService())->resolveByStringRepresentation('t3://invalid');
221  }
222 
223  #[Test]
224  public function ‪unknownUrnExceptionIsThrown(): void
225  {
226  $this->expectException(UnknownUrnException::class);
227  $this->expectExceptionCode(1457177667);
228 
229  (new ‪LinkService())->resolveByStringRepresentation('invalid');
230  }
231 
232  #[Test]
234  {
235  $afterLinkResolvedByStringRepresentationEvent = null;
236  $modifiedResult = ['type' => 'my-type'];
237 
239  $container = GeneralUtility::getContainer();
240  $container->set(
241  'after-link-resolved-by-string-representation-listener',
242  static function (‪AfterLinkResolvedByStringRepresentationEvent $event) use (&$afterLinkResolvedByStringRepresentationEvent, $modifiedResult) {
243  $afterLinkResolvedByStringRepresentationEvent = $event;
244  $event->‪setResult($modifiedResult);
245  }
246  );
247 
248  $listenerProdiver = GeneralUtility::makeInstance(ListenerProvider::class, $container);
249  $listenerProdiver->addListener(AfterLinkResolvedByStringRepresentationEvent::class, 'after-link-resolved-by-string-representation-listener');
250  $container->set(ListenerProvider::class, $listenerProdiver);
251  $container->set(EventDispatcherInterface::class, new ‪EventDispatcher($listenerProdiver));
252 
253  // Note: The $urn will trigger the UnknownLinkHandlerException. This exception is
254  // being caught and since the event listener sets a "type" the exception is not thrown.
255  // However, the exception is passed to the event to provide extensions as much information as possible
256  $urn = 't3://invalid';
257  $expectedExceptionMessage = 'LinkHandler for invalid was not registered';
258  $result = (new ‪LinkService())->resolveByStringRepresentation($urn);
259 
260  self::assertSame($modifiedResult, $result);
261  self::assertInstanceOf(AfterLinkResolvedByStringRepresentationEvent::class, $afterLinkResolvedByStringRepresentationEvent);
262  self::assertSame($modifiedResult, $afterLinkResolvedByStringRepresentationEvent->getResult());
263  self::assertSame($urn, $afterLinkResolvedByStringRepresentationEvent->getUrn());
264  self::assertSame($expectedExceptionMessage, $afterLinkResolvedByStringRepresentationEvent->getResolveException()->getMessage());
265  }
266 }
‪TYPO3\CMS\Core\EventDispatcher\EventDispatcher
Definition: EventDispatcher.php:30
‪TYPO3\CMS\Core\EventDispatcher\NoopEventDispatcher
Definition: NoopEventDispatcher.php:29
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\EventDispatcher\ListenerProvider
Definition: ListenerProvider.php:30