/*******************************************************************************
* Copyright (c) 2012-2016 Codenvy, S.A.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.everrest.core.impl.header;
import com.google.common.collect.ImmutableMap;
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
import org.everrest.core.impl.MultivaluedMapImpl;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.NewCookie;
import javax.ws.rs.ext.RuntimeDelegate;
import javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import static com.google.common.collect.Lists.newArrayList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(DataProviderRunner.class)
public class HeaderHelperTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
@After
public void tearDown() throws Exception {
RuntimeDelegate.setInstance(null);
}
@Test
public void createsAcceptedCharsetListWhenHeaderIsNull() {
List<AcceptToken> charsetList = HeaderHelper.createAcceptedCharsetList(null);
assertEquals(newArrayList(new AcceptToken("*")), charsetList);
}
@Test
public void createAcceptedCharsetListWhenHeaderIsEmptyString() {
List<AcceptToken> charsetList = HeaderHelper.createAcceptedCharsetList("");
assertEquals(newArrayList(new AcceptToken("*")), charsetList);
}
@Test
public void createsAcceptedCharsetListFromHeader() {
String charsets = "Windows-1251,utf-8; q =0.9,*;q=0.7";
List<AcceptToken> expectedCharsetList =
newArrayList(new AcceptToken("windows-1251"), new AcceptToken("utf-8", 0.9f), new AcceptToken("*", 0.7f));
List<AcceptToken> charsetList = HeaderHelper.createAcceptedCharsetList(charsets);
assertEquals(expectedCharsetList, charsetList);
}
@Test
public void createsAcceptedEncodingListWhenHeaderIsNull() {
List<AcceptToken> charsetList = HeaderHelper.createAcceptedEncodingList(null);
assertEquals(newArrayList(new AcceptToken("*")), charsetList);
}
@Test
public void createsAcceptedEncodingListWhenHeaderIsEmptyString() {
List<AcceptToken> charsetList = HeaderHelper.createAcceptedEncodingList("");
assertEquals(newArrayList(new AcceptToken("*")), charsetList);
}
@Test
public void createsAcceptedEncodingListFromHeader() {
String encodings = "compress;q=0.5, gzip ; q=1.0";
List<AcceptToken> expectedEncodingList = newArrayList(new AcceptToken("gzip"), new AcceptToken("compress", 0.5f));
List<AcceptToken> encodingList = HeaderHelper.createAcceptedEncodingList(encodings);
assertEquals(expectedEncodingList, encodingList);
}
@Test
public void createsAcceptedLanguageListWhenHeaderIsNull() throws Exception {
List<AcceptLanguage> acceptedLanguageList = HeaderHelper.createAcceptedLanguageList(null);
assertEquals(newArrayList(new AcceptLanguage(new Locale("*"))), acceptedLanguageList);
}
@Test
public void createsAcceptedLanguageListWhenHeaderIsEmptyString() throws Exception {
List<AcceptLanguage> acceptedLanguageList = HeaderHelper.createAcceptedLanguageList("");
assertEquals(newArrayList(new AcceptLanguage(new Locale("*"))), acceptedLanguageList);
}
@Test
public void createsAcceptedLanguageListFromHeader() throws Exception {
String languages = "da;q=0.825, en-GB, en;q=0.8";
List<AcceptLanguage> expectedAcceptedLanguageList =
newArrayList(new AcceptLanguage(new Locale("en", "GB")), new AcceptLanguage(new Locale("da"), 0.825f), new AcceptLanguage(new Locale("en"), 0.8f));
List<AcceptLanguage> acceptedLanguageList = HeaderHelper.createAcceptedLanguageList(languages);
assertEquals(expectedAcceptedLanguageList, acceptedLanguageList);
}
@Test
public void createsAcceptMediaTypeListWhenHeaderIsNull() {
List<AcceptMediaType> acceptMediaTypeList = HeaderHelper.createAcceptMediaTypeList(null);
List<AcceptMediaType> expectedAcceptMediaTypeList = newArrayList(new AcceptMediaType("*", "*"));
assertEquals(expectedAcceptMediaTypeList, acceptMediaTypeList);
}
@Test
public void createsAcceptMediaTypeListWhenHeaderIsEmptyString() {
List<AcceptMediaType> acceptMediaTypeList = HeaderHelper.createAcceptMediaTypeList("");
List<AcceptMediaType> expectedAcceptMediaTypeList = newArrayList(new AcceptMediaType("*", "*"));
assertEquals(expectedAcceptMediaTypeList, acceptMediaTypeList);
}
@Test
public void createsAcceptMediaTypeListFromHeader() {
String header = "text/xml; charset=utf8;q=0.825, text/html;charset=utf8, text/plain;charset=utf8;q=0.8";
List<AcceptMediaType> acceptMediaTypeList = HeaderHelper.createAcceptMediaTypeList(header);
List<AcceptMediaType> expectedAcceptMediaTypeList = newArrayList(
new AcceptMediaType("text", "html", ImmutableMap.of("charset", "utf8")),
new AcceptMediaType("text", "xml", ImmutableMap.of("charset", "utf8", "q", "0.825")),
new AcceptMediaType("text", "plain", ImmutableMap.of("charset", "utf8", "q", "0.8")));
assertEquals(expectedAcceptMediaTypeList, acceptMediaTypeList);
}
@DataProvider
public static Object[][] forParsesCookies() {
return new Object[][] {
{"name=andrew", newArrayList(new Cookie("name", "andrew"))},
{"company=exo,name=andrew", newArrayList(new Cookie("company", "exo"), new Cookie("name", "andrew"))},
{"company=exo;name=andrew", newArrayList(new Cookie("company", "exo"), new Cookie("name", "andrew"))},
{"$Version=1;company=exo;$Path=/exo,$domain=exo.com;name=andrew",
newArrayList(new Cookie("company", "exo", "/exo", "exo.com"), new Cookie("name", "andrew"))},
{"$Version=0; company=exo; $path=/exo, $Domain=exo.com;name=andrew, $Domain=exo.org",
newArrayList(new Cookie("company", "exo", "/exo", "exo.com", 0), new Cookie("name", "andrew", null, "exo.org", 0))}
};
}
@UseDataProvider("forParsesCookies")
@Test
public void parsesCookies(String cookiesHeader, List<Cookie> expectedCookies) {
List<Cookie> cookies = HeaderHelper.parseCookies(cookiesHeader);
assertEquals(expectedCookies, cookies);
}
@DataProvider
public static Object[][] forParsesNewCookies() {
return new Object[][] {
{"name=andrew", new NewCookie("name", "andrew")},
{"name=andrew;version=1;paTh=/path;Domain=codenvy.com;comment=\"comment\";max-age=300;expires=Thu, 29 Dec 2011 12:03:50 GMT;HttpOnly;secure",
new NewCookie("name", "andrew", "/path", "codenvy.com", 1, "comment", 300, date(2011, 12, 29, 12, 3, 50, "GMT"), true, true)},
};
}
@UseDataProvider("forParsesNewCookies")
@Test
public void parsesNewCookies(String cookieHeader, NewCookie expectedNewCookie) {
NewCookie newCookie = HeaderHelper.parseNewCookie(cookieHeader);
assertNotNull(newCookie);
assertEquals(expectedNewCookie.getName(), newCookie.getName());
assertEquals(expectedNewCookie.getValue(), newCookie.getValue());
if (expectedNewCookie.getExpiry() != null) {
assertTrue(String.format("Expiry dates are not equal. Expected %s, actual %s", expectedNewCookie.getExpiry(), newCookie.getExpiry()),
Math.abs(expectedNewCookie.getExpiry().getTime() - newCookie.getExpiry().getTime()) < 1000);
}
assertEquals(expectedNewCookie.getMaxAge(), newCookie.getMaxAge());
assertEquals(expectedNewCookie.getPath(), newCookie.getPath());
assertEquals(expectedNewCookie.getDomain(), newCookie.getDomain());
assertEquals(expectedNewCookie.getComment(), newCookie.getComment());
assertEquals(expectedNewCookie.getVersion(), newCookie.getVersion());
assertEquals(expectedNewCookie.isSecure(), newCookie.isSecure());
assertEquals(expectedNewCookie.isHttpOnly(), newCookie.isHttpOnly());
}
@Test
public void parsesANSI() {
// EEE MMM d HH:mm:ss yyyy
String dateHeader = "THU DEC 29 12:03:50 2011";
Date expectedDate = date(2011, 12, 29, 12, 3, 50, "GMT");
Date date = HeaderHelper.parseDateHeader(dateHeader);
assertTrue(String.format("Dates are not equal. Expected %s, actual %s", expectedDate, date),
Math.abs(expectedDate.getTime() - date.getTime()) < 1000);
}
@Test
public void parsesRFC_1036() {
// EEEE, dd-MMM-yy HH:mm:ss zzz
String dateHeader = "Thursday, 29-Dec-11 12:03:50 EST";
Date expectedDate = date(2011, 12, 29, 12, 3, 50, "EST");
Date date = HeaderHelper.parseDateHeader(dateHeader);
assertTrue(String.format("Dates are not equal, %s and %s", expectedDate, date),
Math.abs(expectedDate.getTime() - date.getTime()) < 1000);
}
@Test
public void parsesRFC_1123() {
// EEE, dd MMM yyyy HH:mm:ss zzz
String dateHeader = "Thu, 29 Dec 2011 12:03:50 GMT";
Date expectedDate = date(2011, 12, 29, 12, 3, 50, "GMT");
Date date = HeaderHelper.parseDateHeader(dateHeader);
assertTrue(String.format("Dates are not equal, %s and %s", expectedDate, date),
Math.abs(expectedDate.getTime() - date.getTime()) < 1000);
}
private static Date date(int year, int month, int day, int hours, int minutes, int seconds, String timeZone) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone(timeZone));
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month - 1);
calendar.set(Calendar.DAY_OF_MONTH, day);
calendar.set(Calendar.HOUR_OF_DAY, hours);
calendar.set(Calendar.MINUTE, minutes);
calendar.set(Calendar.SECOND, seconds);
return calendar.getTime();
}
@Test
public void failsParseDateIfItDoesNotMatchToAnySupportedFormat() {
String dateHeader = "12:03:50 GMT";
thrown.expect(IllegalArgumentException.class);
HeaderHelper.parseDateHeader(dateHeader);
}
@Test
public void formatsDate() throws Exception {
final Date date = date(2010, 1, 8, 2, 5, 0, "EET");
assertEquals("Fri, 08 Jan 2010 00:05:00 GMT", HeaderHelper.formatDate(date));
}
@Test
public void getsContentLengthAsLong() throws Exception {
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
headers.putSingle(HttpHeaders.CONTENT_LENGTH, "111");
final long contentLength = HeaderHelper.getContentLengthLong(headers);
assertEquals(111L, contentLength);
}
@DataProvider
public static Object[][] forConvertsCollectionToString() {
return new Object[][]{
{newArrayList("a", "b", "c"), "a,b,c"},
{newArrayList(), ""},
{null, null}
};
}
@UseDataProvider("forConvertsCollectionToString")
@Test
public void convertsCollectionToString(Collection<String> header, String expectedResult) throws Exception {
final String result = HeaderHelper.convertToString(header);
assertEquals(expectedResult, result);
}
@DataProvider
public static Object[][] forAppendsStringInStringBuilderEscapesAndAddsQuoteIfNeed() {
return new Object[][] {
{"DoNotNeedAddQuotes", "DoNotNeedAddQuotes"},
{"Need\tAdd Quotes", "\"Need\tAdd Quotes\""},
{"Need Add \"Quotes\"", "\"Need Add \\\"Quotes\\\"\""},
{"NeedAdd\"Quotes\"", "\"NeedAdd\\\"Quotes\\\"\""},
{null, ""}
};
}
@UseDataProvider("forAppendsStringInStringBuilderEscapesAndAddsQuoteIfNeed")
@Test
public void appendsStringInStringBuilderEscapesAndAddsQuoteIfNeed(String string, String expectedResult) throws Exception {
StringBuilder builder = new StringBuilder();
HeaderHelper.appendWithQuote(builder, string);
assertEquals(expectedResult, builder.toString());
}
@DataProvider
public static Object[][] forRemovesWhitespaces() {
return new Object[][]{
{"remove_white spaces", "remove_whitespaces"},
{"rem ove_white\t spaces", "remove_whitespaces"},
{"leave_as_is", "leave_as_is"}
};
}
@UseDataProvider("forRemovesWhitespaces")
@Test
public void removesWhitespaces(String string, String expectedResult) throws Exception {
assertEquals(expectedResult, HeaderHelper.removeWhitespaces(string));
}
@DataProvider
public static Object[][] forAddsQuotesIfHasWhitespace() {
return new Object[][] {
{"DoNotNeedAddQuotes", "DoNotNeedAddQuotes"},
{"Need\tAddQuotes", "\"Need\tAddQuotes\""},
{"Need Add Quotes", "\"Need Add Quotes\""}
};
}
@UseDataProvider("forAddsQuotesIfHasWhitespace")
@Test
public void addsQuotesIfHasWhitespace(String string, String expectedResult) throws Exception {
assertEquals(expectedResult, HeaderHelper.addQuotesIfHasWhitespace(string));
}
@DataProvider
public static Object[][] forParsesQualityValue() {
return new Object[][]{
{"0.75", 0.75f},
{".3", 0.3f},
{"1.0", 1.0f},
{"0.0", 0.0f}
};
}
@UseDataProvider("forParsesQualityValue")
@Test
public void parsesQualityValue(String qValueString, float expectedResult) throws Exception {
assertEquals(expectedResult, HeaderHelper.parseQualityValue(qValueString), 0.0f);
}
@Test
public void failsParseQualityValueWhenStringIsLongerThanFiveCharacters() throws Exception {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Quality value string has more then 5 characters");
HeaderHelper.parseQualityValue("0.7777");
}
@Test
public void failsParseQualityValueWhenValueIsGreaterThanOne() throws Exception {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Quality value can't be greater then 1.0");
HeaderHelper.parseQualityValue("1.05");
}
@Test
public void failsParseQualityValueWhenValueIsNotNumeric() throws Exception {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Invalid quality value '0.5x'");
HeaderHelper.parseQualityValue("0.5x");
}
@DataProvider
public static Object[][] forChecksIsStringToken() {
return new Object[][] {
{"", -1},
{"token", -1},
{"is,not token", 2},
{"is not:token", 6}
};
}
@UseDataProvider("forChecksIsStringToken")
@Test
public void checksIsStringToken(String checkIsToken, int indexOfFirstInvalidChar) throws Exception {
assertEquals(indexOfFirstInvalidChar, HeaderHelper.isToken(checkIsToken));
}
@DataProvider
public static Object[][] forRemovesQuoteEscapes() {
return new Object[][]{
{"\\\"token\\\"", "\"token\""},
{"other \\\"token\\\"", "other \"token\""},
{"token", "token"}
};
}
@UseDataProvider("forRemovesQuoteEscapes")
@Test
public void removesQuoteEscapes(String string, String expectedResult) throws Exception {
assertEquals(expectedResult, HeaderHelper.removeQuoteEscapes(string));
}
@SuppressWarnings("unchecked")
@Test
public void transformsObjectToStringWithHeaderDelegate() throws Exception {
RuntimeDelegate runtimeDelegate = mock(RuntimeDelegate.class);
RuntimeDelegate.setInstance(runtimeDelegate);
HeaderDelegate<String> headerDelegate = mock(HeaderDelegate.class);
when(runtimeDelegate.createHeaderDelegate(String.class)).thenReturn(headerDelegate);
when(headerDelegate.toString("foo")).thenReturn("<foo>");
assertEquals("<foo>", HeaderHelper.getHeaderAsString("foo"));
}
@Test
public void transformsObjectToStringWithToStringMethodWhenHeaderDelegateDoesNotPresent() throws Exception {
RuntimeDelegate runtimeDelegate = mock(RuntimeDelegate.class);
RuntimeDelegate.setInstance(runtimeDelegate);
Object someObject = mock(Object.class);
when(someObject.toString()).thenReturn("<foo>");
assertEquals("<foo>", HeaderHelper.getHeaderAsString(someObject));
}
}