/*******************************************************************************
* 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 org.everrest.core.ApplicationContext;
import org.everrest.core.ContainerResponseWriter;
import org.everrest.core.impl.provider.StringEntityProvider;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InOrder;
import org.mockito.stubbing.Answer;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.MessageBodyWriter;
import java.io.ByteArrayOutputStream;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE;
import static javax.ws.rs.core.MediaType.TEXT_PLAIN_TYPE;
import static javax.ws.rs.core.MediaType.WILDCARD_TYPE;
import static org.everrest.core.util.ParameterizedTypeImpl.newParameterizedType;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.same;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class ContainerResponseTest {
private ProviderBinder providers;
private ContainerRequest containerRequest;
private ContainerResponseWriter containerResponseWriter;
private ByteArrayOutputStream entityStream;
private ContainerResponse containerResponse;
@Before
public void setUp() throws Exception {
providers = mock(ProviderBinder.class);
containerRequest = mock(ContainerRequest.class);
ApplicationContext applicationContext = mock(ApplicationContext.class);
when(applicationContext.getProviders()).thenReturn(providers);
when(applicationContext.getContainerRequest()).thenReturn(containerRequest);
when(applicationContext.getQueryParameters()).thenReturn(new MultivaluedHashMap<>());
ApplicationContext.setCurrent(applicationContext);
entityStream = new ByteArrayOutputStream();
containerResponseWriter = mock(ContainerResponseWriter.class);
containerResponse = new ContainerResponse(containerResponseWriter);
doAnswer(writeEntity()).when(containerResponseWriter).writeBody(same(containerResponse), any(MessageBodyWriter.class));
}
private Answer<Void> writeEntity() {
return invocation -> {
MessageBodyWriter messageBodyWriter = (MessageBodyWriter)invocation.getArguments()[1];
Object entity = containerResponse.getEntity();
if (entity != null) {
messageBodyWriter.writeTo(entity,
entity.getClass(),
containerResponse.getEntityType(),
null,
containerResponse.getContentType(),
containerResponse.getHttpHeaders(),
entityStream);
}
return null;
};
}
@Test
public void setsNullResponse() throws Exception {
containerResponse.setResponse(null);
assertNull(containerResponse.getResponse());
assertEquals(0, containerResponse.getStatus());
assertNull(containerResponse.getEntity());
assertNull(containerResponse.getEntityType());
assertTrue(containerResponse.getHttpHeaders().isEmpty());
assertNull(containerResponse.getContentType());
}
@Test
public void setsResponse() throws Exception {
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
headers.putSingle(CONTENT_TYPE, TEXT_PLAIN_TYPE);
Response response = mockResponse(200, headers, "foo");
containerResponse.setResponse(response);
assertSame(response, containerResponse.getResponse());
assertEquals(200, containerResponse.getStatus());
assertEquals("foo", containerResponse.getEntity());
assertEquals(String.class, containerResponse.getEntityType());
assertEquals(headers, containerResponse.getHttpHeaders());
assertEquals(TEXT_PLAIN_TYPE, containerResponse.getContentType());
}
@Test
public void setsResponseWithGenericEntity() throws Exception {
GenericEntity<List<String>> genericEntity = new GenericEntity<List<String>>(newArrayList("foo")) {
};
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
headers.putSingle(CONTENT_TYPE, TEXT_PLAIN_TYPE);
Response response = mockResponse(200, headers, genericEntity);
containerResponse.setResponse(response);
assertSame(response, containerResponse.getResponse());
assertEquals(200, containerResponse.getStatus());
assertEquals(newArrayList("foo"), containerResponse.getEntity());
assertEquals(newParameterizedType(List.class, String.class), containerResponse.getEntityType());
assertEquals(headers, containerResponse.getHttpHeaders());
assertEquals(TEXT_PLAIN_TYPE, containerResponse.getContentType());
}
@Test
public void writesResponseWhenResponseEntityIsNullAndRequestMethodIsGET() throws Exception {
when(providers.getMessageBodyWriter(String.class, String.class, null, TEXT_PLAIN_TYPE)).thenReturn(new StringEntityProvider());
when(containerRequest.getMethod()).thenReturn("GET");
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
Response response = mockResponse(200, headers, null);
containerResponse.setResponse(response);
containerResponse.writeResponse();
assertEquals(200, containerResponse.getStatus());
verify(containerResponseWriter).writeHeaders(containerResponse);
verify(containerResponseWriter, never()).writeBody(same(containerResponse), any(MessageBodyWriter.class));
}
@Test
public void writesResponseWhenResponseEntityIsNotNullRequestMethodIsHEADAndContentTypeIsSetExplicitly() throws Exception {
when(providers.getMessageBodyWriter(String.class, String.class, null, TEXT_PLAIN_TYPE)).thenReturn(new StringEntityProvider());
when(containerRequest.getMethod()).thenReturn("HEAD");
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
headers.putSingle(CONTENT_TYPE, TEXT_PLAIN_TYPE);
Response response = mockResponse(200, headers, "foo");
containerResponse.setResponse(response);
containerResponse.writeResponse();
assertEquals(200, containerResponse.getStatus());
InOrder inOrder = inOrder(containerResponseWriter);
inOrder.verify(containerResponseWriter).writeHeaders(containerResponse);
inOrder.verify(containerResponseWriter, never()).writeBody(same(containerResponse), any(MessageBodyWriter.class));
}
@Test
public void writesResponseWhenResponseEntityIsNotNullRequestMethodIsGETAndContentTypeIsSetExplicitly() throws Exception {
when(providers.getMessageBodyWriter(String.class, String.class, null, TEXT_PLAIN_TYPE)).thenReturn(new StringEntityProvider());
when(containerRequest.getMethod()).thenReturn("GET");
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
headers.putSingle(CONTENT_TYPE, TEXT_PLAIN_TYPE);
Response response = mockResponse(200, headers, "foo");
containerResponse.setResponse(response);
containerResponse.writeResponse();
assertEquals(200, containerResponse.getStatus());
InOrder inOrder = inOrder(containerResponseWriter);
inOrder.verify(containerResponseWriter).writeHeaders(containerResponse);
inOrder.verify(containerResponseWriter, never()).writeBody(same(containerResponse), any(MessageBodyWriter.class));
}
@Test
public void writesResponseWhenResponseEntityIsNotNullRequestMethodIsGETAcceptHeaderIsSetAndContentTypeIsNotSet() throws Exception {
when(providers.getMessageBodyWriter(String.class, String.class, null, TEXT_PLAIN_TYPE)).thenReturn(new StringEntityProvider());
when(containerRequest.getMethod()).thenReturn("GET");
when(containerRequest.getAcceptableMediaTypes()).thenReturn(newArrayList(TEXT_PLAIN_TYPE));
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
Response response = mockResponse(200, headers, "foo");
containerResponse.setResponse(response);
containerResponse.writeResponse();
assertEquals(200, containerResponse.getStatus());
assertEquals(TEXT_PLAIN_TYPE, containerResponse.getContentType());
verify(containerResponseWriter).writeHeaders(containerResponse);
verify(containerResponseWriter).writeBody(same(containerResponse), any(MessageBodyWriter.class));
}
@Test
public void writesResponseWhenResponseEntityIsNotNullRequestMethodIsGETAcceptHeaderIsNotSetAndContentTypeIsNotSet() throws Exception {
when(providers.getMessageBodyWriter(String.class, String.class, null, TEXT_PLAIN_TYPE)).thenReturn(new StringEntityProvider());
when(providers.getAcceptableWriterMediaTypes(String.class, String.class, null)).thenReturn(newArrayList(TEXT_PLAIN_TYPE));
when(containerRequest.getMethod()).thenReturn("GET");
when(containerRequest.getAcceptableMediaTypes()).thenReturn(newArrayList(WILDCARD_TYPE));
when(containerRequest.getAcceptableMediaType(newArrayList(TEXT_PLAIN_TYPE))).thenReturn(TEXT_PLAIN_TYPE);
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
Response response = mockResponse(200, headers, "foo");
containerResponse.setResponse(response);
containerResponse.writeResponse();
assertEquals(200, containerResponse.getStatus());
verify(containerResponseWriter).writeHeaders(containerResponse);
verify(containerResponseWriter).writeBody(same(containerResponse), any(MessageBodyWriter.class));
}
@Test
public void createsNOT_ACCEPTABLEResponseWhenNotFoundAnyWriterForEntity() throws Exception {
when(containerRequest.getMethod()).thenReturn("GET");
when(containerRequest.getAcceptableMediaTypes()).thenReturn(newArrayList(WILDCARD_TYPE));
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
Response response = mockResponse(200, headers, "foo");
containerResponse.setResponse(response);
containerResponse.writeResponse();
assertEquals(406, containerResponse.getStatus());
verify(containerResponseWriter).writeHeaders(containerResponse);
verify(containerResponseWriter).writeBody(same(containerResponse), any(MessageBodyWriter.class));
}
@Test
public void neverCreatesNOT_ACCEPTABLEResponseForHEADRequestEvenWhenNotFoundAnyWriterForEntity() throws Exception {
when(containerRequest.getMethod()).thenReturn("HEAD");
when(containerRequest.getAcceptableMediaTypes()).thenReturn(newArrayList(WILDCARD_TYPE));
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
Response response = mockResponse(200, headers, "foo");
containerResponse.setResponse(response);
containerResponse.writeResponse();
assertEquals(200, containerResponse.getStatus());
verify(containerResponseWriter).writeHeaders(containerResponse);
verify(containerResponseWriter, never()).writeBody(same(containerResponse), any(MessageBodyWriter.class));
}
private Response mockResponse(int status, MultivaluedMap<String, Object> headers, Object entity) {
Response response = mock(Response.class);
when(response.getStatus()).thenReturn(status);
when(response.getMetadata()).thenReturn(headers);
when(response.getEntity()).thenReturn(entity);
return response;
}
}