]> git.immae.eu Git - github/shaarli/Shaarli.git/blame - tests/LinkUtilsTest.php
Extract the title/charset during page download, and check content type
[github/shaarli/Shaarli.git] / tests / LinkUtilsTest.php
CommitLineData
1557cefb
A
1<?php
2
3require_once 'application/LinkUtils.php';
4
5/**
6* Class LinkUtilsTest.
7*/
8class LinkUtilsTest extends PHPUnit_Framework_TestCase
9{
10 /**
11 * Test html_extract_title() when the title is found.
12 */
13 public function testHtmlExtractExistentTitle()
14 {
15 $title = 'Read me please.';
16 $html = '<html><meta>stuff</meta><title>'. $title .'</title></html>';
17 $this->assertEquals($title, html_extract_title($html));
68ea1d2b
A
18 $html = '<html><title>'. $title .'</title>blabla<title>another</title></html>';
19 $this->assertEquals($title, html_extract_title($html));
1557cefb
A
20 }
21
22 /**
23 * Test html_extract_title() when the title is not found.
24 */
25 public function testHtmlExtractNonExistentTitle()
26 {
27 $html = '<html><meta>stuff</meta></html>';
28 $this->assertFalse(html_extract_title($html));
29 }
30
1557cefb
A
31 /**
32 * Test headers_extract_charset() when the charset is found.
33 */
34 public function testHeadersExtractExistentCharset()
35 {
36 $charset = 'x-MacCroatian';
d65342e3
A
37 $headers = 'text/html; charset='. $charset;
38 $this->assertEquals(strtolower($charset), header_extract_charset($headers));
1557cefb
A
39 }
40
41 /**
42 * Test headers_extract_charset() when the charset is not found.
43 */
44 public function testHeadersExtractNonExistentCharset()
45 {
d65342e3
A
46 $headers = '';
47 $this->assertFalse(header_extract_charset($headers));
1557cefb 48
d65342e3
A
49 $headers = 'text/html';
50 $this->assertFalse(header_extract_charset($headers));
1557cefb
A
51 }
52
53 /**
54 * Test html_extract_charset() when the charset is found.
55 */
56 public function testHtmlExtractExistentCharset()
57 {
58 $charset = 'x-MacCroatian';
59 $html = '<html><meta>stuff2</meta><meta charset="'. $charset .'"/></html>';
60 $this->assertEquals(strtolower($charset), html_extract_charset($html));
61 }
62
63 /**
64 * Test html_extract_charset() when the charset is not found.
65 */
66 public function testHtmlExtractNonExistentCharset()
67 {
68 $html = '<html><meta>stuff</meta></html>';
69 $this->assertFalse(html_extract_charset($html));
70 $html = '<html><meta>stuff</meta><meta charset=""/></html>';
71 $this->assertFalse(html_extract_charset($html));
72 }
141a86c5 73
d65342e3
A
74 /**
75 * Test the download callback with valid value
76 */
77 public function testCurlDownloadCallbackOk()
78 {
79 $callback = get_curl_download_callback($charset, $title, 'ut_curl_getinfo_ok');
80 $data = [
81 'HTTP/1.1 200 OK',
82 'Server: GitHub.com',
83 'Date: Sat, 28 Oct 2017 12:01:33 GMT',
84 'Content-Type: text/html; charset=utf-8',
85 'Status: 200 OK',
86 'end' => 'th=device-width"><title>Refactoring · GitHub</title><link rel="search" type="application/opensea',
87 '<title>ignored</title>',
88 ];
89 foreach ($data as $key => $line) {
90 $ignore = null;
91 $expected = $key !== 'end' ? strlen($line) : false;
92 $this->assertEquals($expected, $callback($ignore, $line));
93 if ($expected === false) {
94 break;
95 }
96 }
97 $this->assertEquals('utf-8', $charset);
98 $this->assertEquals('Refactoring · GitHub', $title);
99 }
100
101 /**
102 * Test the download callback with valid values and no charset
103 */
104 public function testCurlDownloadCallbackOkNoCharset()
105 {
106 $callback = get_curl_download_callback($charset, $title, 'ut_curl_getinfo_no_charset');
107 $data = [
108 'HTTP/1.1 200 OK',
109 'end' => 'th=device-width"><title>Refactoring · GitHub</title><link rel="search" type="application/opensea',
110 '<title>ignored</title>',
111 ];
112 foreach ($data as $key => $line) {
113 $ignore = null;
114 $this->assertEquals(strlen($line), $callback($ignore, $line));
115 }
116 $this->assertEmpty($charset);
117 $this->assertEquals('Refactoring · GitHub', $title);
118 }
119
120 /**
121 * Test the download callback with valid values and no charset
122 */
123 public function testCurlDownloadCallbackOkHtmlCharset()
124 {
125 $callback = get_curl_download_callback($charset, $title, 'ut_curl_getinfo_no_charset');
126 $data = [
127 'HTTP/1.1 200 OK',
128 '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />',
129 'end' => 'th=device-width"><title>Refactoring · GitHub</title><link rel="search" type="application/opensea',
130 '<title>ignored</title>',
131 ];
132 foreach ($data as $key => $line) {
133 $ignore = null;
134 $expected = $key !== 'end' ? strlen($line) : false;
135 $this->assertEquals($expected, $callback($ignore, $line));
136 if ($expected === false) {
137 break;
138 }
139 }
140 $this->assertEquals('utf-8', $charset);
141 $this->assertEquals('Refactoring · GitHub', $title);
142 }
143
144 /**
145 * Test the download callback with valid values and no title
146 */
147 public function testCurlDownloadCallbackOkNoTitle()
148 {
149 $callback = get_curl_download_callback($charset, $title, 'ut_curl_getinfo_ok');
150 $data = [
151 'HTTP/1.1 200 OK',
152 'end' => 'th=device-width">Refactoring · GitHub<link rel="search" type="application/opensea',
153 'ignored',
154 ];
155 foreach ($data as $key => $line) {
156 $ignore = null;
157 $this->assertEquals(strlen($line), $callback($ignore, $line));
158 }
159 $this->assertEquals('utf-8', $charset);
160 $this->assertEmpty($title);
161 }
162
163 /**
164 * Test the download callback with an invalid content type.
165 */
166 public function testCurlDownloadCallbackInvalidContentType()
167 {
168 $callback = get_curl_download_callback($charset, $title, 'ut_curl_getinfo_ct_ko');
169 $ignore = null;
170 $this->assertFalse($callback($ignore, ''));
171 $this->assertEmpty($charset);
172 $this->assertEmpty($title);
173 }
174
175 /**
176 * Test the download callback with an invalid response code.
177 */
178 public function testCurlDownloadCallbackInvalidResponseCode()
179 {
180 $callback = get_curl_download_callback($charset, $title, 'ut_curl_getinfo_rc_ko');
181 $ignore = null;
182 $this->assertFalse($callback($ignore, ''));
183 $this->assertEmpty($charset);
184 $this->assertEmpty($title);
185 }
186
187 /**
188 * Test the download callback with an invalid content type and response code.
189 */
190 public function testCurlDownloadCallbackInvalidContentTypeAndResponseCode()
191 {
192 $callback = get_curl_download_callback($charset, $title, 'ut_curl_getinfo_rs_ct_ko');
193 $ignore = null;
194 $this->assertFalse($callback($ignore, ''));
195 $this->assertEmpty($charset);
196 $this->assertEmpty($title);
197 }
198
141a86c5
A
199 /**
200 * Test count_private.
201 */
202 public function testCountPrivateLinks()
203 {
204 $refDB = new ReferenceLinkDB();
205 $this->assertEquals($refDB->countPrivateLinks(), count_private($refDB->getLinks()));
206 }
9ccca401
A
207
208 /**
209 * Test text2clickable without a redirector being set.
210 */
211 public function testText2clickableWithoutRedirector()
212 {
213 $text = 'stuff http://hello.there/is=someone#here otherstuff';
214 $expectedText = 'stuff <a href="http://hello.there/is=someone#here">http://hello.there/is=someone#here</a> otherstuff';
215 $processedText = text2clickable($text, '');
216 $this->assertEquals($expectedText, $processedText);
217 }
218
219 /**
220 * Test text2clickable a redirector set.
221 */
222 public function testText2clickableWithRedirector()
223 {
224 $text = 'stuff http://hello.there/is=someone#here otherstuff';
225 $redirector = 'http://redirector.to';
226 $expectedText = 'stuff <a href="'.
227 $redirector .
228 urlencode('http://hello.there/is=someone#here') .
229 '">http://hello.there/is=someone#here</a> otherstuff';
230 $processedText = text2clickable($text, $redirector);
231 $this->assertEquals($expectedText, $processedText);
232 }
233
234 /**
235 * Test testSpace2nbsp.
236 */
237 public function testSpace2nbsp()
238 {
239 $text = ' Are you thrilled by flags ?'. PHP_EOL .' Really?';
240 $expectedText = '&nbsp; Are you &nbsp; thrilled &nbsp;by flags &nbsp; ?'. PHP_EOL .'&nbsp;Really?';
241 $processedText = space2nbsp($text);
242 $this->assertEquals($expectedText, $processedText);
243 }
244
245 /**
246 * Test hashtags auto-link.
247 */
248 public function testHashtagAutolink()
249 {
250 $index = 'http://domain.tld/';
251 $rawDescription = '#hashtag\n
252 # nothashtag\n
253 test#nothashtag #hashtag \#nothashtag\n
254 test #hashtag #hashtag test #hashtag.test\n
255 #hashtag #hashtag-nothashtag #hashtag_hashtag\n
256 What is #ашок anyway?\n
257 カタカナ #カタカナ」カタカナ\n';
258 $autolinkedDescription = hashtag_autolink($rawDescription, $index);
259
260 $this->assertContains($this->getHashtagLink('hashtag', $index), $autolinkedDescription);
261 $this->assertNotContains(' #hashtag', $autolinkedDescription);
262 $this->assertNotContains('>#nothashtag', $autolinkedDescription);
263 $this->assertContains($this->getHashtagLink('ашок', $index), $autolinkedDescription);
264 $this->assertContains($this->getHashtagLink('カタカナ', $index), $autolinkedDescription);
265 $this->assertContains($this->getHashtagLink('hashtag_hashtag', $index), $autolinkedDescription);
266 $this->assertNotContains($this->getHashtagLink('hashtag-nothashtag', $index), $autolinkedDescription);
267 }
268
269 /**
270 * Test hashtags auto-link without index URL.
271 */
272 public function testHashtagAutolinkNoIndex()
273 {
274 $rawDescription = 'blabla #hashtag x#nothashtag';
275 $autolinkedDescription = hashtag_autolink($rawDescription);
276
277 $this->assertContains($this->getHashtagLink('hashtag'), $autolinkedDescription);
278 $this->assertNotContains(' #hashtag', $autolinkedDescription);
279 $this->assertNotContains('>#nothashtag', $autolinkedDescription);
280 }
281
282 /**
283 * Util function to build an hashtag link.
284 *
285 * @param string $hashtag Hashtag name.
286 * @param string $index Index URL.
287 *
288 * @return string HTML hashtag link.
289 */
290 private function getHashtagLink($hashtag, $index = '')
291 {
292 $hashtagLink = '<a href="'. $index .'?addtag=$1" title="Hashtag $1">#$1</a>';
293 return str_replace('$1', $hashtag, $hashtagLink);
294 }
1557cefb 295}
d65342e3
A
296
297// old style mock: PHPUnit doesn't allow function mock
298
299/**
300 * Returns code 200 or html content type.
301 *
302 * @param resource $ch cURL resource
303 * @param int $type cURL info type
304 *
305 * @return int|string 200 or 'text/html'
306 */
307function ut_curl_getinfo_ok($ch, $type)
308{
309 switch ($type) {
310 case CURLINFO_RESPONSE_CODE:
311 return 200;
312 case CURLINFO_CONTENT_TYPE:
313 return 'text/html; charset=utf-8';
314 }
315}
316
317/**
318 * Returns code 200 or html content type without charset.
319 *
320 * @param resource $ch cURL resource
321 * @param int $type cURL info type
322 *
323 * @return int|string 200 or 'text/html'
324 */
325function ut_curl_getinfo_no_charset($ch, $type)
326{
327 switch ($type) {
328 case CURLINFO_RESPONSE_CODE:
329 return 200;
330 case CURLINFO_CONTENT_TYPE:
331 return 'text/html';
332 }
333}
334
335/**
336 * Invalid response code.
337 *
338 * @param resource $ch cURL resource
339 * @param int $type cURL info type
340 *
341 * @return int|string 404 or 'text/html'
342 */
343function ut_curl_getinfo_rc_ko($ch, $type)
344{
345 switch ($type) {
346 case CURLINFO_RESPONSE_CODE:
347 return 404;
348 case CURLINFO_CONTENT_TYPE:
349 return 'text/html; charset=utf-8';
350 }
351}
352
353/**
354 * Invalid content type.
355 *
356 * @param resource $ch cURL resource
357 * @param int $type cURL info type
358 *
359 * @return int|string 200 or 'text/plain'
360 */
361function ut_curl_getinfo_ct_ko($ch, $type)
362{
363 switch ($type) {
364 case CURLINFO_RESPONSE_CODE:
365 return 200;
366 case CURLINFO_CONTENT_TYPE:
367 return 'text/plain';
368 }
369}
370
371/**
372 * Invalid response code and content type.
373 *
374 * @param resource $ch cURL resource
375 * @param int $type cURL info type
376 *
377 * @return int|string 404 or 'text/plain'
378 */
379function ut_curl_getinfo_rs_ct_ko($ch, $type)
380{
381 switch ($type) {
382 case CURLINFO_RESPONSE_CODE:
383 return 404;
384 case CURLINFO_CONTENT_TYPE:
385 return 'text/plain';
386 }
387}
388