/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.cxf.jaxrs.impl;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Variant;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageImpl;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class RequestImplTest extends Assert {
private Message m;
private MultivaluedMap<String, String> metadata;
@Before
public void setUp() {
m = new MessageImpl();
metadata = new MetadataMap<String, String>();
m.put(Message.PROTOCOL_HEADERS, metadata);
m.put(Message.HTTP_REQUEST_METHOD, "GET");
}
@After
public void tearUp() {
m = null;
metadata.clear();
}
@Test
public void testSingleMatchingVariant() {
metadata.putSingle(HttpHeaders.CONTENT_TYPE, "application/xml");
metadata.putSingle(HttpHeaders.CONTENT_LANGUAGE, "en");
metadata.putSingle(HttpHeaders.CONTENT_ENCODING, "utf-8");
assertSameVariant(MediaType.APPLICATION_XML_TYPE, new Locale("en"), StandardCharsets.UTF_8.name());
assertSameVariant(null, new Locale("en"), StandardCharsets.UTF_8.name());
assertSameVariant(MediaType.APPLICATION_XML_TYPE, null, StandardCharsets.UTF_8.name());
assertSameVariant(MediaType.APPLICATION_XML_TYPE, new Locale("en"), null);
}
@Test
public void testSingleMatchingVariantWithContentTypeOnly() {
metadata.putSingle(HttpHeaders.CONTENT_TYPE, "application/xml");
assertSameVariant(MediaType.APPLICATION_XML_TYPE, new Locale("en"), StandardCharsets.UTF_8.name());
assertSameVariant(null, new Locale("en"), StandardCharsets.UTF_8.name());
assertSameVariant(MediaType.APPLICATION_XML_TYPE, null, StandardCharsets.UTF_8.name());
assertSameVariant(MediaType.APPLICATION_XML_TYPE, new Locale("en"), null);
}
@Test
public void testSingleNonMatchingVariant() {
metadata.putSingle(HttpHeaders.ACCEPT, "application/xml");
metadata.putSingle(HttpHeaders.ACCEPT_LANGUAGE, "en");
metadata.putSingle(HttpHeaders.ACCEPT_ENCODING, "utf-8");
List<Variant> list = new ArrayList<>();
list.add(new Variant(MediaType.APPLICATION_JSON_TYPE, new Locale("en"), "utf-8"));
assertNull(new RequestImpl(m).selectVariant(list));
}
@Test
public void testMultipleNonMatchingVariants() {
metadata.putSingle(HttpHeaders.ACCEPT, "application/xml");
metadata.putSingle(HttpHeaders.ACCEPT_LANGUAGE, "en");
metadata.putSingle(HttpHeaders.ACCEPT_ENCODING, "utf-8");
List<Variant> list = new ArrayList<>();
list.add(new Variant(MediaType.APPLICATION_JSON_TYPE, new Locale("en"), "utf-8"));
list.add(new Variant(MediaType.APPLICATION_XML_TYPE, new Locale("es"), "utf-8"));
list.add(new Variant(MediaType.APPLICATION_XML_TYPE, new Locale("en"), "abc"));
assertNull(new RequestImpl(m).selectVariant(list));
}
@Test
public void testMultipleVariantsSingleMatch() {
metadata.putSingle(HttpHeaders.ACCEPT, "application/xml");
metadata.putSingle(HttpHeaders.ACCEPT_LANGUAGE, "en");
metadata.putSingle(HttpHeaders.ACCEPT_ENCODING, "gzip");
List<Variant> list = new ArrayList<>();
list.add(new Variant(MediaType.APPLICATION_JSON_TYPE, new Locale("en"), "utf-8"));
list.add(new Variant(MediaType.APPLICATION_XML_TYPE, new Locale("es"), "utf-8"));
Variant var3 = new Variant(MediaType.APPLICATION_XML_TYPE, new Locale("en"), "gzip");
list.add(var3);
assertSame(var3, new RequestImpl(m).selectVariant(list));
}
@Test
public void testMultipleVariantsBestMatch() {
metadata.putSingle(HttpHeaders.ACCEPT, "application/xml");
metadata.putSingle(HttpHeaders.ACCEPT_LANGUAGE, "en-us");
metadata.putSingle(HttpHeaders.ACCEPT_ENCODING, "gzip;q=1.0, compress");
List<Variant> list = new ArrayList<>();
list.add(new Variant(MediaType.APPLICATION_JSON_TYPE, new Locale("en"), "gzip"));
Variant var2 = new Variant(MediaType.APPLICATION_XML_TYPE, new Locale("en"), "gzip");
list.add(var2);
Variant var3 = new Variant(MediaType.APPLICATION_XML_TYPE, new Locale("en"), null);
list.add(var3);
assertSame(var2, new RequestImpl(m).selectVariant(list));
list.clear();
list.add(var3);
assertSame(var3, new RequestImpl(m).selectVariant(list));
}
private void assertSameVariant(MediaType mt, Locale lang, String enc) {
Variant var = new Variant(mt, lang, enc);
List<Variant> list = new ArrayList<>();
list.add(var);
assertSame(var, new RequestImpl(m).selectVariant(list));
}
@Test
public void testWeakEtags() {
metadata.putSingle("If-Match", new EntityTag("123", true).toString());
ResponseBuilder rb =
new RequestImpl(m).evaluatePreconditions(new EntityTag("123"));
assertNotNull("Strict compararison is required", rb);
Response r = rb.build();
assertEquals("If-Match precondition was not met", 412, r.getStatus());
assertEquals("Response should include ETag",
"\"123\"", r.getMetadata().getFirst("ETag").toString());
}
@Test
public void testGetMethod() {
assertEquals("Wrong method",
"GET", new RequestImpl(m).getMethod());
}
@Test
public void testStrictEtagsPreconditionMet() {
metadata.putSingle("If-Match", new EntityTag("123").toString());
ResponseBuilder rb =
new RequestImpl(m).evaluatePreconditions(new EntityTag("123"));
assertNull("Precondition must be met", rb);
}
@Test
public void testStrictEtagsPreconditionNotMet() {
metadata.putSingle("If-Match", new EntityTag("123", true).toString());
ResponseBuilder rb =
new RequestImpl(m).evaluatePreconditions(new EntityTag("123"));
assertEquals("Precondition must not be met, strict comparison is required",
412, rb.build().getStatus());
}
@Test
public void testStarEtags() {
metadata.putSingle("If-Match", "*");
ResponseBuilder rb =
new RequestImpl(m).evaluatePreconditions(new EntityTag("123"));
assertNull("Precondition must be met", rb);
}
@Test
public void testStarEtagsIfNotMatch() {
metadata.putSingle(HttpHeaders.IF_NONE_MATCH, "*");
ResponseBuilder rb =
new RequestImpl(m).evaluatePreconditions(new EntityTag("123"));
assertEquals("Precondition must not be met",
304, rb.build().getStatus());
}
@Test
public void testIfNotMatchAndLastModified() {
metadata.putSingle(HttpHeaders.IF_NONE_MATCH, "1");
ResponseBuilder rb =
new RequestImpl(m).evaluatePreconditions(new Date(), new EntityTag("1"));
assertEquals("Precondition must not be met",
304, rb.build().getStatus());
}
@Test
public void testEtagsIfNotMatch() {
metadata.putSingle(HttpHeaders.IF_NONE_MATCH, "\"123\"");
ResponseBuilder rb =
new RequestImpl(m).evaluatePreconditions(new EntityTag("123"));
assertEquals("Precondition must not be met",
304, rb.build().getStatus());
}
@Test
public void testStarEtagsIfNotMatchPut() {
metadata.putSingle(HttpHeaders.IF_NONE_MATCH, "*");
m.put(Message.HTTP_REQUEST_METHOD, "PUT");
ResponseBuilder rb =
new RequestImpl(m).evaluatePreconditions(new EntityTag("123"));
assertEquals("Precondition must not be met",
412, rb.build().getStatus());
}
@Test
public void testBeforeDate() throws Exception {
metadata.putSingle("If-Modified-Since", "Tue, 21 Oct 2008 14:00:00 GMT");
Date serverDate = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH)
.parse("Tue, 21 Oct 2008 17:00:00 GMT");
ResponseBuilder rb =
new RequestImpl(m).evaluatePreconditions(serverDate);
assertNull("Precondition must be met", rb);
}
@Test
public void testBeforeDateIfNotModified() throws Exception {
metadata.putSingle(HttpHeaders.IF_UNMODIFIED_SINCE, "Mon, 20 Oct 2008 14:00:00 GMT");
Date serverDate = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH)
.parse("Tue, 21 Oct 2008 14:00:00 GMT");
ResponseBuilder rb =
new RequestImpl(m).evaluatePreconditions(serverDate);
assertEquals("Precondition must not be met", 412, rb.build().getStatus());
}
@Test
public void testAfterDate() throws Exception {
metadata.putSingle("If-Modified-Since", "Tue, 21 Oct 2008 14:00:00 GMT");
Date lastModified = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH)
.parse("Mon, 20 Oct 2008 14:00:00 GMT");
ResponseBuilder rb =
new RequestImpl(m).evaluatePreconditions(lastModified);
assertNotNull("Precondition is not met", rb);
Response r = rb.build();
assertEquals("If-Modified-Since precondition was not met", 304, r.getStatus());
}
@Test
public void testIfNoneMatchAndDateWithMatchingTags() throws Exception {
metadata.putSingle(HttpHeaders.IF_NONE_MATCH, "\"123\"");
metadata.putSingle("If-Modified-Since", "Tue, 21 Oct 2008 14:00:00 GMT");
Date lastModified = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH)
.parse("Mon, 22 Oct 2008 14:00:00 GMT");
ResponseBuilder rb =
new RequestImpl(m).evaluatePreconditions(lastModified, new EntityTag("\"123\""));
assertNull("Precondition is not met", rb);
}
@Test
public void testIfNoneMatchAndDateWithNonMatchingTags() throws Exception {
metadata.putSingle(HttpHeaders.IF_NONE_MATCH, "\"123\"");
metadata.putSingle("If-Modified-Since", "Tue, 20 Oct 2008 14:00:00 GMT");
Date lastModified = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH)
.parse("Mon, 21 Oct 2008 14:00:00 GMT");
ResponseBuilder rb =
new RequestImpl(m).evaluatePreconditions(lastModified, new EntityTag("124"));
assertNull("Dates must not be checked if tags do not match", rb);
}
}