com.google.api.server.spi.response.ServletResponseResultWriterTest.java Source code

Java tutorial

Introduction

Here is the source code for com.google.api.server.spi.response.ServletResponseResultWriterTest.java

Source

/*
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.api.server.spi.response;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.google.api.server.spi.ObjectMapperUtil;
import com.google.api.server.spi.types.DateAndTime;
import com.google.api.server.spi.types.SimpleDate;
import com.google.appengine.api.datastore.Blob;
import com.google.common.collect.ImmutableMap;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.springframework.mock.web.MockHttpServletResponse;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

/**
 * Tests for {@link ServletResponseResultWriter}.
 */
@RunWith(JUnit4.class)
public class ServletResponseResultWriterTest {

    private static final long DATE_VALUE = 1000000000L;
    private static final String DATE_VALUE_STRING = "1970-01-12T13:46:40.000";
    private static final String DATE_AND_TIME_VALUE_STRING = "2002-10-02T10:00:00-05:00";
    private static final String SIMPLE_DATE_VALUE_STRING = "2002-10-02";

    @Test
    public void testTypeChangesInMapAsString() throws Exception {
        Map<String, Object> value = new HashMap<>();
        value.put("nonPrimitive", 100L);
        value.put("primitive", 200L);
        value.put("date", new Date(DATE_VALUE));
        value.put("dateAndTime", DateAndTime.parseRfc3339String(DATE_AND_TIME_VALUE_STRING));
        value.put("simpleDate", new SimpleDate(2002, 10, 2));
        testTypeChangesAsString(value);
    }

    @SuppressWarnings("unused")
    public void testTypeChangesInBeanAsString() throws Exception {
        Object value = new Object() {
            public long getPrimitive() {
                return 200L;
            }

            public Long getNonPrimitive() {
                return 100L;
            }

            public Long getLongNull() {
                return null;
            }

            public String getStringNull() {
                return null;
            }

            public String getStringEmpty() {
                return "";
            }

            public Date getDate() {
                return new Date(DATE_VALUE);
            }

            public Date getDateNull() {
                return null;
            }

            public DateAndTime getDateAndTime() {
                return DateAndTime.parseRfc3339String(DATE_AND_TIME_VALUE_STRING);
            }

            public DateAndTime getDateAndTimeNull() {
                return null;
            }

            public SimpleDate getSimpleDate() {
                return new SimpleDate(2002, 10, 2);
            }

            public SimpleDate getSimpleDateNull() {
                return null;
            }

            public Long[] getEmptyLongArray() {
                return new Long[0];
            }

            public List<Long> getEmptyLongList() {
                return new ArrayList<>();
            }
        };
        ObjectNode output = testTypeChangesAsString(value);
        assertTrue(output.path("longNull").isMissingNode());
        assertTrue(output.path("stringNull").isMissingNode());
        assertEquals("", output.path("stringEmpty").asText());
        assertTrue(output.path("dateNull").isMissingNode());
        assertTrue(output.path("dateAndTimeNull").isMissingNode());
        assertTrue(output.path("simpleDateNull").isMissingNode());
        assertTrue(output.path("emptyLongArray").isMissingNode());
        assertTrue(output.path("emptyLongList").isMissingNode());
    }

    @Test
    public void testTypeChangesInArrayAsString() throws Exception {
        Object[] array = new Object[] { 100L, 200L };
        String responseBody = writeToResponse(array);

        ObjectNode output = ObjectMapperUtil.createStandardObjectMapper().readValue(responseBody, ObjectNode.class);
        ArrayNode items = (ArrayNode) output.get("items");
        assertTrue(items.get(0).isTextual());
        assertEquals("100", items.get(0).asText());
        assertTrue(items.get(1).isTextual());
        assertEquals("200", items.get(1).asText());
    }

    @Test
    public void testWriteNull() throws Exception {
        MockHttpServletResponse response = new MockHttpServletResponse();
        ServletResponseResultWriter writer = new ServletResponseResultWriter(response, null);
        writer.write(null);
        assertEquals("", response.getContentAsString());
        assertEquals(HttpServletResponse.SC_NO_CONTENT, response.getStatus());
    }

