// Copyright (c) 2009, Richard Kennard
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Richard Kennard nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY RICHARD KENNARD ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL RICHARD KENNARD BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package ste.web.http;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import static org.assertj.core.api.Assertions.fail;
import static org.assertj.core.api.BDDAssertions.then;
import org.junit.Test;
import ste.web.http.QueryString.Separator;
/**
* Unit tests for QueryString
*
* @author Richard Kennard
* @version 1.2
*/
public class BugFreeQueryString {
/**
* Test getters
*/
@Test
public void getters() {
QueryString queryString = QueryString.parse("id=1");
then(queryString.toString()).isEqualTo("id=1");
then(queryString.toString()).isEqualTo("id=1");
queryString = QueryString.parse("x=1&y=2");
then(queryString.toString()).isEqualTo("x=1&y=2");
then("x=1;y=2").isEqualTo(queryString.toString(Separator.SEMICOLON));
then(queryString.get("x")).isEqualTo("1");
then(queryString.getValues("y").get(0)).isEqualTo("2");
then(queryString.getMap().get("y").get(0)).isEqualTo("2");
then(queryString.get("z")).isNull();
then(!queryString.contains("z"));
then(
queryString.getNames()
).hasSize(2).contains("x").contains("y");
// contains
queryString = QueryString.parse("x=1&y=2&z");
then(queryString.get("z")).isNull();
then(queryString.contains("z")).isTrue();
}
/**
* Test setters
*/
@Test
public void setters()
throws URISyntaxException {
// New parameter
QueryString queryString = QueryString.create();
queryString.set("forumId", 3);
then(queryString.toString()).isEqualTo("forumId=3");
queryString.set("forumId", (Number) null);
then(queryString.toString()).isEmpty();
try {
queryString.set(null, "3");
fail("missing check for not nullable parameters");
} catch (NullPointerException e) {
// Should fail
}
try {
queryString.set(null, (String) null);
fail("missing check for not nullable parameters");
} catch (NullPointerException e) {
// Should fail
}
queryString.set("name", "Richard Kennard");
then(queryString.toString()).isEqualTo("name=Richard+Kennard");
queryString.append("name", "Julianne Kennard");
then(queryString.toString()).isEqualTo("name=Richard+Kennard&name=Julianne+Kennard");
queryString.append("name", (String) null).append(null);
then(queryString.toString()).isEqualTo("name=Richard+Kennard&name=Julianne+Kennard&name");
queryString.append("name=Charlotte+Kennard&name=Millie+Kennard");
then(queryString.toString()).isEqualTo("name=Richard+Kennard&name=Julianne+Kennard&name&name=Charlotte+Kennard&name=Millie+Kennard");
queryString.set("name=Charlotte+Kennard;name=Millie+Kennard;add");
then(queryString.toString()).isEqualTo("name=Charlotte+Kennard&name=Millie+Kennard&add");
queryString.remove("name");
then(queryString.toString()).isEqualTo("add");
then(queryString.isEmpty()).isFalse();
queryString.remove("add");
then(queryString.isEmpty()).isTrue();
queryString = QueryString.parse(new URI("http://java.sun.com?a=%3C%3E%26&b=2"));
then(queryString.get("a")).isEqualTo("<>&");
Map<String, List<String>> queryMap = queryString.getMap();
queryMap.get("a").add(0, "foo");
queryMap.put("b", new ArrayList<String>(Arrays.asList("3")));
// (should not have modified original)
then(queryString.toString()).isEqualTo("a=%3C%3E%26&b=2");
queryString = QueryString.create(queryString.getMap());
then(queryString.toString()).isEqualTo("a=%3C%3E%26&b=2");
queryMap.get("a").add(0, "foo");
then(queryString.toString()).isEqualTo("a=%3C%3E%26&b=2");
// Test round-trip
queryString = QueryString.create();
queryString.set("a", "x&y");
queryString.set("b", "u;v");
then(queryString.toString()).isEqualTo("a=x%26y&b=u%3Bv");
queryString = QueryString.parse(queryString.toString());
then(queryString.get("a")).isEqualTo("x&y");
then(queryString.get("b")).isEqualTo("u;v");
}
/**
* Test apply
*/
@Test
public void apply()
throws URISyntaxException {
URI uri = new URI("http://java.sun.com?page=1");
QueryString queryString = QueryString.parse(uri);
queryString.set("page", 2);
uri = queryString.apply(uri);
then(uri.toString()).isEqualTo("http://java.sun.com?page=2");
uri = new URI("/forum.jsp?message=12");
queryString = QueryString.parse(uri).append("reply", 2);
uri = queryString.apply(uri);
then(uri.toString()).isEqualTo("/forum.jsp?message=12&reply=2");
// Test escaping
uri = new URI("http://www.google.com/search?q=foo+bar");
queryString = QueryString.parse(uri);
queryString.set("q", "100%");
uri = queryString.apply(uri);
then(uri.toString()).isEqualTo("http://www.google.com/search?q=100%25");
queryString.append("%", "%25");
uri = queryString.apply(uri);
then(uri.toString()).isEqualTo("http://www.google.com/search?q=100%25&%25=%2525");
queryString.set("q", "a + b = 100%");
queryString.remove("%");
uri = queryString.apply(uri);
then(uri.toString()).isEqualTo("http://www.google.com/search?q=a+%2B+b+%3D+100%25");
// Test different parts of the URI
uri = new URI("http://rkennard@java.sun.com:80#bar");
uri = queryString.apply(uri);
then(uri.toString()).isEqualTo("http://rkennard@java.sun.com:80?q=a+%2B+b+%3D+100%25#bar");
uri = new URI("http", "userinfo", "::192.9.5.5", 8080, "/path", "query", "fragment");
uri = queryString.apply(uri);
then(uri.toString()).isEqualTo("http://userinfo@[::192.9.5.5]:8080/path?q=a+%2B+b+%3D+100%25#fragment");
uri = new URI("http", "userinfo", "[::192.9.5.5]", 8080, "/path", "query", "fragment");
uri = queryString.apply(uri);
then(uri.toString()).isEqualTo("http://userinfo@[::192.9.5.5]:8080/path?q=a+%2B+b+%3D+100%25#fragment");
uri = new URI("file", "/authority", null, null, null);
uri = queryString.apply(uri);
then(uri.toString()).isEqualTo("file:///authority?q=a+%2B+b+%3D+100%25");
}
/**
* Test equals
*/
@Test
public void testEquals()
throws Exception {
URI uri = new URI("http://java.sun.com?page=1¶=2");
QueryString queryString = QueryString.parse(uri);
then(queryString).isEqualTo(queryString);
then(queryString.equals(uri)).isFalse();
QueryString queryString2 = QueryString.create();
then(queryString.equals(queryString2)).isFalse();
then(queryString2.equals(queryString)).isFalse();
queryString2 = QueryString.parse(uri.getQuery());
then(queryString2).isEqualTo(queryString);
then(queryString2.hashCode()).isEqualTo(queryString.hashCode());
queryString.set("page", 2);
then(queryString.equals(queryString2)).isFalse();
then(queryString.hashCode() != queryString2.hashCode()).isTrue();
queryString = QueryString.create();
queryString2 = QueryString.create();
then(queryString2).isEqualTo(queryString);
then(queryString2.hashCode()).isEqualTo(queryString.hashCode());
}
/**
* Test round-trip
*/
@Test
public void testRoundTrip()
throws Exception {
then(QueryString.parse("page=1¶=2").toString()).isEqualTo("page=1¶=2");
then(QueryString.parse("bar=&baz").toString()).isEqualTo("bar=&baz");
then(QueryString.parse("bar=1&bar=2&bar&bar=&bar=3").toString()).isEqualTo("bar=1&bar=2&bar&bar=&bar=3");
}
@Test
public void testUrlEncodedParameterNames() {
then(QueryString.parse("%70age=1&par%61=2").toString()).isEqualTo("page=1¶=2");
}
@Test
public void getNamesAsSet() {
then(
QueryString.parse("").getNames()
).isNotNull().isEmpty();
then(
QueryString.parse("page=1¶=2").getNames()
).isNotNull().isNotEmpty().contains("page").contains("para");
}
}