/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2012-2015 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * http://glassfish.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package org.glassfish.jersey.tests.api; import java.security.AccessController; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; import javax.ws.rs.core.Cookie; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.NewCookie; import javax.ws.rs.core.Response; import javax.ws.rs.core.Variant; import org.glassfish.jersey.internal.util.PropertiesHelper; import org.glassfish.jersey.message.internal.HeaderUtils; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** * @author Pavel Bucek (pavel.bucek at oracle.com) */ public class ResponseTest { /* * Create an instance of Response using Response.ok(String, Variant).build() * verify that correct status code is returned */ @Test public void OkTest5() { Response resp; int status = 200; String content = "Test Only"; List<String> encoding = Arrays.asList("gzip", "compress"); List<String> lang = Arrays.asList("en-US", "en-GB", "zh-CN"); MediaType mt = new MediaType("text", "plain"); List<Variant> vts = Variant.VariantListBuilder.newInstance().mediaTypes(mt) .languages(new Locale("en", "US"), new Locale("en", "GB"), new Locale("zh", "CN")).encodings((String[]) encoding.toArray()) .add().build(); String tmp; for (Variant vt : vts) { resp = Response.ok(content, vt).build(); tmp = verifyResponse(resp, content, status, encoding, lang, null, null, null, null); if (tmp.endsWith("false")) { System.out.println("### " + tmp); fail(); } } } /* * Create an instance of Response using * Response.ResponseBuilder.clone() * verify that correct status code is returned */ @Test public void cloneTest() throws CloneNotSupportedException { StringBuilder sb = new StringBuilder(); int status = 200; List<String> type = Arrays.asList("text/plain", "text/html"); List<String> encoding = Arrays.asList("gzip", "compress"); List<String> lang = Arrays.asList("en-US", "en-GB", "zh-CN"); String name = "name_1"; String value = "value_1"; Cookie ck1 = new Cookie(name, value); NewCookie nck1 = new NewCookie(ck1); List<String> cookies = Arrays.asList(nck1.toString().toLowerCase()); Response.ResponseBuilder respb1 = Response.status(status) .header("Content-type", "text/plain").header("Content-type", "text/html").header("Content-Language", "en-US") .header("Content-Language", "en-GB").header("Content-Language", "zh-CN").header("Cache-Control", "no-transform") .header("Set-Cookie", "name_1=value_1;version=1"); Response.ResponseBuilder respb2 = respb1.clone(); Response resp2 = respb2.build(); String tmp = verifyResponse(resp2, null, status, encoding, lang, type, null, null, cookies); if (tmp.endsWith("false")) { System.out.println("### " + sb.toString()); fail(); } sb.append(tmp).append(newline); String content = "TestOnly"; Response resp1 = respb1.entity(content).cookie((NewCookie) null).build(); tmp = verifyResponse(resp1, content, status, encoding, lang, type, null, null, null); if (tmp.endsWith("false")) { System.out.println("### " + sb.toString()); fail(); } MultivaluedMap<java.lang.String, java.lang.Object> mvp = resp1.getMetadata(); if (mvp.containsKey("Set-Cookie")) { sb.append("Response contains unexpected Set-Cookie: ").append(mvp.getFirst("Set-Cookie").toString()).append(newline); System.out.println("### " + sb.toString()); fail(); } sb.append(tmp).append(newline); } /* * Create an instance of Response using * Response.fromResponse(Response).build() * verify that correct status code is returned */ @Test public void fromResponseTest() { int status = 200; String content = "Test Only"; List<String> type = Arrays.asList("text/plain", "text/html"); List<String> encoding = Arrays.asList("gzip", "compress"); List<String> lang = Arrays.asList("en-US", "en-GB", "zh-CN"); MediaType mt1 = new MediaType("text", "plain"); MediaType mt2 = new MediaType("text", "html"); List<Variant> vts = Variant.VariantListBuilder.newInstance().mediaTypes(mt1, mt2) .languages(new Locale("en", "US"), new Locale("en", "GB"), new Locale("zh", "CN")).encodings((String[]) encoding.toArray()) .add().build(); String tmp; for (Variant vt : vts) { Response resp1 = Response.ok(content, vt).build(); Response resp = Response.fromResponse(resp1).build(); tmp = verifyResponse(resp, content, status, encoding, lang, type, null, null, null); if (tmp.endsWith("false")) { System.out.println("### " + tmp); fail(); } } } /* * Create an instance of Response using * Response.ResponseBuilder.header(String, Object).build() * verify that correct status code is returned */ @Test public void headerTest() { int status = 200; List<String> type = Arrays.asList("text/plain", "text/html"); List<String> encoding = Arrays.asList("gzip", "compress"); List<String> lang = Arrays.asList("en-US", "en-GB", "zh-CN"); String name = "name_1"; String value = "value_1"; Cookie ck1 = new Cookie(name, value); NewCookie nck1 = new NewCookie(ck1); List<String> cookies = Arrays.asList(nck1.toString().toLowerCase()); Response resp = Response.status(status).header("Content-type", "text/plain").header("Content-type", "text/html").header("Content-Language", "en-US") .header("Content-Language", "en-GB").header("Content-Language", "zh-CN").header("Cache-Control", "no-transform") .header("Set-Cookie", "name_1=value_1;version=1").build(); String tmp = verifyResponse(resp, null, status, encoding, lang, type, null, null, cookies); if (tmp.endsWith("false")) { System.out.println("### " + tmp); fail(); } } /* * Create an instance of Response using * Response.status(int).variant(Variant).build() * verify that correct status code is returned */ @Test public void variantTest() { Response resp; int status = 200; List<String> encoding = Arrays.asList("gzip", "compress"); List<String> lang = Arrays.asList("en-US", "en-GB", "zh-CN"); MediaType mt = new MediaType("text", "plain"); List<Variant> vts = Variant.VariantListBuilder.newInstance().mediaTypes(mt) .languages(new Locale("en", "US"), new Locale("en", "GB"), new Locale("zh", "CN")).encodings((String[]) encoding.toArray()) .add().build(); String tmp; for (Variant vt : vts) { resp = Response.status(status).variant(vt).build(); tmp = verifyResponse(resp, null, status, encoding, lang, null, null, null, null); if (tmp.endsWith("false")) { System.out.println("### " + tmp); fail(); } } } private static final String indent = " "; private static final String newline = AccessController.doPrivileged(PropertiesHelper.getSystemProperty("line.separator")); private String verifyResponse(Response resp, String content, int status, List<String> encoding, List<String> language, List<String> type, List<String> var, List<String> ccl, List<String> cookies) { boolean pass = true; StringBuilder sb = new StringBuilder(); sb.append("========== Verifying a Response: ").append(newline); String tmp = verifyResponse(resp, content, status, null); sb.append(indent).append(tmp).append(newline); if (tmp.endsWith("false")) { pass = false; } MultivaluedMap<String, String> mvp = HeaderUtils.asStringHeaders( resp.getMetadata()); for (String key : mvp.keySet()) { sb.append(indent + "Processing Key found in response: ").append(key).append(": ").append(mvp.get(key)).append("; ") .append(newline); if (key.equalsIgnoreCase("Vary")) { for (String value : var) { String actual = mvp.get(key).toString().toLowerCase(); if (!actual.contains(value)) { pass = false; sb.append(indent + indent + "Expected header ").append(value).append(" not set in Vary.").append(newline); } else { sb.append(indent + indent + "Found expected header ").append(value).append(".").append(newline); } } } if (encoding != null) { if (key.equalsIgnoreCase("Content-encoding")) { for (Object enc : mvp.get(key)) { if (!encoding.contains(enc.toString().toLowerCase())) { pass = false; sb.append(indent + indent + "Encoding test failed: ").append(newline); } } } } if (language != null) { if (key.equalsIgnoreCase("Content-language")) { for (String lang : mvp.get(key)) { if (!language.contains(lang)) { pass = false; sb.append(indent + indent + "language test failed: ").append(lang) .append(" is not expected in Response").append(newline); for (String tt : language) { sb.append(indent + indent + "Expecting Content-Language ").append(tt).append(newline); } } } } } if (type != null) { if (key.equalsIgnoreCase("Content-Type")) { for (Object lang : mvp.get(key)) { if (!type.contains(lang.toString().toLowerCase())) { pass = false; sb.append(indent + indent + "Content-Type test failed: ").append(lang) .append(" is not expected in Response").append(newline); } } } } if (ccl != null) { for (String tt : ccl) { sb.append("Expecting Cache-Control ").append(tt).append(newline); } if (key.equalsIgnoreCase("Cache-Control")) { for (Object all_ccl : mvp.get(key)) { for (String cc : ccl) { if (!(all_ccl.toString().toLowerCase().contains(cc.toLowerCase()))) { pass = false; sb.append(indent + indent + "Cache-Control test failed: ").append(cc) .append(" is not found in Response.").append(newline); } } } } } if (cookies != null) { for (String tt : cookies) { sb.append(indent + indent + "Expecting Set-Cookie").append(tt).append(newline); } if (key.equalsIgnoreCase("Set-Cookie")) { for (Object nck_actual : mvp.get(key)) { sb.append(indent + indent + "Processing ").append(nck_actual.toString()).append(newline); if (!cookies.contains(nck_actual.toString().toLowerCase() .replace(" ", ""))) { pass = false; sb.append(indent + indent + "Set-Cookie test failed: ").append(nck_actual) .append(" is not expected in Response.").append(newline); } else { sb.append(indent + indent + "Expected Set-Cookie: ").append(nck_actual) .append(" is found in Response.").append(newline); } } } } } sb.append(indent).append(pass); return sb.toString(); } private String verifyResponse(Response resp, String content, int status, HashMap<String, String> expected_map) { boolean pass = true; StringBuilder sb = new StringBuilder(); sb.append("========== Verifying a Response with Map: ").append(newline); if ((content == null) || (content.equals(""))) { if (!(resp.getEntity() == null) || "".equals(resp.getEntity())) { pass = false; sb.append(indent + "Entity verification failed: expecting no content, got ").append((String) resp.getEntity()) .append(newline); } } else if (!content.equals(resp.getEntity())) { pass = false; sb.append(indent + "Entity verification failed: expecting ").append(content).append(", got ") .append((String) resp.getEntity()).append(newline); } else { sb.append(indent + "Correct content found in Response: ").append((String) resp.getEntity()).append(newline); } if (resp.getStatus() != status) { pass = false; sb.append(indent + "Status code verification failed: expecting ").append(status).append(", got ") .append(resp.getStatus()).append(newline); } else { sb.append(indent + "Correct status found in Response: ").append(status).append(newline); } MultivaluedMap<java.lang.String, java.lang.Object> mvp = resp.getMetadata(); if (expected_map == null) { sb.append(indent + "No keys to verify or expected, but found the following keys in Response:").append(newline); for (String key : mvp.keySet()) { sb.append(indent + indent + "Key: ").append(key).append("; ").append(mvp.getFirst(key)).append(";") .append(newline); } } else { for (String key_actual : mvp.keySet()) { sb.append(indent + "Response contains key: ").append(key_actual).append(newline); } sb.append(indent + "Verifying the following keys in Response:").append(newline); String actual, expected; for (String key : expected_map.keySet()) { if (!mvp.containsKey(key)) { pass = false; sb.append(indent + indent + "Key: ").append(key).append(" is not found in Response;").append(newline); } else if (key.equalsIgnoreCase("last-modified")) { sb.append(indent + indent + "Key Last-Modified is found in response").append(newline); } else { expected = expected_map.get(key).toLowerCase(); actual = mvp.getFirst(key).toString().toLowerCase(); if (actual.startsWith("\"") && actual.endsWith("\"")) { actual = actual.substring(1, actual.length() - 1); } if (!actual.equals(expected)) { pass = false; sb.append(indent + indent + "Key: ").append(key).append(" found in Response, but with different value;") .append(newline); sb.append(indent + indent + "Expecting ").append(expected_map.get(key)).append("; got ") .append(mvp.getFirst(key)).append(newline); } sb.append(indent + indent + "Processed key ").append(key).append(" with expected value ") .append(expected_map.get(key)).append(newline); } } } sb.append(indent).append(pass); return sb.toString(); } @Test public void testAllowString() { Response.ResponseBuilder responseBuilder = Response.ok(); responseBuilder = responseBuilder.allow("GET"); assertTrue(responseBuilder.build().getHeaderString(HttpHeaders.ALLOW).contains("GET")); responseBuilder = responseBuilder.allow((String) null); assertTrue(responseBuilder.build().getHeaderString(HttpHeaders.ALLOW) == null); } @Test public void testAllowSet() { Response.ResponseBuilder responseBuilder = Response.ok(); responseBuilder = responseBuilder.allow(new HashSet<>(Arrays.asList("GET"))); assertTrue(responseBuilder.build().getHeaderString(HttpHeaders.ALLOW).contains("GET")); responseBuilder = responseBuilder.allow((Set<String>) null); assertEquals(null, responseBuilder.build().getHeaderString(HttpHeaders.ALLOW)); } @Test public void testAllowVariant() { Response.ResponseBuilder responseBuilder = Response.ok(); responseBuilder = responseBuilder.allow(new HashSet<>(Arrays.asList("GET"))); assertTrue(responseBuilder.build().getHeaderString(HttpHeaders.ALLOW).contains("GET")); responseBuilder = responseBuilder.allow((String[]) null); assertEquals(null, responseBuilder.build().getHeaderString(HttpHeaders.ALLOW)); } @Test public void bufferEntityTest() { Response response = Response.ok().build(); response.close(); try { response.bufferEntity(); fail("IllegalStateException expected when reading entity after response has been closed."); } catch (IllegalStateException ex) { // expected } } @Test public void getEntityTest() { Response response = Response.ok().build(); response.close(); try { response.getEntity(); fail("IllegalStateException expected when reading entity after response has been closed."); } catch (IllegalStateException ex) { // expected } } @Test public void hasEntityTest() { Response response = Response.ok().build(); response.close(); try { response.hasEntity(); fail("IllegalStateException expected when reading entity after response has been closed."); } catch (IllegalStateException ex) { // expected } } // Reproducer for JERSEY-1553 @Test public void testVariants() { List<String> encoding = Arrays.asList("gzip", "compress"); List<Variant> list = Variant.VariantListBuilder .newInstance() .mediaTypes(MediaType.TEXT_PLAIN_TYPE) .languages(new Locale("en", "US"), new Locale("en", "GB")) .encodings(encoding.toArray(new String[encoding.size()])).add().build(); final Response r1 = Response.ok().variants(list).build(); assertNotNull(r1); assertNotNull(r1.getHeaderString(HttpHeaders.VARY)); final Response r2 = Response.ok().variants(list.toArray(new Variant[list.size()])).build(); assertNotNull(r2); assertNotNull(r2.getHeaderString(HttpHeaders.VARY)); } }