]>
Commit | Line | Data |
---|---|---|
e26e2060 A |
1 | <?php |
2 | ||
3 | namespace Shaarli\Formatter; | |
4 | ||
5 | use DateTime; | |
e26e2060 A |
6 | use Shaarli\Bookmark\Bookmark; |
7 | use Shaarli\Config\ConfigManager; | |
a5a9cf23 | 8 | use Shaarli\TestCase; |
e26e2060 A |
9 | |
10 | /** | |
11 | * Class BookmarkDefaultFormatterTest | |
12 | * @package Shaarli\Formatter | |
13 | */ | |
14 | class 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&for=real#hash', $link['url']); | |
57 | $this->assertEquals( | |
58 | 'https://sub.domain.tld?query=here&for=real#hash', | |
59 | $link['real_url'] | |
60 | ); | |
61 | $this->assertEquals('This is a <strong>bookmark</strong>', $link['title']); | |
62 | $this->assertEquals( | |
63 | '<h2>Content</h2><p>`Here is some content</p>', | |
64 | $link['description'] | |
65 | ); | |
66 | $tags[3] = '<script>alert("xss");</script>'; | |
67 | $this->assertEquals($tags, $link['taglist']); | |
68 | $this->assertEquals(implode(' ', $tags), $link['tags']); | |
69 | $this->assertEquals( | |
70 | 'http://domain2.tdl2/?type=img&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 <strong>description</strong><br />'; | |
124 | $url = 'https://sub.domain.tld?query=here&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] = ' A N D KEEP '. | |
129 | 'SPACES ! <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(); | |
214 | $bookmark->setDescription('This guide extends and expands on PSR-1, the basic coding standard.'); | |
215 | $bookmark->addAdditionalContentEntry( | |
216 | 'search_highlight', | |
217 | ['description' => [ | |
218 | ['start' => 0, 'end' => 10], // "This guide" | |
219 | ['start' => 45, 'end' => 50], // basic | |
220 | ['start' => 58, 'end' => 67], // standard. | |
221 | ]] | |
222 | ); | |
223 | ||
224 | $link = $this->formatter->format($bookmark); | |
225 | ||
226 | $this->assertSame( | |
227 | '<span class="search-highlight">This guide</span> extends and expands on PSR-1, the ' . | |
228 | '<span class="search-highlight">basic</span> coding ' . | |
229 | '<span class="search-highlight">standard.</span>', | |
230 | $link['description'] | |
231 | ); | |
232 | } | |
233 | ||
234 | /** | |
235 | * Test formatUrlHtml with search result highlight. | |
236 | */ | |
237 | public function testFormatUrlHtmlWithSearchHighlight(): void | |
238 | { | |
239 | $this->formatter = new BookmarkDefaultFormatter($this->conf, false); | |
240 | ||
241 | $bookmark = new Bookmark(); | |
242 | $bookmark->setUrl('http://www.php-fig.org/psr/psr-2/'); | |
243 | $bookmark->addAdditionalContentEntry( | |
244 | 'search_highlight', | |
245 | ['url' => [ | |
246 | ['start' => 0, 'end' => 4], // http | |
247 | ['start' => 15, 'end' => 18], // fig | |
248 | ['start' => 27, 'end' => 33], // "psr-2/" | |
249 | ]] | |
250 | ); | |
251 | ||
252 | $link = $this->formatter->format($bookmark); | |
253 | ||
254 | $this->assertSame( | |
255 | '<span class="search-highlight">http</span>://www.php-' . | |
256 | '<span class="search-highlight">fig</span>.org/psr/' . | |
257 | '<span class="search-highlight">psr-2/</span>', | |
258 | $link['url_html'] | |
259 | ); | |
260 | } | |
261 | ||
262 | /** | |
263 | * Test formatTagListHtml with search result highlight. | |
264 | */ | |
265 | public function testFormatTagListHtmlWithSearchHighlight(): void | |
266 | { | |
267 | $this->formatter = new BookmarkDefaultFormatter($this->conf, false); | |
268 | ||
269 | $bookmark = new Bookmark(); | |
270 | $bookmark->setTagsString('coding-style standards quality assurance'); | |
271 | $bookmark->addAdditionalContentEntry( | |
272 | 'search_highlight', | |
273 | ['tags' => [ | |
274 | ['start' => 0, 'end' => 12], // coding-style | |
275 | ['start' => 23, 'end' => 30], // quality | |
276 | ['start' => 31, 'end' => 40], // assurance | |
277 | ],] | |
278 | ); | |
279 | ||
280 | $link = $this->formatter->format($bookmark); | |
281 | ||
282 | $this->assertSame( | |
283 | [ | |
284 | '<span class="search-highlight">coding-style</span>', | |
285 | 'standards', | |
286 | '<span class="search-highlight">quality</span>', | |
287 | '<span class="search-highlight">assurance</span>', | |
288 | ], | |
289 | $link['taglist_html'] | |
290 | ); | |
291 | } | |
740b32b5 A |
292 | |
293 | /** | |
294 | * Test default formatting with formatter_settings.autolink set to false: | |
295 | * URLs and hashtags should not be transformed | |
296 | */ | |
297 | public function testFormatDescriptionWithoutLinkification(): void | |
298 | { | |
299 | $this->conf->set('formatter_settings.autolink', false); | |
300 | $this->formatter = new BookmarkDefaultFormatter($this->conf, false); | |
301 | ||
302 | $bookmark = new Bookmark(); | |
303 | $bookmark->setDescription('Hi!' . PHP_EOL . 'https://thisisaurl.tld #hashtag'); | |
304 | ||
305 | $link = $this->formatter->format($bookmark); | |
306 | ||
307 | static::assertSame( | |
308 | 'Hi!<br />' . PHP_EOL . 'https://thisisaurl.tld #hashtag', | |
309 | $link['description'] | |
310 | ); | |
311 | } | |
e26e2060 | 312 | } |