/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* See LICENSE.txt included in this distribution for the specific
* language governing permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at LICENSE.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
*/
package org.opensolaris.opengrok.web;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilderFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Test of the methods in <code>org.opensolaris.opengrok.web.Util</code>.
*/
public class UtilTest {
private static Locale savedLocale;
@BeforeClass
public static void setUpClass() {
// Some of the methods have different results in different locales.
// Set locale to en_US for these tests.
savedLocale = Locale.getDefault();
Locale.setDefault(Locale.US);
}
@AfterClass
public static void tearDownClass() {
Locale.setDefault(savedLocale);
savedLocale = null;
}
@Test
public void htmlize() throws IOException {
String[][] input_output = {
{"This is a test", "This is a test"},
{"Newline\nshould become <br/>",
"Newline<br/>should become <br/>"},
{"Open & Grok", "Open & Grok"},
{"&<>", "&<>"},};
for (String[] in_out : input_output) {
// 1 arg
assertEquals(in_out[1], Util.htmlize(in_out[0]));
// 2 args
StringBuilder sb = new StringBuilder();
Util.htmlize(in_out[0], sb);
assertEquals(in_out[1], sb.toString());
}
}
@Test
public void breadcrumbPath() {
assertEquals(null, Util.breadcrumbPath("/root/", null));
assertEquals("", Util.breadcrumbPath("/root/", ""));
assertEquals("<a href=\"/root/x\">x</a>",
Util.breadcrumbPath("/root/", "x"));
assertEquals("<a href=\"/root/xx\">xx</a>",
Util.breadcrumbPath("/root/", "xx"));
// parent directories have a trailing slash in href
assertEquals("<a href=\"/r/a/\">a</a>/<a href=\"/r/a/b\">b</a>",
Util.breadcrumbPath("/r/", "a/b"));
// if basename is a dir (ends with file seperator), href link also
// ends with a '/'
assertEquals("<a href=\"/r/a/\">a</a>/<a href=\"/r/a/b/\">b</a>/",
Util.breadcrumbPath("/r/", "a/b/"));
// should work the same way with a '.' as file separator
assertEquals("<a href=\"/r/java/\">java</a>."
+ "<a href=\"/r/java/lang/\">lang</a>."
+ "<a href=\"/r/java/lang/String\">String</a>",
Util.breadcrumbPath("/r/", "java.lang.String", '.'));
// suffix added to the link?
assertEquals("<a href=\"/root/xx&project=y\">xx</a>",
Util.breadcrumbPath("/root/", "xx", '/', "&project=y", false));
// compact: path needs to be resolved to /xx and no link is added
// for the virtual root directory (parent) but emitted as plain text.
// Prefix gets just prefixed as is and not mangled wrt. path -> "//"
assertEquals("/<a href=\"/root//xx&project=y\">xx</a>",
Util.breadcrumbPath("/root/", "../xx", '/', "&project=y", true));
// relative pathes are resolved wrt. / , so path resolves to /a/c/d
assertEquals("/<a href=\"/r//a/\">a</a>/"
+ "<a href=\"/r//a/c/\">c</a>/"
+ "<a href=\"/r//a/c/d\">d</a>",
Util.breadcrumbPath("/r/", "../a/b/../c//d", '/', "", true));
}
@Test
public void redableSize() {
assertEquals("0 ", Util.readableSize(0));
assertEquals("1 ", Util.readableSize(1));
assertEquals("-1 ", Util.readableSize(-1));
assertEquals("1,000 ", Util.readableSize(1000));
assertEquals("1 KiB", Util.readableSize(1024));
assertEquals("2.4 KiB", Util.readableSize(2500));
assertEquals("<b>1.4 MiB</b>", Util.readableSize(1474560));
assertEquals("<b>3.5 GiB</b>", Util.readableSize(3758489600L));
assertEquals("<b>8,589,934,592 GiB</b>",
Util.readableSize(Long.MAX_VALUE));
}
@Test
public void readableLine() throws Exception {
StringWriter out = new StringWriter();
// hmmm - where do meaningful tests start?
Util.readableLine(42, out, null, null, null, null);
assertEquals("\n<a class=\"l\" name=\"42\" href=\"#42\">42</a>",
out.toString());
out.getBuffer().setLength(0); // clear buffer
Util.readableLine(110, out, null, null, null, null);
assertEquals("\n<a class=\"hl\" name=\"110\" href=\"#110\">110</a>",
out.toString());
}
@Test
public void path2uid() {
assertEquals("\u0000etc\u0000passwd\u0000date",
Util.path2uid("/etc/passwd", "date"));
}
@Test
public void uid2url() {
assertEquals("/etc/passwd", Util.uid2url(
Util.path2uid("/etc/passwd", "date")));
}
@Test
public void URIEncode() {
assertEquals("", Util.URIEncode(""));
assertEquals("a+b", Util.URIEncode("a b"));
assertEquals("a%23b", Util.URIEncode("a#b"));
assertEquals("a%2Fb", Util.URIEncode("a/b"));
assertEquals("README.txt", Util.URIEncode("README.txt"));
}
@Test
public void URIEncodePath() {
assertEquals("", Util.URIEncodePath(""));
assertEquals("/", Util.URIEncodePath("/"));
assertEquals("a", Util.URIEncodePath("a"));
assertEquals("%09", Util.URIEncodePath("\t"));
assertEquals("a%2Bb", Util.URIEncodePath("a+b"));
assertEquals("a%20b", Util.URIEncodePath("a b"));
assertEquals("/a//x/yz/%23%23/%20/%20%3F",
Util.URIEncodePath("/a//x/yz/##/ / ?"));
assertEquals("foo%3A%3Abar%3A%3Atest.js",
Util.URIEncodePath("foo::bar::test.js"));
assertEquals("bl%C3%A5b%C3%A6rsyltet%C3%B8y",
Util.URIEncodePath("bl\u00E5b\u00E6rsyltet\u00F8y"));
}
@Test
public void formQuoteEscape() {
assertEquals("", Util.formQuoteEscape(null));
assertEquals("abc", Util.formQuoteEscape("abc"));
assertEquals(""abc"", Util.formQuoteEscape("\"abc\""));
assertEquals("å", Util.formQuoteEscape("å"));
}
@Test
public void diffline() {
String[][] tests = {
{
"if (a < b && foo < bar && c > d)",
"if (a < b && foo > bar && c > d)",
"if (a < b && foo <span class=\"d\"><</span> bar && c > d)",
"if (a < b && foo <span class=\"a\">></span> bar && c > d)"
},
{
"foo << 1",
"foo >> 1",
"foo <span class=\"d\"><<</span> 1",
"foo <span class=\"a\">>></span> 1"
},
{
"\"(ses_id, mer_id, pass_id, \" + refCol +\" , mer_ref, amnt, "
+ "cur, ps_id, ret_url, d_req_time, d_req_mil, h_resp_time, "
+ "h_resp_mil) \"",
"\"(ses_id, mer_id, pass_id, \" + refCol +\" , mer_ref, amnt, "
+ "cur, ps_id, ret_url, exp_url, d_req_time, d_req_mil, "
+ "h_resp_time, h_resp_mil) \"",
"\"(ses_id, mer_id, pass_id, \" + refCol +\" , mer_ref, amnt, "
+ "cur, ps_id, ret_url, d_req_time, d_req_mil, h_resp_time, "
+ "h_resp_mil) \"",
"\"(ses_id, mer_id, pass_id, \" + refCol +\" , mer_ref, amnt, "
+ "cur, ps_id, ret_url, <span class=\"a\">exp_url, "
+ "</span>d_req_time, d_req_mil, h_resp_time, h_resp_mil) \""
},
{
"\"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\", values);",
"\"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\", values);",
"\"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\", values);",
"\"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?<span "
+ "class=\"a\">, ?</span>)\", values);"
},
{
"char *config_list = NULL;",
"char **config_list = NULL;",
"char *config_list = NULL;",
"char *<span class=\"a\">*</span>config_list = NULL;"
},
{
"char **config_list = NULL;",
"char *config_list = NULL;",
"char *<span class=\"d\">*</span>config_list = NULL;",
"char *config_list = NULL;"
},
{
"* An error occured or there is non-numeric stuff at the end",
"* An error occurred or there is non-numeric stuff at the end",
"* An error occured or there is non-numeric stuff at the end",
"* An error occur<span class=\"a\">r</span>ed or there is "
+ "non-numeric stuff at the end"
}
};
for (int i = 0; i < tests.length; i++) {
String[] strings = Util.diffline(
new StringBuilder(tests[i][0]),
new StringBuilder(tests[i][1]));
assertEquals("" + i + "," + 0, tests[i][2], strings[0]);
assertEquals("" + i + "," + 1, tests[i][3], strings[1]);
}
}
@Test
public void testEncode() {
String[][] tests = new String[][]{
{"Test <code>title</code>", "Test <code>title</code>"},
{"ahoj", "ahoj"},
{"<>|&\"'", "<>|&"'"},
{"tab\ttab", "tab tab"},
{"multi\nline\t\nstring", "multi<br/>line <br/>string"}
};
for (String[] test : tests) {
assertEquals(test[1], Util.encode(test[0]));
}
}
@Test
public void dumpConfiguration() throws Exception {
StringBuilder out = new StringBuilder();
Util.dumpConfiguration(out);
String s = out.toString();
// Verify that we got a table.
assertTrue(s.startsWith("<table"));
// Verify that the output is well-formed.
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + s;
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
new ByteArrayInputStream(xml.getBytes("UTF-8")));
}
@Test
public void jsStringLiteral() {
assertEquals("\"abc\\n\\r\\\"\\\\\"",
Util.jsStringLiteral("abc\n\r\"\\"));
}
@Test
public void stripPathPrefix() {
assertEquals("/", Util.stripPathPrefix("/", "/"));
assertEquals("/abc", Util.stripPathPrefix("/abc", "/abc"));
assertEquals("/abc/", Util.stripPathPrefix("/abc", "/abc/"));
assertEquals("/abc", Util.stripPathPrefix("/abc/", "/abc"));
assertEquals("/abc/", Util.stripPathPrefix("/abc/", "/abc/"));
assertEquals("abc", Util.stripPathPrefix("/", "/abc"));
assertEquals("abc/def", Util.stripPathPrefix("/", "/abc/def"));
assertEquals("def", Util.stripPathPrefix("/abc", "/abc/def"));
assertEquals("def", Util.stripPathPrefix("/abc/", "/abc/def"));
assertEquals("/abcdef", Util.stripPathPrefix("/abc", "/abcdef"));
assertEquals("/abcdef", Util.stripPathPrefix("/abc/", "/abcdef"));
assertEquals("def/ghi", Util.stripPathPrefix("/abc", "/abc/def/ghi"));
assertEquals("def/ghi", Util.stripPathPrefix("/abc/", "/abc/def/ghi"));
}
@Test
public void testSlider() {
/*
* Test if contains all five pages for 55 results paginated by 10
*/
for (int i = 0; i < 10; i++) {
for (int j = 1; j <= 5; j++) {
assertTrue("Contains page " + j, Util.createSlider(i * 10, 10, 55).contains(">" + j + "<"));
}
}
assertFalse("Does not contain page 1", Util.createSlider(0, 10, 4).contains(">1<"));
assertFalse("Does not contain page 5", Util.createSlider(0, 10, 2).contains(">5<"));
assertFalse("Does not contain page 1", Util.createSlider(0, 10, 0).contains(">1<"));
}
@Test
public void testIsUrl() {
assertTrue(Util.isHttpUri("http://www.example.com"));
assertTrue(Util.isHttpUri("http://example.com"));
assertTrue(Util.isHttpUri("https://example.com"));
assertTrue(Util.isHttpUri("https://www.example.com"));
assertTrue(Util.isHttpUri("http://www.example.com?param=1¶m2=2"));
assertTrue(Util.isHttpUri("http://www.example.com/other/page"));
assertTrue(Util.isHttpUri("https://www.example.com?param=1¶m2=2"));
assertTrue(Util.isHttpUri("https://www.example.com/other/page"));
assertTrue(Util.isHttpUri("http://www.example.com:80/other/page"));
assertTrue(Util.isHttpUri("http://www.example.com:8080/other/page"));
assertTrue(Util.isHttpUri("https://www.example.com:80/other/page"));
assertTrue(Util.isHttpUri("https://www.example.com:8080/other/page"));
assertFalse(Util.isHttpUri("git@github.com:OpenGrok/OpenGrok"));
assertFalse(Util.isHttpUri("hg@mercurial.com:OpenGrok/OpenGrok"));
assertFalse(Util.isHttpUri("ssh://git@github.com:OpenGrok/OpenGrok"));
assertFalse(Util.isHttpUri("ldap://example.com/OpenGrok/OpenGrok"));
assertFalse(Util.isHttpUri("smtp://example.com/OpenGrok/OpenGrok"));
}
@Test
public void testLinkify() throws URISyntaxException, MalformedURLException {
assertTrue(Util.linkify("http://www.example.com")
.matches("<a.*?href=\"http://www\\.example\\.com\".*?>.*?</a>"));
assertTrue(Util.linkify("https://example.com")
.matches("<a.*?href=\"https://example\\.com\".*?>.*?</a>"));
assertTrue(Util.linkify("http://www.example.com?param=1¶m2=2")
.matches("<a.*?href=\"http://www\\.example\\.com\\?param=1¶m2=2\".*?>.*?</a>"));
assertTrue(Util.linkify("https://www.example.com:8080/other/page")
.matches("<a.*?href=\"https://www\\.example\\.com:8080/other/page\".*?>.*?</a>"));
assertTrue(Util.linkify("http://www.example.com", true).contains("target=\"_blank\""));
assertTrue(Util.linkify("https://example.com", true).contains("target=\"_blank\""));
assertTrue(Util.linkify("http://www.example.com?param=1¶m2=2", true).contains("target=\"_blank\""));
assertTrue(Util.linkify("https://www.example.com:8080/other/page", true).contains("target=\"_blank\""));
assertFalse(Util.linkify("http://www.example.com", false).contains("target=\"_blank\""));
assertFalse(Util.linkify("https://example.com", false).contains("target=\"_blank\""));
assertFalse(Util.linkify("http://www.example.com?param=1¶m2=2", false).contains("target=\"_blank\""));
assertFalse(Util.linkify("https://www.example.com:8080/other/page", false).contains("target=\"_blank\""));
assertTrue(Util.linkify("git@github.com:OpenGrok/OpenGrok").equals("git@github.com:OpenGrok/OpenGrok"));
assertTrue(Util.linkify("hg@mercurial.com:OpenGrok/OpenGrok").equals("hg@mercurial.com:OpenGrok/OpenGrok"));
assertTrue(Util.linkify("ssh://git@github.com:OpenGrok/OpenGrok").equals("ssh://git@github.com:OpenGrok/OpenGrok"));
assertTrue(Util.linkify("ldap://example.com/OpenGrok/OpenGrok").equals("ldap://example.com/OpenGrok/OpenGrok"));
assertTrue(Util.linkify("smtp://example.com/OpenGrok/OpenGrok").equals("smtp://example.com/OpenGrok/OpenGrok"));
assertTrue(Util.linkify("just some crazy text").equals("just some crazy text"));
// escaping url
assertTrue(Util.linkify("http://www.example.com/\"quotation\"/else")
.contains("href=\"" + Util.encodeURL("http://www.example.com/\"quotation\"/else") + "\""));
assertTrue(Util.linkify("https://example.com/><\"")
.contains("href=\"" + Util.encodeURL("https://example.com/><\"") + "\""));
assertTrue(Util.linkify("http://www.example.com?param=1¶m2=2¶m3=\"quoted>\"")
.contains("href=\"" + Util.encodeURL("http://www.example.com?param=1¶m2=2¶m3=\"quoted>\"") + "\""));
// escaping titles
assertTrue(Util.linkify("http://www.example.com/\"quotation\"/else")
.contains("title=\"Link to " + Util.encode("http://www.example.com/\"quotation\"/else") + "\""));
assertTrue(Util.linkify("https://example.com/><\"")
.contains("title=\"Link to " + Util.encode("https://example.com/><\"") + "\""));
assertTrue(Util.linkify("http://www.example.com?param=1¶m2=2¶m3=\"quoted>\"")
.contains("title=\"Link to " + Util.encode("http://www.example.com?param=1¶m2=2¶m3=\"quoted>\"") + "\""));
}
@Test
public void testBuildLink() throws URISyntaxException, MalformedURLException {
assertEquals("<a href=\"http://www.example.com\">link</a>", Util.buildLink("link", "http://www.example.com"));
assertEquals("<a href=\"http://www.example.com?url=xasw&beta=gama\">link</a>", Util.buildLink("link", "http://www.example.com?url=xasw&beta=gama"));
String link = Util.buildLink("link", "http://www.example.com", true);
assertTrue(link.contains("href=\"http://www.example.com\""));
assertTrue(link.contains("target=\"_blank\""));
link = Util.buildLink("link", "http://www.example.com?url=xasw&beta=gama", true);
assertTrue(link.contains("href=\"http://www.example.com?url=xasw&beta=gama\""));
assertTrue(link.contains("target=\"_blank\""));
Map<String, String> attrs = new TreeMap<>();
attrs.put("href", "https://www.example.com/abcd/acbd");
attrs.put("title", "Some important title");
attrs.put("data-id", "123456");
link = Util.buildLink("link", attrs);
assertTrue(link.contains("href=\"https://www.example.com/abcd/acbd\""));
assertTrue(link.contains("title=\"Some important title\""));
assertTrue(link.contains("data-id=\"123456\""));
}
@Test(expected = MalformedURLException.class)
public void testBuildLinkInvalidUrl1() throws URISyntaxException, MalformedURLException {
Util.buildLink("link", "www.example.com"); // invalid protocol
}
@Test(expected = URISyntaxException.class)
public void testBuildLinkInvalidUrl2() throws URISyntaxException, MalformedURLException {
Util.buildLink("link", "http://www.exa\"mp\"le.com"); // invalid authority
}
@Test
public void testLinkifyPattern() {
String text
= "Lorem ipsum dolor sit amet, consectetur adipiscing elit, "
+ "sed do eiusmod tempor incididunt as per 12345698 ut labore et dolore magna "
+ "aliqua. bug3333fff Ut enim ad minim veniam, quis nostrud exercitation "
+ "ullamco laboris nisi ut aliquip ex ea introduced in 9791216541 commodo consequat. "
+ "Duis aute irure dolor in reprehenderit in voluptate velit "
+ "esse cillum dolore eu fixes 132469187 fugiat nulla pariatur. Excepteur sint "
+ "occaecat bug6478abc cupidatat non proident, sunt in culpa qui officia "
+ "deserunt mollit anim id est laborum.";
String expected
= "Lorem ipsum dolor sit amet, consectetur adipiscing elit, "
+ "sed do eiusmod tempor incididunt as per "
+ "<a href=\"http://www.example.com?bug=12345698\" target=\"_blank\">12345698</a> ut labore et dolore magna "
+ "aliqua. bug3333fff Ut enim ad minim veniam, quis nostrud exercitation "
+ "ullamco laboris nisi ut aliquip ex ea introduced in "
+ "<a href=\"http://www.example.com?bug=9791216541\" target=\"_blank\">9791216541</a> commodo consequat. "
+ "Duis aute irure dolor in reprehenderit in voluptate velit "
+ "esse cillum dolore eu fixes "
+ "<a href=\"http://www.example.com?bug=132469187\" target=\"_blank\">132469187</a> fugiat nulla pariatur. Excepteur sint "
+ "occaecat bug6478abc cupidatat non proident, sunt in culpa qui officia "
+ "deserunt mollit anim id est laborum.";
String expected2
= "Lorem ipsum dolor sit amet, consectetur adipiscing elit, "
+ "sed do eiusmod tempor incididunt as per 12345698 ut labore et dolore magna "
+ "aliqua. "
+ "<a href=\"http://www.other-example.com?bug=3333\" target=\"_blank\">bug3333fff</a> Ut enim ad minim veniam, quis nostrud exercitation "
+ "ullamco laboris nisi ut aliquip ex ea introduced in 9791216541 commodo consequat. "
+ "Duis aute irure dolor in reprehenderit in voluptate velit "
+ "esse cillum dolore eu fixes 132469187 fugiat nulla pariatur. Excepteur sint "
+ "occaecat "
+ "<a href=\"http://www.other-example.com?bug=6478\" target=\"_blank\">bug6478abc</a> cupidatat non proident, sunt in culpa qui officia "
+ "deserunt mollit anim id est laborum.";
assertEquals(expected, Util.linkifyPattern(text, Pattern.compile("\\b([0-9]{8,})\\b"), "$1", "http://www.example.com?bug=$1"));
assertEquals(expected2, Util.linkifyPattern(text, Pattern.compile("\\b(bug([0-9]{4})\\w{3})\\b"), "$1", "http://www.other-example.com?bug=$2"));
}
@Test
public void testCompleteUrl() {
HttpServletRequest req = new DummyHttpServletRequest() {
@Override
public int getServerPort() {
return 8080;
}
@Override
public String getServerName() {
return "www.example.com";
}
@Override
public String getScheme() {
return "http";
}
@Override
public StringBuffer getRequestURL() {
return new StringBuffer(getScheme() + "://" + getServerName() + ':' + getServerPort() + "/source/location/undefined");
}
};
/**
* Absolute including hostname.
*/
assertEquals("http://opengrok.com/user=", Util.completeUrl("http://opengrok.com/user=", req));
assertEquals("http://opengrok.cz.grok.com/user=", Util.completeUrl("http://opengrok.cz.grok.com/user=", req));
assertEquals("http://opengrok.com/user=123&id=", Util.completeUrl("http://opengrok.com/user=123&id=", req));
/**
* Absolute/relative without the hostname.
*/
assertEquals("http://www.example.com:8080/cgi-bin/user=", Util.completeUrl("/cgi-bin/user=", req));
assertEquals("http://www.example.com:8080/cgi-bin/user=123&id=", Util.completeUrl("/cgi-bin/user=123&id=", req));
assertEquals("http://www.example.com:8080/source/location/undefined/cgi-bin/user=", Util.completeUrl("cgi-bin/user=", req));
assertEquals("http://www.example.com:8080/source/location/undefined/cgi-bin/user=123&id=", Util.completeUrl("cgi-bin/user=123&id=", req));
assertEquals("http://www.example.com:8080/source/location/undefined", Util.completeUrl("", req));
/**
* Escaping should work.
*/
assertEquals("http://www.example.com:8080/cgi-%22bin/user=123&id=", Util.completeUrl("/cgi-\"bin/user=123&id=", req));
}
}