/******************************************************************************* * 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.provider; import com.google.common.collect.ImmutableMap; import org.everrest.core.ApplicationContext; import org.everrest.core.impl.MultivaluedMapImpl; import org.everrest.core.tools.EmptyInputStream; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.MultivaluedMap; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.lang.reflect.ParameterizedType; import java.util.List; import java.util.Map; import static com.google.common.collect.Lists.newArrayList; import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED_TYPE; import static org.everrest.core.util.ParameterizedTypeImpl.newParameterizedType; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.eq; 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 MultivaluedMapEntityProviderTest { private final ParameterizedType multiValuedMapGenericType = newParameterizedType(MultivaluedMap.class, String.class, String.class); private byte[] testContent; private ApplicationContext context; private HttpServletRequest servletRequest; private MultivaluedMapEntityProvider multivaluedMapEntityProvider; @Before public void setUp() throws Exception { testContent = "foo=to%20be%20or%20not%20to%20be&bar=hello%20world".getBytes("UTF-8"); servletRequest = mock(HttpServletRequest.class); context = mock(ApplicationContext.class, RETURNS_DEEP_STUBS); when(context.getAttributes().get("org.everrest.provider.entity.decoded.form")).thenReturn(null); ApplicationContext.setCurrent(context); multivaluedMapEntityProvider = new MultivaluedMapEntityProvider(servletRequest); } @After public void tearDown() throws Exception { ApplicationContext.setCurrent(null); } @Test public void isReadableForMultivaluedMap() throws Exception { assertTrue(multivaluedMapEntityProvider.isReadable(MultivaluedMap.class, multiValuedMapGenericType, null, null)); } @Test public void isNotReadableForTypeOtherThanMultivaluedMap() throws Exception { assertFalse(multivaluedMapEntityProvider.isReadable(Object.class, null, null, null)); } @Test public void isWritableForMultivaluedMap() throws Exception { assertTrue(multivaluedMapEntityProvider.isWriteable(MultivaluedMap.class, null, null, null)); } @Test public void isNotWritableForTypeOtherThanMultivaluedMap() throws Exception { assertFalse(multivaluedMapEntityProvider.isWriteable(Object.class, null, null, null)); } @SuppressWarnings("unchecked") @Test public void readsContentOfEntityStreamAsMultivaluedMap() throws Exception { MultivaluedMap<String, String> multivaluedMap = multivaluedMapEntityProvider.readFrom((Class)MultivaluedMap.class, multiValuedMapGenericType, null, APPLICATION_FORM_URLENCODED_TYPE, new MultivaluedMapImpl(), new ByteArrayInputStream(testContent)); Map<String, List<String>> decodedMap = ImmutableMap.of("foo", newArrayList("to be or not to be"), "bar", newArrayList("hello world")); Map<String, List<String>> encodedMap = ImmutableMap.of("foo", newArrayList("to%20be%20or%20not%20to%20be"), "bar", newArrayList("hello%20world")); assertEquals(decodedMap, multivaluedMap); ArgumentCaptor<Object> argumentCaptor = ArgumentCaptor.forClass(Object.class); verify(context.getAttributes()).put(eq("org.everrest.provider.entity.decoded.form"), argumentCaptor.capture()); assertEquals(decodedMap, argumentCaptor.getValue()); verify(context.getAttributes()).put(eq("org.everrest.provider.entity.encoded.form"), argumentCaptor.capture()); assertEquals(encodedMap, argumentCaptor.getValue()); } @SuppressWarnings("unchecked") @Test public void getsParsedDecodedMultivaluedMapFromContextIfPresent() throws Exception { MultivaluedMap<String, String> decodedMap = new MultivaluedHashMap<>(); when(context.getAttributes().get("org.everrest.provider.entity.decoded.form")).thenReturn(decodedMap); MultivaluedMap<String, String> multivaluedMap = multivaluedMapEntityProvider.readFrom((Class)MultivaluedMap.class, multiValuedMapGenericType, null, APPLICATION_FORM_URLENCODED_TYPE, new MultivaluedMapImpl(), new ByteArrayInputStream(testContent)); assertSame(decodedMap, multivaluedMap); } @SuppressWarnings("unchecked") @Test public void getsParametersFromServletRequestWhenEntityStreamIsEmpty() throws Exception { Map<String, String[]> parameterMap = ImmutableMap.of("foo", new String[]{"to be or not to be"}, "bar", new String[]{"hello world"}); when(servletRequest.getParameterMap()).thenReturn(parameterMap); MultivaluedMap<String, String> multivaluedMap = multivaluedMapEntityProvider.readFrom((Class)MultivaluedMap.class, multiValuedMapGenericType, null, APPLICATION_FORM_URLENCODED_TYPE, new MultivaluedMapImpl(), new EmptyInputStream()); Map<String, List<String>> decodedMap = ImmutableMap.of("foo", newArrayList("to be or not to be"), "bar", newArrayList("hello world")); assertEquals(decodedMap, multivaluedMap); ArgumentCaptor<Object> argumentCaptor = ArgumentCaptor.forClass(Object.class); verify(context.getAttributes()).put(eq("org.everrest.provider.entity.decoded.form"), argumentCaptor.capture()); assertEquals(decodedMap, argumentCaptor.getValue()); verify(context.getAttributes()).put(eq("org.everrest.provider.entity.encoded.form"), argumentCaptor.capture()); assertTrue(((MultivaluedMap)argumentCaptor.getValue()).isEmpty()); } @SuppressWarnings("unchecked") @Test public void readsContentOfEntityStreamAsMultivaluedMapWhenFormFieldMissedValue() throws Exception { testContent = "foo&bar=hello%20world".getBytes("UTF-8"); MultivaluedMap<String, String> multivaluedMap = multivaluedMapEntityProvider.readFrom((Class)MultivaluedMap.class, multiValuedMapGenericType, null, APPLICATION_FORM_URLENCODED_TYPE, new MultivaluedMapImpl(), new ByteArrayInputStream(testContent)); Map<String, List<String>> decodedMap = ImmutableMap.of("foo", newArrayList(""), "bar", newArrayList("hello world")); assertEquals(decodedMap, multivaluedMap); } @Test public void writesMultivaluedMapToOutputStream() throws Exception { MultivaluedMap<String, String> multivaluedMap = new MultivaluedHashMap<>(); multivaluedMap.put("bar", newArrayList("hello world")); multivaluedMap.put("foo", newArrayList("to be or not to be")); ByteArrayOutputStream out = new ByteArrayOutputStream(); multivaluedMapEntityProvider.writeTo(multivaluedMap, MultivaluedMap.class, multiValuedMapGenericType, null, APPLICATION_FORM_URLENCODED_TYPE, new MultivaluedHashMap<>(), out); assertEquals("bar=hello+world&foo=to+be+or+not+to+be", out.toString()); } }