1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * See LICENSE.txt included in this distribution for the specific 9 * language governing permissions and limitations under the License. 10 * 11 * When distributing Covered Code, include this CDDL HEADER in each 12 * file and include the License file at LICENSE.txt. 13 * If applicable, add the following below this CDDL HEADER, with the 14 * fields enclosed by brackets "[]" replaced with your own identifying 15 * information: Portions Copyright [yyyy] [name of copyright owner] 16 * 17 * CDDL HEADER END 18 */ 19 20 /* 21 * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. 22 * Portions Copyright (c) 2017, 2019, Chris Fraire <cfraire@me.com>. 23 */ 24 package org.opengrok.indexer.web; 25 26 import java.io.ByteArrayInputStream; 27 import java.io.IOException; 28 import java.io.StringWriter; 29 import java.net.MalformedURLException; 30 import java.net.URISyntaxException; 31 import java.net.URL; 32 import java.nio.charset.StandardCharsets; 33 import java.util.List; 34 import java.util.Locale; 35 import java.util.Map; 36 import java.util.TreeMap; 37 import java.util.regex.Pattern; 38 import javax.xml.parsers.DocumentBuilderFactory; 39 40 import jakarta.servlet.http.HttpServletRequest; 41 import org.junit.jupiter.api.AfterAll; 42 import org.junit.jupiter.api.BeforeAll; 43 import org.junit.jupiter.api.Test; 44 import org.junit.jupiter.api.condition.EnabledOnOs; 45 import org.junit.jupiter.api.condition.OS; 46 47 import static org.hamcrest.MatcherAssert.assertThat; 48 import static org.hamcrest.collection.IsIterableContainingInOrder.contains; 49 import static org.junit.jupiter.api.Assertions.assertEquals; 50 import static org.junit.jupiter.api.Assertions.assertFalse; 51 import static org.junit.jupiter.api.Assertions.assertNull; 52 import static org.junit.jupiter.api.Assertions.assertThrows; 53 import static org.junit.jupiter.api.Assertions.assertTrue; 54 55 /** 56 * Test of the methods in <code>org.opengrok.indexer.web.Util</code>. 57 */ 58 public class UtilTest { 59 60 private static Locale savedLocale; 61 62 @BeforeAll setUpClass()63 public static void setUpClass() { 64 // Some of the methods have different results in different locales. 65 // Set locale to en_US for these tests. 66 savedLocale = Locale.getDefault(); 67 Locale.setDefault(Locale.US); 68 } 69 70 @AfterAll tearDownClass()71 public static void tearDownClass() { 72 Locale.setDefault(savedLocale); 73 savedLocale = null; 74 } 75 76 @Test htmlize()77 public void htmlize() throws IOException { 78 String[][] input_output = { 79 {"This is a test", "This is a test"}, 80 {"Newline\nshould become <br/>", "Newline<br/>should become <br/>"}, 81 {"Open & Grok", "Open & Grok"}, 82 {"&<>", "&amp;&lt;&gt;"}}; 83 for (String[] in_out : input_output) { 84 // 1 arg 85 assertEquals(in_out[1], Util.htmlize(in_out[0])); 86 // 2 args 87 StringBuilder sb = new StringBuilder(); 88 Util.htmlize(in_out[0], sb); 89 assertEquals(in_out[1], sb.toString()); 90 } 91 } 92 93 @Test breadcrumbPath()94 public void breadcrumbPath() { 95 assertNull(Util.breadcrumbPath("/root/", null)); 96 97 assertEquals("", Util.breadcrumbPath("/root/", "")); 98 99 assertEquals("<a href=\"/root/x\">x</a>", 100 Util.breadcrumbPath("/root/", "x")); 101 assertEquals("<a href=\"/root/xx\">xx</a>", 102 Util.breadcrumbPath("/root/", "xx")); 103 104 // parent directories have a trailing slash in href 105 assertEquals("<a href=\"/r/a/\">a</a>/<a href=\"/r/a/b\">b</a>", 106 Util.breadcrumbPath("/r/", "a/b")); 107 // if basename is a dir (ends with file seperator), href link also 108 // ends with a '/' 109 assertEquals("<a href=\"/r/a/\">a</a>/<a href=\"/r/a/b/\">b</a>/", 110 Util.breadcrumbPath("/r/", "a/b/")); 111 // should work the same way with a '.' as file separator 112 assertEquals("<a href=\"/r/java/\">java</a>." 113 + "<a href=\"/r/java/lang/\">lang</a>." 114 + "<a href=\"/r/java/lang/String\">String</a>", 115 Util.breadcrumbPath("/r/", "java.lang.String", '.')); 116 // suffix added to the link? 117 assertEquals("<a href=\"/root/xx&project=y\">xx</a>", 118 Util.breadcrumbPath("/root/", "xx", '/', "&project=y", false)); 119 // compact: path needs to be resolved to /xx and no link is added 120 // for the virtual root directory (parent) but emitted as plain text. 121 // Prefix gets just prefixed as is and not mangled wrt. path -> "//" 122 assertEquals("/<a href=\"/root//xx&project=y\">xx</a>", 123 Util.breadcrumbPath("/root/", "../xx", '/', "&project=y", true)); 124 // relative pathes are resolved wrt. / , so path resolves to /a/c/d 125 assertEquals("/<a href=\"/r//a/\">a</a>/" 126 + "<a href=\"/r//a/c/\">c</a>/" 127 + "<a href=\"/r//a/c/d\">d</a>", 128 Util.breadcrumbPath("/r/", "../a/b/../c//d", '/', "", true)); 129 } 130 131 @Test redableSize()132 public void redableSize() { 133 assertEquals("0 ", Util.readableSize(0)); 134 assertEquals("1 ", Util.readableSize(1)); 135 assertEquals("-1 ", Util.readableSize(-1)); 136 assertEquals("1,000 ", Util.readableSize(1000)); 137 assertEquals("1 KiB", Util.readableSize(1024)); 138 assertEquals("2.4 KiB", Util.readableSize(2500)); 139 assertEquals("<b>1.4 MiB</b>", Util.readableSize(1474560)); 140 assertEquals("<b>3.5 GiB</b>", Util.readableSize(3758489600L)); 141 assertEquals("<b>8,589,934,592 GiB</b>", 142 Util.readableSize(Long.MAX_VALUE)); 143 } 144 145 @Test readableLine()146 public void readableLine() throws Exception { 147 StringWriter out = new StringWriter(); 148 // hmmm - where do meaningful tests start? 149 Util.readableLine(42, out, null, null, null, null); 150 assertEquals("\n<a class=\"l\" name=\"42\" href=\"#42\">42</a>", 151 out.toString()); 152 153 out.getBuffer().setLength(0); // clear buffer 154 Util.readableLine(110, out, null, null, null, null); 155 assertEquals("\n<a class=\"hl\" name=\"110\" href=\"#110\">110</a>", 156 out.toString()); 157 } 158 159 @Test path2uid()160 public void path2uid() { 161 assertEquals("\u0000etc\u0000passwd\u0000date", 162 Util.path2uid("/etc/passwd", "date")); 163 } 164 165 @Test 166 @EnabledOnOs(OS.WINDOWS) fixPathIfWindows()167 void fixPathIfWindows() { 168 assertEquals("/var/opengrok", Util.fixPathIfWindows("\\var\\opengrok")); 169 } 170 171 @Test uid2url()172 public void uid2url() { 173 assertEquals("/etc/passwd", Util.uid2url( 174 Util.path2uid("/etc/passwd", "date"))); 175 } 176 177 @Test testUriEncode()178 public void testUriEncode() { 179 assertEquals("", Util.uriEncode("")); 180 assertEquals("a+b", Util.uriEncode("a b")); 181 assertEquals("a%23b", Util.uriEncode("a#b")); 182 assertEquals("a%2Fb", Util.uriEncode("a/b")); 183 assertEquals("README.txt", Util.uriEncode("README.txt")); 184 } 185 186 @Test testUriEncodePath()187 public void testUriEncodePath() { 188 assertEquals("", Util.uriEncodePath("")); 189 assertEquals("/", Util.uriEncodePath("/")); 190 assertEquals("a", Util.uriEncodePath("a")); 191 assertEquals("%09", Util.uriEncodePath("\t")); 192 assertEquals("a%2Bb", Util.uriEncodePath("a+b")); 193 assertEquals("a%20b", Util.uriEncodePath("a b")); 194 assertEquals("/a//x/yz/%23%23/%20/%20%3F", 195 Util.uriEncodePath("/a//x/yz/##/ / ?")); 196 assertEquals("foo%3A%3Abar%3A%3Atest.js", 197 Util.uriEncodePath("foo::bar::test.js")); 198 assertEquals("bl%C3%A5b%C3%A6rsyltet%C3%B8y", 199 Util.uriEncodePath("bl\u00E5b\u00E6rsyltet\u00F8y")); 200 } 201 202 @Test formQuoteEscape()203 public void formQuoteEscape() { 204 assertEquals("", Util.formQuoteEscape(null)); 205 assertEquals("abc", Util.formQuoteEscape("abc")); 206 assertEquals(""abc"", Util.formQuoteEscape("\"abc\"")); 207 assertEquals("&aring;", Util.formQuoteEscape("å")); 208 } 209 210 @Test diffline()211 public void diffline() { 212 String[][] tests = { 213 { 214 "if (a < b && foo < bar && c > d)", 215 "if (a < b && foo > bar && c > d)", 216 "if (a < b && foo <span class=\"d\"><</span> bar && c > d)", 217 "if (a < b && foo <span class=\"a\">></span> bar && c > d)" 218 }, 219 { 220 "foo << 1", 221 "foo >> 1", 222 "foo <span class=\"d\"><<</span> 1", 223 "foo <span class=\"a\">>></span> 1" 224 }, 225 { 226 "\"(ses_id, mer_id, pass_id, \" + refCol +\" , mer_ref, amnt, " 227 + "cur, ps_id, ret_url, d_req_time, d_req_mil, h_resp_time, " 228 + "h_resp_mil) \"", 229 "\"(ses_id, mer_id, pass_id, \" + refCol +\" , mer_ref, amnt, " 230 + "cur, ps_id, ret_url, exp_url, d_req_time, d_req_mil, " 231 + "h_resp_time, h_resp_mil) \"", 232 ""(ses_id, mer_id, pass_id, " + refCol +" , mer_ref, amnt, " 233 + "cur, ps_id, ret_url, d_req_time, d_req_mil, h_resp_time, " 234 + "h_resp_mil) "", 235 ""(ses_id, mer_id, pass_id, " + refCol +" , mer_ref, amnt, " 236 + "cur, ps_id, ret_url, <span class=\"a\">exp_url, " 237 + "</span>d_req_time, d_req_mil, h_resp_time, h_resp_mil) "" 238 }, 239 { 240 "\"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\", values);", 241 "\"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\", values);", 242 ""VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", values);", 243 ""VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?<span " 244 + "class=\"a\">, ?</span>)", values);" 245 }, 246 { 247 "char *config_list = NULL;", 248 "char **config_list = NULL;", 249 "char *config_list = NULL;", 250 "char *<span class=\"a\">*</span>config_list = NULL;" 251 }, 252 { 253 "char **config_list = NULL;", 254 "char *config_list = NULL;", 255 "char *<span class=\"d\">*</span>config_list = NULL;", 256 "char *config_list = NULL;" 257 }, 258 { 259 "* An error occured or there is non-numeric stuff at the end", 260 "* An error occurred or there is non-numeric stuff at the end", 261 "* An error occured or there is non-numeric stuff at the end", 262 "* An error occur<span class=\"a\">r</span>ed or there is " 263 + "non-numeric stuff at the end" 264 } 265 }; 266 for (int i = 0; i < tests.length; i++) { 267 String[] strings = Util.diffline( 268 new StringBuilder(tests[i][0]), 269 new StringBuilder(tests[i][1])); 270 assertEquals(tests[i][2], strings[0], "" + i + "," + 0); 271 assertEquals(tests[i][3], strings[1], "" + i + "," + 1); 272 } 273 } 274 275 @Test testEncode()276 public void testEncode() { 277 String[][] tests = new String[][] { 278 {"Test <code>title</code>", "Test <code>title</code>"}, 279 {"ahoj", "ahoj"}, 280 {"<>|&\"'", "<>|&"'"}, 281 {"tab\ttab", "tab tab"}, 282 {"multi\nline\t\nstring", "multi<br/>line <br/>string"} 283 }; 284 285 for (String[] test : tests) { 286 assertEquals(test[1], Util.encode(test[0])); 287 } 288 } 289 290 @Test dumpConfiguration()291 public void dumpConfiguration() throws Exception { 292 StringBuilder out = new StringBuilder(); 293 Util.dumpConfiguration(out); 294 String s = out.toString(); 295 296 // Verify that we got a table. 297 assertTrue(s.startsWith("<table")); 298 299 // Verify that the output is well-formed. 300 String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + s; 301 DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( 302 new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))); 303 } 304 305 @Test jsStringLiteral()306 public void jsStringLiteral() { 307 assertEquals("\"abc\\n\\r\\\"\\\\\"", 308 Util.jsStringLiteral("abc\n\r\"\\")); 309 } 310 311 @Test stripPathPrefix()312 public void stripPathPrefix() { 313 assertEquals("/", Util.stripPathPrefix("/", "/")); 314 assertEquals("/abc", Util.stripPathPrefix("/abc", "/abc")); 315 assertEquals("/abc/", Util.stripPathPrefix("/abc", "/abc/")); 316 assertEquals("/abc", Util.stripPathPrefix("/abc/", "/abc")); 317 assertEquals("/abc/", Util.stripPathPrefix("/abc/", "/abc/")); 318 assertEquals("abc", Util.stripPathPrefix("/", "/abc")); 319 assertEquals("abc/def", Util.stripPathPrefix("/", "/abc/def")); 320 assertEquals("def", Util.stripPathPrefix("/abc", "/abc/def")); 321 assertEquals("def", Util.stripPathPrefix("/abc/", "/abc/def")); 322 assertEquals("/abcdef", Util.stripPathPrefix("/abc", "/abcdef")); 323 assertEquals("/abcdef", Util.stripPathPrefix("/abc/", "/abcdef")); 324 assertEquals("def/ghi", Util.stripPathPrefix("/abc", "/abc/def/ghi")); 325 assertEquals("def/ghi", Util.stripPathPrefix("/abc/", "/abc/def/ghi")); 326 } 327 328 @Test testSlider()329 public void testSlider() { 330 /* 331 * Test if contains all five pages for 55 results paginated by 10 332 */ 333 for (int i = 0; i < 10; i++) { 334 for (int j = 1; j <= 5; j++) { 335 assertTrue(Util.createSlider(i * 10, 10, 55).contains(">" + j + "<"), "Contains page " + j); 336 } 337 } 338 339 assertFalse(Util.createSlider(0, 10, 4).contains(">1<"), "Does not contain page 1"); 340 assertFalse(Util.createSlider(0, 10, 2).contains(">5<"), "Does not contain page 5"); 341 assertFalse(Util.createSlider(0, 10, 0).contains(">1<"), "Does not contain page 1"); 342 } 343 344 @Test testIsUrl()345 public void testIsUrl() { 346 assertTrue(Util.isHttpUri("http://www.example.com")); 347 assertTrue(Util.isHttpUri("http://example.com")); 348 assertTrue(Util.isHttpUri("https://example.com")); 349 assertTrue(Util.isHttpUri("https://www.example.com")); 350 assertTrue(Util.isHttpUri("http://www.example.com?param=1¶m2=2")); 351 assertTrue(Util.isHttpUri("http://www.example.com/other/page")); 352 assertTrue(Util.isHttpUri("https://www.example.com?param=1¶m2=2")); 353 assertTrue(Util.isHttpUri("https://www.example.com/other/page")); 354 assertTrue(Util.isHttpUri("http://www.example.com:80/other/page")); 355 assertTrue(Util.isHttpUri("http://www.example.com:8080/other/page")); 356 assertTrue(Util.isHttpUri("https://www.example.com:80/other/page")); 357 assertTrue(Util.isHttpUri("https://www.example.com:8080/other/page")); 358 359 assertFalse(Util.isHttpUri("git@github.com:OpenGrok/OpenGrok")); 360 assertFalse(Util.isHttpUri("hg@mercurial.com:OpenGrok/OpenGrok")); 361 assertFalse(Util.isHttpUri("ssh://git@github.com:OpenGrok/OpenGrok")); 362 assertFalse(Util.isHttpUri("ldap://example.com/OpenGrok/OpenGrok")); 363 assertFalse(Util.isHttpUri("smtp://example.com/OpenGrok/OpenGrok")); 364 } 365 366 @Test testRedactUrl()367 public void testRedactUrl() { 368 assertEquals("/foo/bar", Util.redactUrl("/foo/bar")); 369 assertEquals("http://foo/bar?r=xxx", Util.redactUrl("http://foo/bar?r=xxx")); 370 assertEquals("http://" + Util.REDACTED_USER_INFO + "@foo/bar?r=xxx", 371 Util.redactUrl("http://user@foo/bar?r=xxx")); 372 assertEquals("http://" + Util.REDACTED_USER_INFO + "@foo/bar?r=xxx", 373 Util.redactUrl("http://user:pass@foo/bar?r=xxx")); 374 } 375 376 @Test testLinkify()377 public void testLinkify() throws URISyntaxException, MalformedURLException { 378 assertTrue(Util.linkify("http://www.example.com") 379 .matches("<a.*?href=\"http://www\\.example\\.com\".*?>.*?</a>")); 380 assertTrue(Util.linkify("https://example.com") 381 .matches("<a.*?href=\"https://example\\.com\".*?>.*?</a>")); 382 assertTrue(Util.linkify("http://www.example.com?param=1¶m2=2") 383 .matches("<a.*?href=\"http://www\\.example\\.com\\?param=1¶m2=2\".*?>.*?</a>")); 384 assertTrue(Util.linkify("https://www.example.com:8080/other/page") 385 .matches("<a.*?href=\"https://www\\.example\\.com:8080/other/page\".*?>.*?</a>")); 386 387 assertTrue(Util.linkify("http://www.example.com", true).contains("target=\"_blank\"")); 388 assertTrue(Util.linkify("https://example.com", true).contains("target=\"_blank\"")); 389 assertTrue(Util.linkify("http://www.example.com?param=1¶m2=2", true).contains("target=\"_blank\"")); 390 assertTrue(Util.linkify("https://www.example.com:8080/other/page", true).contains("target=\"_blank\"")); 391 assertTrue(Util.linkify("https://www.example.com:8080/other/page", true).contains("rel=\"noreferrer\"")); 392 393 assertFalse(Util.linkify("http://www.example.com", false).contains("target=\"_blank\"")); 394 assertFalse(Util.linkify("https://example.com", false).contains("target=\"_blank\"")); 395 assertFalse(Util.linkify("http://www.example.com?param=1¶m2=2", false).contains("target=\"_blank\"")); 396 assertFalse(Util.linkify("https://www.example.com:8080/other/page", false).contains("target=\"_blank\"")); 397 398 assertEquals("git@github.com:OpenGrok/OpenGrok", Util.linkify("git@github.com:OpenGrok/OpenGrok")); 399 assertEquals("hg@mercurial.com:OpenGrok/OpenGrok", Util.linkify("hg@mercurial.com:OpenGrok/OpenGrok")); 400 assertEquals("ssh://git@github.com:OpenGrok/OpenGrok", Util.linkify("ssh://git@github.com:OpenGrok/OpenGrok")); 401 assertEquals("ldap://example.com/OpenGrok/OpenGrok", Util.linkify("ldap://example.com/OpenGrok/OpenGrok")); 402 assertEquals("smtp://example.com/OpenGrok/OpenGrok", Util.linkify("smtp://example.com/OpenGrok/OpenGrok")); 403 assertEquals("just some crazy text", Util.linkify("just some crazy text")); 404 405 // escaping url 406 assertTrue(Util.linkify("http://www.example.com/\"quotation\"/else") 407 .contains("href=\"" + Util.encodeURL("http://www.example.com/\"quotation\"/else") + "\"")); 408 assertTrue(Util.linkify("https://example.com/><\"") 409 .contains("href=\"" + Util.encodeURL("https://example.com/><\"") + "\"")); 410 assertTrue(Util.linkify("http://www.example.com?param=1¶m2=2¶m3=\"quoted>\"") 411 .contains("href=\"" + Util.encodeURL("http://www.example.com?param=1¶m2=2¶m3=\"quoted>\"") + "\"")); 412 // escaping titles 413 assertTrue(Util.linkify("http://www.example.com/\"quotation\"/else") 414 .contains("title=\"Link to " + Util.encode("http://www.example.com/\"quotation\"/else") + "\"")); 415 assertTrue(Util.linkify("https://example.com/><\"") 416 .contains("title=\"Link to " + Util.encode("https://example.com/><\"") + "\"")); 417 assertTrue(Util.linkify("http://www.example.com?param=1¶m2=2¶m3=\"quoted>\"") 418 .contains("title=\"Link to " + Util.encode("http://www.example.com?param=1¶m2=2¶m3=\"quoted>\"") + "\"")); 419 } 420 421 @Test testBuildLink()422 public void testBuildLink() throws URISyntaxException, MalformedURLException { 423 assertEquals("<a href=\"http://www.example.com\">link</a>", Util.buildLink("link", "http://www.example.com")); 424 assertEquals("<a href=\"http://www.example.com?url=xasw&beta=gama\">link</a>", 425 Util.buildLink("link", "http://www.example.com?url=xasw&beta=gama")); 426 427 String link = Util.buildLink("link", "http://www.example.com", true); 428 assertTrue(link.contains("href=\"http://www.example.com\"")); 429 assertTrue(link.contains("target=\"_blank\"")); 430 431 link = Util.buildLink("link", "http://www.example.com?url=xasw&beta=gama", true); 432 assertTrue(link.contains("href=\"http://www.example.com?url=xasw&beta=gama\"")); 433 assertTrue(link.contains("target=\"_blank\"")); 434 435 Map<String, String> attrs = new TreeMap<>(); 436 attrs.put("href", "https://www.example.com/abcd/acbd"); 437 attrs.put("title", "Some important title"); 438 attrs.put("data-id", "123456"); 439 440 link = Util.buildLink("link", attrs); 441 assertTrue(link.contains("href=\"https://www.example.com/abcd/acbd\"")); 442 assertTrue(link.contains("title=\"Some important title\"")); 443 assertTrue(link.contains("data-id=\"123456\"")); 444 } 445 446 @Test testBuildLinkInvalidUrl1()447 public void testBuildLinkInvalidUrl1() { 448 assertThrows(MalformedURLException.class, () -> Util.buildLink("link", "www.example.com")); // invalid protocol 449 } 450 451 @Test testBuildLinkInvalidUrl2()452 public void testBuildLinkInvalidUrl2() { 453 assertThrows(URISyntaxException.class, () -> Util.buildLink("link", "http://www.exa\"mp\"le.com")); // invalid authority 454 } 455 456 @Test testLinkifyPattern()457 public void testLinkifyPattern() { 458 String text 459 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " 460 + "sed do eiusmod tempor incididunt as per 12345698 ut labore et dolore magna " 461 + "aliqua. bug3333fff Ut enim ad minim veniam, quis nostrud exercitation " 462 + "ullamco laboris nisi ut aliquip ex ea introduced in 9791216541 commodo consequat. " 463 + "Duis aute irure dolor in reprehenderit in voluptate velit " 464 + "esse cillum dolore eu fixes 132469187 fugiat nulla pariatur. Excepteur sint " 465 + "occaecat bug6478abc cupidatat non proident, sunt in culpa qui officia " 466 + "deserunt mollit anim id est laborum."; 467 String expected 468 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " 469 + "sed do eiusmod tempor incididunt as per " 470 + "<a href=\"http://www.example.com?bug=12345698\" rel=\"noreferrer\" target=\"_blank\">12345698</a>" 471 + " ut labore et dolore magna " 472 + "aliqua. bug3333fff Ut enim ad minim veniam, quis nostrud exercitation " 473 + "ullamco laboris nisi ut aliquip ex ea introduced in " 474 + "<a href=\"http://www.example.com?bug=9791216541\" rel=\"noreferrer\" target=\"_blank\">9791216541</a>" 475 + " commodo consequat. " 476 + "Duis aute irure dolor in reprehenderit in voluptate velit " 477 + "esse cillum dolore eu fixes " 478 + "<a href=\"http://www.example.com?bug=132469187\" rel=\"noreferrer\" target=\"_blank\">132469187</a>" 479 + " fugiat nulla pariatur. Excepteur sint " 480 + "occaecat bug6478abc cupidatat non proident, sunt in culpa qui officia " 481 + "deserunt mollit anim id est laborum."; 482 String expected2 483 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " 484 + "sed do eiusmod tempor incididunt as per 12345698 ut labore et dolore magna " 485 + "aliqua. " 486 + "<a href=\"http://www.other-example.com?bug=3333\" rel=\"noreferrer\" target=\"_blank\">bug3333fff</a>" 487 + " Ut enim ad minim veniam, quis nostrud exercitation " 488 + "ullamco laboris nisi ut aliquip ex ea introduced in 9791216541 commodo consequat. " 489 + "Duis aute irure dolor in reprehenderit in voluptate velit " 490 + "esse cillum dolore eu fixes 132469187 fugiat nulla pariatur. Excepteur sint " 491 + "occaecat " 492 + "<a href=\"http://www.other-example.com?bug=6478\" rel=\"noreferrer\" target=\"_blank\">bug6478abc</a>" 493 + " cupidatat non proident, sunt in culpa qui officia " 494 + "deserunt mollit anim id est laborum."; 495 496 assertEquals(expected, Util.linkifyPattern(text, Pattern.compile("\\b([0-9]{8,})\\b"), "$1", "http://www.example.com?bug=$1")); 497 assertEquals(expected2, Util.linkifyPattern(text, Pattern.compile("\\b(bug([0-9]{4})\\w{3})\\b"), "$1", 498 "http://www.other-example.com?bug=$2")); 499 } 500 501 @Test testCompleteUrl()502 public void testCompleteUrl() { 503 HttpServletRequest req = new DummyHttpServletRequest() { 504 @Override 505 public int getServerPort() { 506 return 8080; 507 } 508 509 @Override 510 public String getServerName() { 511 return "www.example.com"; 512 } 513 514 @Override 515 public String getScheme() { 516 return "http"; 517 } 518 519 @Override 520 public StringBuffer getRequestURL() { 521 return new StringBuffer(getScheme() + "://" + getServerName() + ':' + getServerPort() + "/source/location/undefined"); 522 } 523 }; 524 525 // Absolute including hostname. 526 assertEquals("http://opengrok.com/user=", Util.completeUrl("http://opengrok.com/user=", req)); 527 assertEquals("http://opengrok.cz.grok.com/user=", Util.completeUrl("http://opengrok.cz.grok.com/user=", req)); 528 assertEquals("http://opengrok.com/user=123&id=", Util.completeUrl("http://opengrok.com/user=123&id=", req)); 529 530 // Absolute/relative without the hostname. 531 assertEquals("http://www.example.com:8080/cgi-bin/user=", Util.completeUrl("/cgi-bin/user=", req)); 532 assertEquals("http://www.example.com:8080/cgi-bin/user=123&id=", Util.completeUrl("/cgi-bin/user=123&id=", req)); 533 assertEquals("http://www.example.com:8080/source/location/undefined/cgi-bin/user=", Util.completeUrl("cgi-bin/user=", req)); 534 assertEquals("http://www.example.com:8080/source/location/undefined/cgi-bin/user=123&id=", Util.completeUrl("cgi-bin/user=123&id=", req)); 535 536 assertEquals("http://www.example.com:8080/source/location/undefined", Util.completeUrl("", req)); 537 538 // Escaping should work. 539 assertEquals("http://www.example.com:8080/cgi-%22bin/user=123&id=", Util.completeUrl("/cgi-\"bin/user=123&id=", req)); 540 } 541 542 @Test getQueryParamsNullTest()543 public void getQueryParamsNullTest() { 544 assertThrows(IllegalArgumentException.class, () -> Util.getQueryParams(null)); 545 } 546 547 @Test getQueryParamsEmptyTest()548 public void getQueryParamsEmptyTest() throws MalformedURLException { 549 URL url = new URL("http://test.com/test"); 550 assertTrue(Util.getQueryParams(url).isEmpty()); 551 } 552 553 @Test getQueryParamsEmptyTest2()554 public void getQueryParamsEmptyTest2() throws MalformedURLException { 555 URL url = new URL("http://test.com/test?"); 556 assertTrue(Util.getQueryParams(url).isEmpty()); 557 } 558 559 @Test getQueryParamsSingleTest()560 public void getQueryParamsSingleTest() throws MalformedURLException { 561 URL url = new URL("http://test.com?param1=value1"); 562 Map<String, List<String>> params = Util.getQueryParams(url); 563 564 assertEquals(1, params.size()); 565 566 assertThat(params.get("param1"), contains("value1")); 567 } 568 569 @Test getQueryParamsMultipleTest()570 public void getQueryParamsMultipleTest() throws MalformedURLException { 571 URL url = new URL("http://test.com?param1=value1¶m2=value2"); 572 Map<String, List<String>> params = Util.getQueryParams(url); 573 574 assertEquals(2, params.size()); 575 576 assertThat(params.get("param1"), contains("value1")); 577 assertThat(params.get("param2"), contains("value2")); 578 } 579 580 @Test getQueryParamsMultipleSameTest()581 public void getQueryParamsMultipleSameTest() throws MalformedURLException { 582 URL url = new URL("http://test.com?param1=value1¶m1=value2"); 583 Map<String, List<String>> params = Util.getQueryParams(url); 584 585 assertEquals(1, params.size()); 586 587 assertThat(params.get("param1"), contains("value1", "value2")); 588 } 589 590 @Test getQueryParamsEncodedTest()591 public void getQueryParamsEncodedTest() throws MalformedURLException { 592 URL url = new URL("http://test.com?param1=%3Fvalue%3F"); 593 Map<String, List<String>> params = Util.getQueryParams(url); 594 595 assertEquals(1, params.size()); 596 597 assertThat(params.get("param1"), contains("?value?")); 598 } 599 600 @Test getQueryParamsEmptyValueTest()601 public void getQueryParamsEmptyValueTest() throws MalformedURLException { 602 URL url = new URL("http://test.com?param1="); 603 604 Map<String, List<String>> params = Util.getQueryParams(url); 605 606 assertThat(params.get("param1"), contains("")); 607 } 608 609 @Test getQueryParamsEmptyAndNormalValuesCombinedTest()610 public void getQueryParamsEmptyAndNormalValuesCombinedTest() throws MalformedURLException { 611 URL url = new URL("http://test.com?param1=value1¶m2=¶m3¶m4=value4"); 612 613 Map<String, List<String>> params = Util.getQueryParams(url); 614 615 assertThat(params.get("param1"), contains("value1")); 616 assertThat(params.get("param2"), contains("")); 617 assertTrue(params.containsKey("param3")); 618 assertThat(params.get("param4"), contains("value4")); 619 } 620 621 } 622