package io.swagger;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiParam;
import io.swagger.models.ModelImpl;
import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.HeaderParameter;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.parameters.PathParameter;
import io.swagger.models.parameters.QueryParameter;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.DoubleProperty;
import io.swagger.models.properties.IntegerProperty;
import io.swagger.models.properties.LongProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.StringProperty;
import io.swagger.util.ParameterProcessor;
import org.testng.annotations.Test;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
public class ParameterProcessorTest {
private static final String TEST_PATTERN_REGXP = "^[A-Z]+$";
private void parametrizedMethod(
@ApiParam(name = "paramName1", value = "paramValue1", defaultValue = "value1", required = true,
allowableValues = "one, two, three, ")
@PathParam("param1") String arg1,
@ApiParam(name = "paramName2", access = "test")
@DefaultValue("10")
@QueryParam("param2") List<Integer> arg2,
@Context String arg3,
@ApiParam(name = "paramName4", hidden = true)
@QueryParam("hiddenParam") String arg4,
@ApiParam(name = "paramName4")
Integer arg5) {
}
@ApiImplicitParams({
@ApiImplicitParam(name = "paramName1", value = "paramValue1", dataType = "string", paramType = "path",
allowMultiple = true, allowableValues = ",,,"),
@ApiImplicitParam(value = "paramValue2", dataType = "string", paramType = "body", access = "test",
defaultValue = "10")
})
private void implicitParametrizedMethod() {
}
private void rangedParametrizedMethod(
@ApiParam(value = "sample param data", defaultValue = "5", allowableValues = "range[0,10]", collectionFormat = "multi")
@PathParam("id") Integer id,
@ApiParam(value = "sample positive infinity data", allowableValues = "range(0, infinity)")
@PathParam("minValue") Double minValue,
@ApiParam(value = "sample negative infinity data", allowableValues = "range[-infinity, 100]")
@PathParam("maxValue") Integer maxValue,
@ApiParam(value = "sample array data", allowMultiple = true, allowableValues = "range(0, 5)")
@PathParam("values") Integer values) {
}
private void arrayParametrizedMethod(@HeaderParam("ids") @Size(min = 5, max = 10) List<Long> ids) {
}
private void beanValidationSizeOnNumber(
@QueryParam("intValue") @Size(min = 5, max = 10) int intValue,
@QueryParam("shortValue") @Size(min = 5, max = 10) short shortValue,
@QueryParam("longValue") @Size(min = 5, max = 10) long longValue,
@QueryParam("floatValue") @Size(min = 5, max = 10) float floatValue,
@QueryParam("doubleValue") @Size(min = 5, max = 10) double doubleValue,
@QueryParam("intWrapperValue") @Size(min = 5, max = 10) Integer intWrapperValue,
@QueryParam("shortWrapperValue") @Size(min = 5, max = 10) Short shortWrapperValue,
@QueryParam("longWrapperValue") @Size(min = 5, max = 10) Long longWrapperValue,
@QueryParam("floatWrapperValue") @Size(min = 5, max = 10) Float floatWrapperValue,
@QueryParam("doubleWrapperValue") @Size(min = 5, max = 10) Double doubleWrapperValue,
@QueryParam("bigIntegerWrapperValue") @Size(min = 5, max = 10) BigInteger bigIntegerWrapperValue,
@QueryParam("bigDecimalWrapperValue") @Size(min = 5, max = 10) BigDecimal bigDecimalWrapperValue) {
}
private void beanValidationSizeOnString(
@QueryParam("stringValue") @Size(min = 5, max = 10) String stringValue) {
}
private void beanValidationMin(
@QueryParam("value") @Min(value = 5) int value) {
}
private void beanValidationMax(
@QueryParam("value") @Max(value = 10) int value) {
}
private void beanValidationDecimalMin(
@QueryParam("inclusiveValue") @DecimalMin(value = "5.5") double inclusiveValue,
@QueryParam("exclusiveValue") @DecimalMin(value = "5.5", inclusive = false) double exclusiveValue) {
}
private void beanValidationDecimalMax(
@QueryParam("inclusiveMax") @DecimalMax(value = "10.5") double inclusiveValue,
@QueryParam("exclusiveMax") @DecimalMax(value = "10.5", inclusive = false) double exclusiveValue) {
}
private void beanValidationPattern(
@QueryParam("patternValue") @Pattern(regexp = TEST_PATTERN_REGXP) String patternValue) {
}
private void beanValidationArrayParametrizedMethod(
@HeaderParam("intValues")
@Size(min = 5, max = 10)
@Min(value = 5)
@Max(value = 10) List<Integer> intValues,
@HeaderParam("doubleValues")
@Size(min = 5, max = 10)
@DecimalMin(value = "5.5", inclusive = false)
@DecimalMax(value = "10.5", inclusive = false) List<Double> doubleValues,
@HeaderParam("stringValues")
@Size(min = 5, max = 10)
@Pattern(regexp = TEST_PATTERN_REGXP) List<String> stringValues,
@ApiParam(allowMultiple = true)
@HeaderParam("allowMultipleValues")
@Size(min = 5, max = 10) String allowMultipleValues
) {
}
@Test(description = "parse parameters from method")
public void parameterProcessorTest() throws NoSuchMethodException {
final Method method = getClass().getDeclaredMethod("parametrizedMethod", String.class, List.class,
String.class, String.class, Integer.class);
final Type[] genericParameterTypes = method.getGenericParameterTypes();
final Annotation[][] paramAnnotations = method.getParameterAnnotations();
final PathParameter p1 = (PathParameter) ParameterProcessor.applyAnnotations(null, new PathParameter(),
genericParameterTypes[0], Arrays.asList(paramAnnotations[0]));
assertNotNull(p1);
assertEquals(p1.getIn(), "path");
assertEquals(p1.getName(), "paramName1");
assertEquals(p1.getDescription(), "paramValue1");
assertEquals(p1.getDefaultValue(), "value1");
assertTrue(p1.getRequired());
assertEquals(p1.getEnum(), Arrays.asList("one", "two", "three"));
assertNull(p1.getAccess());
final QueryParameter p2 = (QueryParameter) ParameterProcessor.applyAnnotations(null, new QueryParameter()
.items(new IntegerProperty()), genericParameterTypes[1], Arrays.asList(paramAnnotations[1]));
assertNotNull(p2);
final IntegerProperty items = (IntegerProperty) p2.getItems();
assertNotNull(items);
assertEquals(p2.getIn(), "query");
assertEquals(p2.getName(), "paramName2");
assertNull(p2.getDescription());
assertEquals((int) items.getDefault(), 10);
assertFalse(p2.getRequired());
assertEquals(p2.getAccess(), "test");
final Parameter p3 = ParameterProcessor.applyAnnotations(null, null,
genericParameterTypes[2], Arrays.asList(paramAnnotations[2]));
assertNull(p3);
final Parameter p4 = ParameterProcessor.applyAnnotations(null, null,
genericParameterTypes[3], Arrays.asList(paramAnnotations[3]));
assertNull(p4);
final BodyParameter p5 = (BodyParameter) ParameterProcessor.applyAnnotations(null, null,
genericParameterTypes[4], Arrays.asList(paramAnnotations[4]));
assertNotNull(p5);
assertEquals(p5.getIn(), "body");
}
@ApiImplicitParams({
@ApiImplicitParam(name = "arrayParam", value = "paramValue1", dataType = "string", paramType = "path",
allowMultiple = true)
})
private void implicitArrayParametrizedMethod() {
}
@Test(description = "parse implicit parameters from method")
public void implicitArrayParameterProcessorTest() throws NoSuchMethodException {
final ApiImplicitParams params = getClass().getDeclaredMethod("implicitArrayParametrizedMethod")
.getAnnotation(ApiImplicitParams.class);
final PathParameter param0 = (PathParameter) ParameterProcessor.applyAnnotations(null, new PathParameter(),
String.class, Collections.<Annotation>singletonList(params.value()[0]));
assertEquals(param0.getType(), "array");
assertEquals(param0.getItems().getType(), "string");
}
@Test(description = "parse implicit parameters from method")
public void implicitParameterProcessorTest() throws NoSuchMethodException {
final ApiImplicitParams params = getClass().getDeclaredMethod("implicitParametrizedMethod")
.getAnnotation(ApiImplicitParams.class);
final PathParameter param0 = (PathParameter) ParameterProcessor.applyAnnotations(null, new PathParameter(),
String.class, Collections.<Annotation>singletonList(params.value()[0]));
assertNotNull(param0);
assertEquals(param0.getIn(), "path");
assertEquals(param0.getName(), "paramName1");
assertEquals(param0.getDescription(), "paramValue1");
assertNull(param0.getEnum());
assertNotNull(param0.getItems());
final BodyParameter param1 = (BodyParameter) ParameterProcessor.applyAnnotations(null, new BodyParameter(),
String.class, Collections.<Annotation>singletonList(params.value()[1]));
assertNotNull(param1);
assertEquals(param1.getIn(), "body");
assertEquals(param1.getName(), "body");
assertEquals(param1.getDescription(), "paramValue2");
assertEquals(param1.getAccess(), "test");
final ModelImpl model = (ModelImpl) param1.getSchema();
assertNotNull(model);
assertEquals(model.getDefaultValue(), "10");
}
@Test
public void resourceWithParamRangeTest() throws NoSuchMethodException {
final Method method = getClass().getDeclaredMethod("rangedParametrizedMethod", Integer.class, Double.class,
Integer.class, Integer.class);
final Type[] genericParameterTypes = method.getGenericParameterTypes();
final Annotation[][] paramAnnotations = method.getParameterAnnotations();
final PathParameter param0 = (PathParameter) ParameterProcessor.applyAnnotations(null, new PathParameter(),
genericParameterTypes[0], Arrays.asList(paramAnnotations[0]));
assertNotNull(param0);
assertEquals(param0.getDefaultValue(), "5");
assertEquals(param0.getMinimum(), new BigDecimal(0.0));
assertEquals(param0.getMaximum(), new BigDecimal(10.0));
assertEquals(param0.getCollectionFormat(), "multi");
final PathParameter param1 = (PathParameter) ParameterProcessor.applyAnnotations(null, new PathParameter(),
genericParameterTypes[1], Arrays.asList(paramAnnotations[1]));
assertNotNull(param1);
assertEquals(param1.getMinimum(), new BigDecimal(0.0));
assertNull(param1.getMaximum(), null);
assertTrue(param1.isExclusiveMinimum());
assertTrue(param1.isExclusiveMaximum());
final PathParameter param2 = (PathParameter) ParameterProcessor.applyAnnotations(null, new PathParameter(),
genericParameterTypes[2], Arrays.asList(paramAnnotations[2]));
assertNotNull(param2);
assertNull(param2.getMinimum());
assertEquals(param2.getMaximum(), new BigDecimal(100.0));
final PathParameter param3 = (PathParameter) ParameterProcessor.applyAnnotations(null, new PathParameter()
.items(new IntegerProperty()), genericParameterTypes[3], Arrays.asList(paramAnnotations[3]));
assertNotNull(param3);
final IntegerProperty items = (IntegerProperty) param3.getItems();
assertNotNull(items);
assertEquals(items.getMinimum(), new BigDecimal(0.0));
assertEquals(items.getMaximum(), new BigDecimal(5.0));
assertTrue(items.getExclusiveMinimum());
assertTrue(items.getExclusiveMaximum());
}
@Test
public void resourceWithArrayParamTest() throws NoSuchMethodException {
final Method method = getClass().getDeclaredMethod("arrayParametrizedMethod", List.class);
final Type[] genericParameterTypes = method.getGenericParameterTypes();
final Annotation[][] paramAnnotations = method.getParameterAnnotations();
final HeaderParameter param = (HeaderParameter) ParameterProcessor.applyAnnotations(null, new HeaderParameter(),
genericParameterTypes[0], Arrays.asList(paramAnnotations[0]));
assertNotNull(param);
assertEquals((int) param.getMinItems(), 5);
assertEquals((int) param.getMaxItems(), 10);
}
@Test
public void beanValidationSizeOnNumberTest() throws NoSuchMethodException {
final Method method = getClass().getDeclaredMethod("beanValidationSizeOnNumber",
int.class,
short.class,
long.class,
float.class,
double.class,
Integer.class,
Short.class,
Long.class,
Float.class,
Double.class,
BigInteger.class,
BigDecimal.class);
final Type[] genericParameterTypes = method.getGenericParameterTypes();
final Annotation[][] paramAnnotations = method.getParameterAnnotations();
for (int i = 0; i < 12; i++) {
final QueryParameter param = (QueryParameter) ParameterProcessor.applyAnnotations(null, new QueryParameter(),
genericParameterTypes[i], Arrays.asList(paramAnnotations[i]));
assertNotNull(param);
assertEquals(param.getMinimum(), new BigDecimal(5));
assertEquals(param.getMaximum(), new BigDecimal(10));
}
}
@Test
public void beanValidationSizeOnStringTest() throws NoSuchMethodException {
final Method method = getClass().getDeclaredMethod("beanValidationSizeOnString",
String.class);
final Type[] genericParameterTypes = method.getGenericParameterTypes();
final Annotation[][] paramAnnotations = method.getParameterAnnotations();
final QueryParameter param = (QueryParameter) ParameterProcessor.applyAnnotations(null, new QueryParameter(),
genericParameterTypes[0], Arrays.asList(paramAnnotations[0]));
assertNotNull(param);
assertEquals(param.getMinLength(), new Integer(5));
assertEquals(param.getMaxLength(), new Integer(10));
}
@Test
public void beanValidationMinTest() throws NoSuchMethodException {
final Method method = getClass().getDeclaredMethod("beanValidationMin",
int.class);
final Type[] genericParameterTypes = method.getGenericParameterTypes();
final Annotation[][] paramAnnotations = method.getParameterAnnotations();
final QueryParameter param = (QueryParameter) ParameterProcessor.applyAnnotations(null, new QueryParameter(),
genericParameterTypes[0], Arrays.asList(paramAnnotations[0]));
assertNotNull(param);
assertEquals(param.getMinimum(), new BigDecimal(5));
}
@Test
public void beanValidationMaxTest() throws NoSuchMethodException {
final Method method = getClass().getDeclaredMethod("beanValidationMax",
int.class);
final Type[] genericParameterTypes = method.getGenericParameterTypes();
final Annotation[][] paramAnnotations = method.getParameterAnnotations();
final QueryParameter param = (QueryParameter) ParameterProcessor.applyAnnotations(null, new QueryParameter(),
genericParameterTypes[0], Arrays.asList(paramAnnotations[0]));
assertNotNull(param);
assertEquals(param.getMaximum(), new BigDecimal(10));
}
@Test
public void beanValidationDecimalMinTest() throws NoSuchMethodException {
final Method method = getClass().getDeclaredMethod("beanValidationDecimalMin",
double.class, double.class);
final Type[] genericParameterTypes = method.getGenericParameterTypes();
final Annotation[][] paramAnnotations = method.getParameterAnnotations();
final QueryParameter inclusiveParam = (QueryParameter) ParameterProcessor.applyAnnotations(null, new QueryParameter(),
genericParameterTypes[0], Arrays.asList(paramAnnotations[0]));
assertNotNull(inclusiveParam);
assertEquals(inclusiveParam.getMinimum(), new BigDecimal(5.5));
assertNull(inclusiveParam.isExclusiveMinimum());
final QueryParameter exclusiveParam = (QueryParameter) ParameterProcessor.applyAnnotations(null, new QueryParameter(),
genericParameterTypes[1], Arrays.asList(paramAnnotations[1]));
assertNotNull(exclusiveParam);
assertEquals(exclusiveParam.getMinimum(), new BigDecimal(5.5));
assertTrue(exclusiveParam.isExclusiveMinimum());
}
@Test
public void beanValidationDecimalMaxTest() throws NoSuchMethodException {
final Method method = getClass().getDeclaredMethod("beanValidationDecimalMax",
double.class, double.class);
final Type[] genericParameterTypes = method.getGenericParameterTypes();
final Annotation[][] paramAnnotations = method.getParameterAnnotations();
final QueryParameter inclusiveParam = (QueryParameter) ParameterProcessor.applyAnnotations(null, new QueryParameter(),
genericParameterTypes[0], Arrays.asList(paramAnnotations[0]));
assertNotNull(inclusiveParam);
assertEquals(inclusiveParam.getMaximum(), new BigDecimal(10.5));
assertNull(inclusiveParam.isExclusiveMaximum());
final QueryParameter exclusiveParam = (QueryParameter) ParameterProcessor.applyAnnotations(null, new QueryParameter(),
genericParameterTypes[1], Arrays.asList(paramAnnotations[1]));
assertNotNull(exclusiveParam);
assertEquals(exclusiveParam.getMaximum(), new BigDecimal(10.5));
assertTrue(exclusiveParam.isExclusiveMaximum());
}
@Test
public void beanValidationPatternTest() throws NoSuchMethodException {
final Method method = getClass().getDeclaredMethod("beanValidationPattern",
String.class);
final Type[] genericParameterTypes = method.getGenericParameterTypes();
final Annotation[][] paramAnnotations = method.getParameterAnnotations();
final QueryParameter param = (QueryParameter) ParameterProcessor.applyAnnotations(null, new QueryParameter(),
genericParameterTypes[0], Arrays.asList(paramAnnotations[0]));
assertNotNull(param);
assertEquals(param.getPattern(), TEST_PATTERN_REGXP);
}
@Test
public void beanValidationArrayParametrizedMethodTest() throws NoSuchMethodException {
final Method method = getClass().getDeclaredMethod("beanValidationArrayParametrizedMethod",
List.class, List.class, List.class, String.class);
final Type[] genericParameterTypes = method.getGenericParameterTypes();
final Annotation[][] paramAnnotations = method.getParameterAnnotations();
//First param - items specified
HeaderParameter headerParam1 = new HeaderParameter().type(ArrayProperty.TYPE).items(new LongProperty());
HeaderParameter param1 = (HeaderParameter) ParameterProcessor.applyAnnotations(null, headerParam1,
genericParameterTypes[0], Arrays.asList(paramAnnotations[0]));
assertNotNull(param1);
assertEquals((int) param1.getMinItems(), 5);
assertEquals((int) param1.getMaxItems(), 10);
Property items1 = param1.getItems();
assertTrue(items1 instanceof LongProperty);
LongProperty longItems = (LongProperty) items1;
assertEquals(longItems.getMinimum(), new BigDecimal(5));
assertNull(longItems.getExclusiveMinimum());
assertEquals(longItems.getMaximum(), new BigDecimal(10));
assertNull(longItems.getExclusiveMaximum());
//Second param - items specified
HeaderParameter headerParam2 = new HeaderParameter().type(ArrayProperty.TYPE).items(new DoubleProperty());
HeaderParameter param2 = (HeaderParameter) ParameterProcessor.applyAnnotations(null, headerParam2,
genericParameterTypes[1], Arrays.asList(paramAnnotations[1]));
assertNotNull(param2);
assertEquals((int) param2.getMinItems(), 5);
assertEquals((int) param2.getMaxItems(), 10);
Property items2 = param2.getItems();
assertTrue(items2 instanceof DoubleProperty);
DoubleProperty doubleItems = (DoubleProperty) items2;
assertEquals(doubleItems.getMinimum(), new BigDecimal(5.5));
assertTrue(doubleItems.getExclusiveMinimum());
assertEquals(doubleItems.getMaximum(), new BigDecimal(10.5));
assertTrue(doubleItems.getExclusiveMaximum());
//Third param - items specified
HeaderParameter headerParam3 = new HeaderParameter().type(ArrayProperty.TYPE).items(new StringProperty());
HeaderParameter param3 = (HeaderParameter) ParameterProcessor.applyAnnotations(null, headerParam3,
genericParameterTypes[2], Arrays.asList(paramAnnotations[2]));
assertNotNull(param3);
assertEquals((int) param3.getMinItems(), 5);
assertEquals((int) param3.getMaxItems(), 10);
Property items3 = param3.getItems();
assertTrue(items3 instanceof StringProperty);
StringProperty stringItems = (StringProperty) items3;
assertEquals(stringItems.getPattern(), TEST_PATTERN_REGXP);
//Fourth param - items specified
HeaderParameter headerParam4 = new HeaderParameter().type(StringProperty.TYPE);
HeaderParameter param4 = (HeaderParameter) ParameterProcessor.applyAnnotations(null, headerParam4,
genericParameterTypes[3], Arrays.asList(paramAnnotations[3]));
assertNotNull(param4);
assertEquals(param4.getType(), ArrayProperty.TYPE);
assertEquals((int) param4.getMinItems(), 5);
assertEquals((int) param4.getMaxItems(), 10);
Property items4 = param4.getItems();
assertTrue(items4 instanceof StringProperty);
}
@ApiImplicitParams(value = {
@ApiImplicitParam(name = "id", dataType = "long", paramType = "path", required = true)
})
private void implicitParametrizedMethodLongType() {
}
@Test(description = "test for issue #1873 fixing.")
public void implicitParameterLongTypeProcessorTest() throws NoSuchMethodException {
final ApiImplicitParams params = getClass().getDeclaredMethod("implicitParametrizedMethodLongType")
.getAnnotation(ApiImplicitParams.class);
final PathParameter param0 = (PathParameter) ParameterProcessor.applyAnnotations(null, new PathParameter(),
String.class, Collections.<Annotation>singletonList(params.value()[0]));
assertEquals(param0.getName(), "id");
assertEquals(param0.getIn(), "path");
assertEquals(param0.getRequired(), true);
assertEquals(param0.getType(), "integer");
assertEquals(param0.getFormat(), "int64");
}
}