/*******************************************************************************
* 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;
import com.google.common.collect.ImmutableMap;
import org.everrest.core.ApplicationContext;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.Variant;
import java.io.InputStream;
import java.net.URI;
import java.security.Principal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import static com.google.common.collect.Lists.newArrayList;
import static javax.ws.rs.core.HttpHeaders.ACCEPT;
import static javax.ws.rs.core.HttpHeaders.ACCEPT_LANGUAGE;
import static javax.ws.rs.core.HttpHeaders.CONTENT_LANGUAGE;
import static javax.ws.rs.core.HttpHeaders.CONTENT_LENGTH;
import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE;
import static javax.ws.rs.core.HttpHeaders.COOKIE;
import static javax.ws.rs.core.HttpHeaders.DATE;
import static javax.ws.rs.core.HttpHeaders.IF_MATCH;
import static javax.ws.rs.core.HttpHeaders.IF_MODIFIED_SINCE;
import static javax.ws.rs.core.HttpHeaders.IF_NONE_MATCH;
import static javax.ws.rs.core.HttpHeaders.IF_UNMODIFIED_SINCE;
import static javax.ws.rs.core.Response.Status.NOT_MODIFIED;
import static javax.ws.rs.core.Response.Status.PRECONDITION_FAILED;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class ContainerRequestTest {
private String httpMethod = "POST";
private URI requestUri = URI.create("http://localhost:8080/servlet/a/b/c");
private URI baseUri = URI.create("http://localhost:8080/servlet");
private MultivaluedMap<String, String> headers = new MultivaluedHashMap<>();
private InputStream entityStream;
private SecurityContext securityContext;
private ApplicationContext applicationContext;
private ContainerRequest containerRequest;
@Before
public void setUp() throws Exception {
securityContext = mock(SecurityContext.class);
applicationContext = mock(ApplicationContext.class, RETURNS_DEEP_STUBS);
ApplicationContext.setCurrent(applicationContext);
containerRequest = new ContainerRequest(httpMethod, requestUri, baseUri, entityStream, headers, securityContext);
}
@After
public void tearDown() throws Exception {
headers.clear();
entityStream = null;
securityContext = null;
}
@Test
public void getsMethod() {
assertEquals(httpMethod, containerRequest.getMethod());
}
@Test
public void getsRequestUri() {
assertEquals(requestUri, containerRequest.getRequestUri());
}
@Test
public void getsBaseUri() {
assertEquals(baseUri, containerRequest.getBaseUri());
}
@Test
public void setsBaseUriAndRequestUri() {
URI newBaseUri = URI.create("http://localhost1:8080/servlet");
URI newRequestUri = URI.create("http://localhost:80802/servlet/a/b/c");
containerRequest.setUris(newRequestUri, newBaseUri);
assertEquals(newBaseUri, containerRequest.getBaseUri());
assertEquals(newRequestUri, containerRequest.getRequestUri());
}
@Test
public void getsAcceptableMediaTypes() {
headers.putSingle(ACCEPT, "text/*;q=0.3, text/html;q=0.7, text/xml");
List<MediaType> acceptableMediaTypes = containerRequest.getAcceptableMediaTypes();
List<MediaType> expectedAcceptMediaTypes = newArrayList(new MediaType("text", "xml"),
new MediaType("text", "html", ImmutableMap.of("q", "0.7")),
new MediaType("text", "*", ImmutableMap.of("q", "0.3")));
assertEquals(expectedAcceptMediaTypes, acceptableMediaTypes);
}
@Test
public void getsAcceptableMediaType() {
headers.putSingle(ACCEPT, "text/*;q=0.3, text/html;q=0.7, text/xml");
List<MediaType> checkMediaTypes = newArrayList(new MediaType(), new MediaType("application", "xml"), new MediaType("text", "plain"));
MediaType acceptableMediaType = containerRequest.getAcceptableMediaType(checkMediaTypes);
assertEquals(new MediaType("text", "plain"), acceptableMediaType);
}
@Test
public void returnsNullWhenAcceptableMediaTypeNotFound() {
headers.putSingle(ACCEPT, "text/*;q=0.3, text/html;q=0.7, text/xml");
List<MediaType> checkMediaTypes = newArrayList(new MediaType(), new MediaType("application", "xml"));
MediaType acceptableMediaType = containerRequest.getAcceptableMediaType(checkMediaTypes);
assertNull(acceptableMediaType);
}
@Test
public void returnsEmptyListWhenNoCookiesHeadersInRequest() {
List<String> cookieHeaders = containerRequest.getCookieHeaders();
assertNotNull(cookieHeaders);
assertTrue(cookieHeaders.isEmpty());
}
@Test
public void getsCookieHeaders() {
headers.putSingle(COOKIE, "foo=bar");
List<String> cookieHeaders = containerRequest.getCookieHeaders();
assertEquals(newArrayList("foo=bar"), cookieHeaders);
}
@Test
public void resetsParsedFormDataWhenSetEntityStream() {
InputStream entityStream = mock(InputStream.class);
containerRequest.setEntityStream(entityStream);
verify(applicationContext.getAttributes()).remove("org.everrest.provider.entity.decoded.form");
verify(applicationContext.getAttributes()).remove("org.everrest.provider.entity.encoded.form");
}
@Test
public void getsAuthenticationScheme() {
when(securityContext.getAuthenticationScheme()).thenReturn("BASIC_AUTH");
assertEquals("BASIC_AUTH", containerRequest.getAuthenticationScheme());
}
@Test
public void getsUserPrincipal() {
Principal principal = mock(Principal.class);
when(securityContext.getUserPrincipal()).thenReturn(principal);
assertSame(principal, containerRequest.getUserPrincipal());
}
@Test
public void testIsSecure() {
when(securityContext.isSecure()).thenReturn(true);
assertTrue(containerRequest.isSecure());
}
@Test
public void testIsUserInRole() {
when(securityContext.isUserInRole("admin")).thenReturn(true);
assertTrue(containerRequest.isUserInRole("admin"));
}
@Test
public void evaluatesPreconditionsResponseByETagAsNullWhenBothIfMatchAndIfNoneMatchHeaderNotSet() {
assertNull(containerRequest.evaluatePreconditions(new EntityTag("1234567")));
}
@Test
public void evaluatesPreconditionsResponseByETagAsNullWhenIfMatchHeaderMatchesWithETag() {
headers.putSingle(IF_MATCH, "\"1234567\"");
assertNull(containerRequest.evaluatePreconditions(new EntityTag("1234567")));
}
@Test
public void evaluatesPreconditionsResponseByETagAs_PRECONDITION_FAILED_WhenETagIsWeak() {
headers.putSingle(IF_MATCH, "\"1234567\"");
Response response = containerRequest.evaluatePreconditions(new EntityTag("W/1234567")).build();
assertEquals(PRECONDITION_FAILED, response.getStatusInfo());
}
@Test
public void evaluatesPreconditionsResponseByETagAsNullWhenIfNoneMatchHeaderDoesNotMatchWithETag() {
headers.putSingle(IF_NONE_MATCH, "\"1234567\"");
assertNull(containerRequest.evaluatePreconditions(new EntityTag("7654321")));
}
@Test
public void evaluatesPreconditionsResponseByETagAs_PRECONDITION_FAILED_WhenIfNoneMatchHeaderMatchesWithETag() {
headers.putSingle(IF_NONE_MATCH, "\"1234567\"");
Response response = containerRequest.evaluatePreconditions(new EntityTag("1234567")).build();
assertEquals(PRECONDITION_FAILED, response.getStatusInfo());
}
@Test
public void evaluatesPreconditionsResponseByETagAs_NOT_MODIFIED_When_GET_RequestAndIfNoneMatchHeaderIsWeak() {
containerRequest.setMethod("GET");
headers.putSingle(IF_NONE_MATCH, "W/\"1234567\"");
Response response = containerRequest.evaluatePreconditions(new EntityTag("1234567")).build();
assertEquals(NOT_MODIFIED, response.getStatusInfo());
}
@Test
public void evaluatesPreconditionsResponseByETagAs_NOT_MODIFIED_When_HEAD_RequestAndIfNoneMatchHeaderIsWeak() {
containerRequest.setMethod("HEAD");
headers.putSingle(IF_NONE_MATCH, "W/\"1234567\"");
Response response = containerRequest.evaluatePreconditions(new EntityTag("1234567")).build();
assertEquals(NOT_MODIFIED, response.getStatusInfo());
}
@Test
public void evaluatesPreconditionsResponseByLastModificationDateAs_PRECONDITION_FAILED_WhenLastModificationDateIsAfterIfUnmodifiedSinceHeader() {
Date now = new Date();
Date before = new Date(now.getTime() - 10000);
headers.putSingle(IF_UNMODIFIED_SINCE, formatDateInRfc1123DateFormat(before));
Response response = containerRequest.evaluatePreconditions(now).build();
assertEquals(PRECONDITION_FAILED, response.getStatusInfo());
}
@Test
public void evaluatesPreconditionsResponseByLastModificationDateAsNullWhenIfUnmodifiedSinceHeaderIsNotSet() {
Date now = new Date();
headers.putSingle(IF_UNMODIFIED_SINCE, null);
assertNull(containerRequest.evaluatePreconditions(now));
}
@Test
public void evaluatesPreconditionsResponseByLastModificationDateAsNullWhenIfUnmodifiedSinceHeaderHasInvalidFormat() {
Date now = new Date();
headers.putSingle(IF_UNMODIFIED_SINCE, "foo");
assertNull(containerRequest.evaluatePreconditions(now));
}
@Test
public void evaluatesPreconditionsResponseByLastModificationDateAs_NOT_MODIFIED_WhenLastModificationDateIsNotAfterIfModifiedSinceHeader() {
Date now = new Date();
Date before = new Date(now.getTime() - 10000);
headers.putSingle(IF_MODIFIED_SINCE, formatDateInRfc1123DateFormat(now));
Response response = containerRequest.evaluatePreconditions(before).build();
assertEquals(NOT_MODIFIED, response.getStatusInfo());
}
@Test
public void evaluatesPreconditionsResponseByLastModificationDateAsNullWhenIfModifiedSinceHeaderIsNotSet() {
Date now = new Date();
headers.putSingle(IF_MODIFIED_SINCE, null);
assertNull(containerRequest.evaluatePreconditions(now));
}
@Test
public void evaluatesPreconditionsResponseByLastModificationDateAsNullWhenIfModifiedSinceHeaderHasInvalidFormat() {
Date now = new Date();
headers.putSingle(IF_MODIFIED_SINCE, "foo");
assertNull(containerRequest.evaluatePreconditions(now));
}
@Test
public void evaluatesPreconditionsResponseByETagAndLastModificationDateAsNullWhenHeadersNotSet() {
assertNull(containerRequest.evaluatePreconditions(new Date(), new EntityTag("1234567")));
}
@Test
public void evaluatesPreconditionsResponseByETagAndLastModificationDateAsNullWhenIfMatchHeaderMatchesWithETag() {
headers.putSingle(IF_MATCH, "\"1234567\"");
assertNull(containerRequest.evaluatePreconditions(new Date(), new EntityTag("1234567")));
}
@Test
public void evaluatesPreconditionsResponseByETagAndLastModificationDateAs_PRECONDITION_FAILED_WhenETagIsWeak() {
headers.putSingle(IF_MATCH, "\"1234567\"");
Response response = containerRequest.evaluatePreconditions(new Date(), new EntityTag("W/1234567")).build();
assertEquals(PRECONDITION_FAILED, response.getStatusInfo());
}
@Test
public void evaluatesPreconditionsResponseByETgaAndLastModificationDateAs_NOT_MODIFIED_WhenLastModificationDateIsNotAfterIfModifiedSinceHeader() {
Date now = new Date();
Date before = new Date(now.getTime() - 10000);
headers.putSingle(IF_MODIFIED_SINCE, formatDateInRfc1123DateFormat(now));
Response response = containerRequest.evaluatePreconditions(before, new EntityTag("1234567")).build();
assertEquals(NOT_MODIFIED, response.getStatusInfo());
}
@Test
public void evaluatesPreconditionsResponseByETagAndLastModificationDateAs_PRECONDITION_FAILED_WhenIfNoneMatchHeaderMatchesWithETag() {
headers.putSingle(IF_NONE_MATCH, "\"1234567\"");
Response response = containerRequest.evaluatePreconditions(new Date(), new EntityTag("1234567")).build();
assertEquals(PRECONDITION_FAILED, response.getStatusInfo());
}
private String formatDateInRfc1123DateFormat(Date date) {
DateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
return format.format(date);
}
@Test
public void evaluatesPreconditionsResponseAs_PRECONDITION_FAILED_WhenIfMatchHeaderSet() {
headers.putSingle(IF_MATCH, "\"1234567\"");
Response response = containerRequest.evaluatePreconditions().build();
assertEquals(PRECONDITION_FAILED, response.getStatusInfo());
}
@Test
public void evaluatesPreconditionsResponseAsNullWhenIfMatchHeaderNotSet() {
headers.putSingle(IF_MATCH, null);
assertNull(containerRequest.evaluatePreconditions());
}
@Test
public void selectsValiant() {
VariantsHandler variantsHandler = mock(VariantsHandler.class);
containerRequest.setVariantsHandler(variantsHandler);
List<Variant> variants = Variant.mediaTypes(MediaType.valueOf("text/xml")).languages(new Locale("en")).add()
.mediaTypes(MediaType.valueOf("text/xml")).languages(new Locale("en", "us")).add()
.build();
containerRequest.selectVariant(variants);
verify(variantsHandler).handleVariants(containerRequest, variants);
}
@Test(expected = IllegalArgumentException.class)
public void throwsExceptionWhenVariantListIsNull() throws Exception {
containerRequest.selectVariant(null);
}
@Test(expected = IllegalArgumentException.class)
public void throwsExceptionWhenVariantListIsEmpty() throws Exception {
containerRequest.selectVariant(newArrayList());
}
@Test
public void getsAcceptableLanguages() {
headers.put(ACCEPT_LANGUAGE, newArrayList("en-GB", "en;q=0.8"));
assertEquals(newArrayList(new Locale("en", "GB"), new Locale("en")), containerRequest.getAcceptableLanguages());
}
@Test
public void getsCookies() {
headers.put(COOKIE, newArrayList("$Version=1;company=codenvy;$Path=/path,$Domain=codenvy.com", "name=andrew"));
Map<String, Cookie> expectedCookies = ImmutableMap.of("company", new Cookie("company", "codenvy", "/path", "codenvy.com"), "name", new Cookie("name", "andrew"));
assertEquals(expectedCookies, containerRequest.getCookies());
}
@Test
public void getsDate() {
Date date = new Date();
headers.putSingle(DATE, formatDateInRfc1123DateFormat(date));
assertTrue("Dates are not equal", Math.abs(date.getTime() - containerRequest.getDate().getTime()) < 1000);
}
@Test
public void getsContentLengthAsMinusOneWhenContentLengthHeaderIsNotSet() {
assertEquals(-1, containerRequest.getLength());
}
@Test
public void getsContentLength() {
headers.putSingle(CONTENT_LENGTH, "101");
assertEquals(101, containerRequest.getLength());
}
@Test
public void getsMediaType() {
headers.putSingle(CONTENT_TYPE, "text/plain");
assertEquals(new MediaType("text", "plain"), containerRequest.getMediaType());
}
@Test
public void getsHeaderAsString() {
headers.put("foo", newArrayList("bar1", "bar2"));
assertEquals("bar1,bar2", containerRequest.getHeaderString("foo"));
}
@Test
public void getsLanguage() {
headers.putSingle(CONTENT_LANGUAGE, "en-gb");
assertEquals(new Locale("en", "gb"), containerRequest.getLanguage());
}
}