]> git.immae.eu Git - github/shaarli/Shaarli.git/blame - tests/formatter/BookmarkDefaultFormatterTest.php
Support search highlights when matching URL content
[github/shaarli/Shaarli.git] / tests / formatter / BookmarkDefaultFormatterTest.php
CommitLineData
e26e2060
A
1<?php
2
3namespace Shaarli\Formatter;
4
5use DateTime;
e26e2060
A
6use Shaarli\Bookmark\Bookmark;
7use Shaarli\Config\ConfigManager;
a5a9cf23 8use Shaarli\TestCase;
e26e2060
A
9
10/**
11 * Class BookmarkDefaultFormatterTest
12 * @package Shaarli\Formatter
13 */
14class BookmarkDefaultFormatterTest extends TestCase
15{
16 /** @var string Path of test config file */
17 protected static $testConf = 'sandbox/config';
18
19 /** @var BookmarkFormatter */
20 protected $formatter;
21
22 /** @var ConfigManager instance */
23 protected $conf;
24
25 /**
26 * Initialize formatter instance.
27 */
8f60e120 28 protected function setUp(): void
e26e2060
A
29 {
30 copy('tests/utils/config/configJson.json.php', self::$testConf .'.json.php');
31 $this->conf = new ConfigManager(self::$testConf);
a39acb25 32 $this->formatter = new BookmarkDefaultFormatter($this->conf, true);
e26e2060
A
33 }
34
35 /**
36 * Test formatting a bookmark with all its attribute filled.
37 */
38 public function testFormatFull()
39 {
40 $bookmark = new Bookmark();
41 $bookmark->setId($id = 11);
42 $bookmark->setShortUrl($short = 'abcdef');
43 $bookmark->setUrl('https://sub.domain.tld?query=here&for=real#hash');
44 $bookmark->setTitle($title = 'This is a <strong>bookmark</strong>');
45 $bookmark->setDescription($desc = '<h2>Content</h2><p>`Here is some content</p>');
46 $bookmark->setTags($tags = ['tag1', 'bookmark', 'other', '<script>alert("xss");</script>']);
47 $bookmark->setThumbnail('http://domain2.tdl2/?type=img&name=file.png');
48 $bookmark->setSticky(true);
49 $bookmark->setCreated($created = DateTime::createFromFormat('Ymd_His', '20190521_190412'));
50 $bookmark->setUpdated($updated = DateTime::createFromFormat('Ymd_His', '20190521_191213'));
51 $bookmark->setPrivate(true);
52
53 $link = $this->formatter->format($bookmark);
54 $this->assertEquals($id, $link['id']);
55 $this->assertEquals($short, $link['shorturl']);
56 $this->assertEquals('https://sub.domain.tld?query=here&amp;for=real#hash', $link['url']);
57 $this->assertEquals(
58 'https://sub.domain.tld?query=here&amp;for=real#hash',
59 $link['real_url']
60 );
61 $this->assertEquals('This is a &lt;strong&gt;bookmark&lt;/strong&gt;', $link['title']);
62 $this->assertEquals(
63 '&lt;h2&gt;Content&lt;/h2&gt;&lt;p&gt;`Here is some content&lt;/p&gt;',
64 $link['description']
65 );
66 $tags[3] = '&lt;script&gt;alert(&quot;xss&quot;);&lt;/script&gt;';
67 $this->assertEquals($tags, $link['taglist']);
68 $this->assertEquals(implode(' ', $tags), $link['tags']);
69 $this->assertEquals(
70 'http://domain2.tdl2/?type=img&amp;name=file.png',
71 $link['thumbnail']
72 );
73 $this->assertEquals($created, $link['created']);
74 $this->assertEquals($created->getTimestamp(), $link['timestamp']);
75 $this->assertEquals($updated, $link['updated']);
76 $this->assertEquals($updated->getTimestamp(), $link['updated_timestamp']);
77 $this->assertTrue($link['private']);
78 $this->assertTrue($link['sticky']);
79 $this->assertEquals('private', $link['class']);
80 }
81
82 /**
83 * Test formatting a bookmark with all its attribute filled.
84 */
85 public function testFormatMinimal()
86 {
87 $bookmark = new Bookmark();
88
89 $link = $this->formatter->format($bookmark);
90 $this->assertEmpty($link['id']);
91 $this->assertEmpty($link['shorturl']);
92 $this->assertEmpty($link['url']);
93 $this->assertEmpty($link['real_url']);
94 $this->assertEmpty($link['title']);
95 $this->assertEmpty($link['description']);
96 $this->assertEmpty($link['taglist']);
97 $this->assertEmpty($link['tags']);
98 $this->assertEmpty($link['thumbnail']);
99 $this->assertEmpty($link['created']);
100 $this->assertEmpty($link['timestamp']);
101 $this->assertEmpty($link['updated']);
102 $this->assertEmpty($link['updated_timestamp']);
103 $this->assertFalse($link['private']);
104 $this->assertFalse($link['sticky']);
105 $this->assertEmpty($link['class']);
106 }
107
108 /**
109 * Make sure that the description is properly formatted by the default formatter.
110 */
111 public function testFormatDescription()
112 {
113 $description = [];
114 $description[] = 'This a <strong>description</strong>' . PHP_EOL;
115 $description[] = 'text https://sub.domain.tld?query=here&for=real#hash more text'. PHP_EOL;
116 $description[] = 'Also, there is an #hashtag added'. PHP_EOL;
117 $description[] = ' A N D KEEP SPACES ! '. PHP_EOL;
118
119 $bookmark = new Bookmark();
120 $bookmark->setDescription(implode('', $description));
121 $link = $this->formatter->format($bookmark);
122
123 $description[0] = 'This a &lt;strong&gt;description&lt;/strong&gt;<br />';
124 $url = 'https://sub.domain.tld?query=here&amp;for=real#hash';
125 $description[1] = 'text <a href="'. $url .'">'. $url .'</a> more text<br />';
03340c18 126 $description[2] = 'Also, there is an <a href="./add-tag/hashtag" '.
e26e2060
A
127 'title="Hashtag hashtag">#hashtag</a> added<br />';
128 $description[3] = '&nbsp; &nbsp; A &nbsp;N &nbsp;D KEEP &nbsp; &nbsp; '.
129 'SPACES &nbsp; &nbsp;! &nbsp; <br />';
130
131 $this->assertEquals(implode(PHP_EOL, $description) . PHP_EOL, $link['description']);
132 }
133
134 /**
135 * Test formatting URL with an index_url set
136 * It should prepend relative links.
137 */
138 public function testFormatNoteWithIndexUrl()
139 {
140 $bookmark = new Bookmark();
141 $bookmark->setUrl($short = '?abcdef');
142 $description = 'Text #hashtag more text';
143 $bookmark->setDescription($description);
144
145 $this->formatter->addContextData('index_url', $root = 'https://domain.tld/hithere/');
146
147 $link = $this->formatter->format($bookmark);
148 $this->assertEquals($root . $short, $link['url']);
149 $this->assertEquals($root . $short, $link['real_url']);
150 $this->assertEquals(
03340c18 151 'Text <a href="'. $root .'./add-tag/hashtag" title="Hashtag hashtag">'.
e26e2060
A
152 '#hashtag</a> more text',
153 $link['description']
154 );
155 }
a39acb25
A
156
157 /**
158 * Make sure that private tags are properly filtered out when the user is logged out.
159 */
160 public function testFormatTagListRemovePrivate(): void
161 {
162 $this->formatter = new BookmarkDefaultFormatter($this->conf, false);
163
164 $bookmark = new Bookmark();
165 $bookmark->setId($id = 11);
166 $bookmark->setTags($tags = ['bookmark', '.private', 'othertag']);
167
168 $link = $this->formatter->format($bookmark);
169
170 unset($tags[1]);
171 $tags = array_values($tags);
172
173 $this->assertSame(11, $link['id']);
174 $this->assertSame($tags, $link['taglist']);
175 $this->assertSame(implode(' ', $tags), $link['tags']);
176 }
f1a148ab
A
177
178 /**
179 * Test formatTitleHtml with search result highlight.
180 */
181 public function testFormatTitleHtmlWithSearchHighlight(): void
182 {
183 $this->formatter = new BookmarkDefaultFormatter($this->conf, false);
184
185 $bookmark = new Bookmark();
186 $bookmark->setTitle('PSR-2: Coding Style Guide');
187 $bookmark->addAdditionalContentEntry(
188 'search_highlight',
189 ['title' => [
190 ['start' => 0, 'end' => 5], // "psr-2"
191 ['start' => 7, 'end' => 13], // coding
192 ['start' => 20, 'end' => 25], // guide
193 ]]
194 );
195
196 $link = $this->formatter->format($bookmark);
197
198 $this->assertSame(
199 '<span class="search-highlight">PSR-2</span>: ' .
200 '<span class="search-highlight">Coding</span> Style ' .
201 '<span class="search-highlight">Guide</span>',
202 $link['title_html']
203 );
204 }
205
206 /**
207 * Test formatDescription with search result highlight.
208 */
209 public function testFormatDescriptionWithSearchHighlight(): void
210 {
211 $this->formatter = new BookmarkDefaultFormatter($this->conf, false);
212
213 $bookmark = new Bookmark();
9ef8555a
A
214 $bookmark->setDescription(
215 'This guide extends and expands on PSR-1, the basic coding standard.' . PHP_EOL .
216 'https://www.php-fig.org/psr/psr-1/'
217 );
f1a148ab
A
218 $bookmark->addAdditionalContentEntry(
219 'search_highlight',
220 ['description' => [
221 ['start' => 0, 'end' => 10], // "This guide"
222 ['start' => 45, 'end' => 50], // basic
223 ['start' => 58, 'end' => 67], // standard.
9ef8555a 224 ['start' => 84, 'end' => 87], // fig
f1a148ab
A
225 ]]
226 );
227
228 $link = $this->formatter->format($bookmark);
229
230 $this->assertSame(
231 '<span class="search-highlight">This guide</span> extends and expands on PSR-1, the ' .
232 '<span class="search-highlight">basic</span> coding ' .
9ef8555a
A
233 '<span class="search-highlight">standard.</span><br />' . PHP_EOL .
234 '<a href="https://www.php-fig.org/psr/psr-1/">' .
235 'https://www.php-<span class="search-highlight">fig</span>.org/psr/psr-1/' .
236 '</a>',
f1a148ab
A
237 $link['description']
238 );
239 }
240
241 /**
242 * Test formatUrlHtml with search result highlight.
243 */
244 public function testFormatUrlHtmlWithSearchHighlight(): void
245 {
246 $this->formatter = new BookmarkDefaultFormatter($this->conf, false);
247
248 $bookmark = new Bookmark();
249 $bookmark->setUrl('http://www.php-fig.org/psr/psr-2/');
250 $bookmark->addAdditionalContentEntry(
251 'search_highlight',
252 ['url' => [
253 ['start' => 0, 'end' => 4], // http
254 ['start' => 15, 'end' => 18], // fig
255 ['start' => 27, 'end' => 33], // "psr-2/"
256 ]]
257 );
258
259 $link = $this->formatter->format($bookmark);
260
261 $this->assertSame(
262 '<span class="search-highlight">http</span>://www.php-' .
263 '<span class="search-highlight">fig</span>.org/psr/' .
264 '<span class="search-highlight">psr-2/</span>',
265 $link['url_html']
266 );
267 }
268
269 /**
270 * Test formatTagListHtml with search result highlight.
271 */
272 public function testFormatTagListHtmlWithSearchHighlight(): void
273 {
274 $this->formatter = new BookmarkDefaultFormatter($this->conf, false);
275
276 $bookmark = new Bookmark();
277 $bookmark->setTagsString('coding-style standards quality assurance');
278 $bookmark->addAdditionalContentEntry(
279 'search_highlight',
280 ['tags' => [
281 ['start' => 0, 'end' => 12], // coding-style
282 ['start' => 23, 'end' => 30], // quality
283 ['start' => 31, 'end' => 40], // assurance
284 ],]
285 );
286
287 $link = $this->formatter->format($bookmark);
288
289 $this->assertSame(
290 [
291 '<span class="search-highlight">coding-style</span>',
292 'standards',
293 '<span class="search-highlight">quality</span>',
294 '<span class="search-highlight">assurance</span>',
295 ],
296 $link['taglist_html']
297 );
298 }
740b32b5
A
299
300 /**
301 * Test default formatting with formatter_settings.autolink set to false:
302 * URLs and hashtags should not be transformed
303 */
304 public function testFormatDescriptionWithoutLinkification(): void
305 {
306 $this->conf->set('formatter_settings.autolink', false);
307 $this->formatter = new BookmarkDefaultFormatter($this->conf, false);
308
309 $bookmark = new Bookmark();
310 $bookmark->setDescription('Hi!' . PHP_EOL . 'https://thisisaurl.tld #hashtag');
311
312 $link = $this->formatter->format($bookmark);
313
314 static::assertSame(
315 'Hi!<br />' . PHP_EOL . 'https://thisisaurl.tld &nbsp;#hashtag',
316 $link['description']
317 );
318 }
e26e2060 319}