/*******************************************************************************
* 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.wink.server.internal;
import java.util.Arrays;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.RuntimeDelegate;
import org.apache.wink.common.http.HttpHeadersEx;
import org.apache.wink.common.http.HttpStatus;
import org.apache.wink.common.http.OPTIONS;
import org.apache.wink.server.internal.servlet.MockServletInvocationTest;
import org.junit.Assert;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
public class OptionsMethodTest extends MockServletInvocationTest {
private static final String[] METHODS = {"HEAD", "GET", "PUT", "DELETE", "POST", "OPTIONS"};
@Override
protected Class<?>[] getClasses() {
return new Class[] {OptionsResource.class, CustomOptionsResource.class};
}
@Path(OptionsResource.PATH)
public static class OptionsResource {
public static final String PATH = "/test";
@GET
@Produces( {MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
public void get() {
}
@PUT
@Consumes( {MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
public void put() {
}
@DELETE
public void delete() {
}
@POST
@Consumes( {MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
@Produces( {MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_JSON})
public void post() {
}
}
@Path(CustomOptionsResource.PATH)
public static class CustomOptionsResource extends OptionsResource {
public static final String PATH = "/test-custom";
public static final String CUSTOM_HEADER = "x-myheader";
@OPTIONS
public Response options() {
Response response =
RuntimeDelegate.getInstance().createResponseBuilder().status(204)
.header(CUSTOM_HEADER, "value").build();
return response;
}
}
public void testDefaultOptionsMethod() throws Exception {
checkOptions(OptionsResource.PATH, METHODS, false);
}
public void testCustomOptionsMethod() throws Exception {
checkOptions(CustomOptionsResource.PATH, METHODS, true);
}
private void checkOptions(String path, String[] methods, boolean customHeader) throws Exception {
// request
MockHttpServletRequest request = new MockHttpServletRequest() {
public String getPathTranslated() {
return null; // prevent Spring to resolve the file on the file
// system which fails
}
};
request.setMethod("OPTIONS");
request.setRequestURI(path);
MockHttpServletResponse response = invoke(request);
// response
// check status code
Assert.assertEquals(HttpStatus.NO_CONTENT.getCode(), response.getStatus());
// custom header
if (customHeader) {
Assert.assertNotNull(response.getHeader(CustomOptionsResource.CUSTOM_HEADER));
} else {
// check allow
String allowStr = (String)response.getHeader(HttpHeadersEx.ALLOW);
List<String> allows = Arrays.asList(allowStr.split("\\s*,\\s*"));
Assert.assertEquals(methods.length, allows.size());
for (String method : methods) {
Assert.assertTrue(allows.contains(method));
}
Assert.assertNull(response.getHeader(CustomOptionsResource.CUSTOM_HEADER));
}
}
}