    @SuppressWarnings("unused")
    public void testByteArrayAsBase64() throws Exception {
        Object value = new Object() {
            public byte[] getValues() {
                return new byte[] { 1, 2, 3, 4 };
            }
        };
        ObjectNode output = ObjectMapperUtil.createStandardObjectMapper().readValue(writeToResponse(value),
                ObjectNode.class);
        assertEquals("AQIDBA==", output.path("values").asText());
    }

    @Test
    public void testWriteErrorResponseHeaders() throws Exception {
        MockHttpServletResponse response = new MockHttpServletResponse();
        ServletResponseResultWriter writer = new ServletResponseResultWriter(response, null);
        Map<String, String> headers = new LinkedHashMap<>();
        headers.put("name0", "value0");
        headers.put("name1", "value1");
        writer.writeError(new UnauthorizedException("message", "schema", headers));
        assertEquals("schema name0=value0, name1=value1", response.getHeader("WWW-Authenticate"));
    }

    @Test
    public void testPrettyPrint() throws Exception {
        MockHttpServletResponse response = new MockHttpServletResponse();
        ServletResponseResultWriter writer = new ServletResponseResultWriter(response, null,
                true /* prettyPrint */);
        writer.write(ImmutableMap.of("one", "two", "three", "four"));
        // If the response is pretty printed, there should be at least two newlines.
        String body = response.getContentAsString();
        int index = body.indexOf('\n');
        assertThat(index).isAtLeast(0);
        index = body.indexOf('\n', index + 1);
        assertThat(index).isAtLeast(0);
        // Unlike the Jackson pretty printer, which will either put no space around a colon or a space
        // on both sides, we want to ensure that a space comes after a colon, but not before.
        assertThat(body).contains("\": ");
        assertThat(body).doesNotContain("\" :");
    }

    @SuppressWarnings("unused")
    public void testBlobAsBase64() throws Exception {
        Object value = new Object() {
            public Blob getBlob() {
                return new Blob(new byte[] { 1, 2, 3, 4 });
            }
        };
        ObjectNode output = ObjectMapperUtil.createStandardObjectMapper().readValue(writeToResponse(value),
                ObjectNode.class);
        assertEquals("AQIDBA==", output.path("blob").asText());
    }

    public enum TestEnum {
        TEST1, TEST2
    }

    @Test
    public void testEnumAsString() throws Exception {
        TestEnum value = TestEnum.TEST1;
        JsonNode output = ObjectMapperUtil.createStandardObjectMapper().readValue(writeToResponse(value),
                JsonNode.class);
        assertEquals("TEST1", output.asText());
    }

    private ObjectNode testTypeChangesAsString(Object value) throws Exception {
        String responseBody = writeToResponse(value);
        ObjectNode output = ObjectMapperUtil.createStandardObjectMapper().readValue(responseBody, ObjectNode.class);
        assertTrue(output.get("nonPrimitive").isTextual());
        assertEquals("100", output.get("nonPrimitive").asText());
        assertTrue(output.get("primitive").isTextual());
        assertEquals("200", output.get("primitive").asText());
        assertEquals(new com.google.api.client.util.DateTime(DATE_VALUE_STRING),
                new com.google.api.client.util.DateTime(output.get("date").asText()));
        assertEquals(DATE_AND_TIME_VALUE_STRING, output.get("dateAndTime").asText());
        assertEquals(DateAndTime.parseRfc3339String(DATE_AND_TIME_VALUE_STRING),
                DateAndTime.parseRfc3339String(output.get("dateAndTime").asText()));
        assertEquals(SIMPLE_DATE_VALUE_STRING, output.get("simpleDate").asText());
        return output;
    }

    private String writeToResponse(Object value) throws IOException {
        MockHttpServletResponse response = new MockHttpServletResponse();
        ServletResponseResultWriter writer = new ServletResponseResultWriter(response, null);
        writer.write(value);
        return response.getContentAsString();
    }
}