package org.jboss.resteasy.test.validation;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.OperateOnDeployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.logging.Logger;
import org.jboss.resteasy.api.validation.ResteasyConstraintViolation;
import org.jboss.resteasy.api.validation.Validation;
import org.jboss.resteasy.api.validation.ViolationReport;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.test.validation.resource.ValidationComplexA;
import org.jboss.resteasy.test.validation.resource.ValidationComplexArrayOfStrings;
import org.jboss.resteasy.test.validation.resource.ValidationComplexB;
import org.jboss.resteasy.test.validation.resource.ValidationComplexCrossParameterConstraint;
import org.jboss.resteasy.test.validation.resource.ValidationComplexCrossParameterValidator;
import org.jboss.resteasy.test.validation.resource.ValidationComplexFoo;
import org.jboss.resteasy.test.validation.resource.ValidationComplexFooConstraint;
import org.jboss.resteasy.test.validation.resource.ValidationComplexFooReaderWriter;
import org.jboss.resteasy.test.validation.resource.ValidationComplexFooValidator;
import org.jboss.resteasy.test.validation.resource.ValidationComplexInterface;
import org.jboss.resteasy.test.validation.resource.ValidationComplexInterfaceSub;
import org.jboss.resteasy.test.validation.resource.ValidationComplexInterfaceSuper;
import org.jboss.resteasy.test.validation.resource.ValidationComplexListOfArrayOfStrings;
import org.jboss.resteasy.test.validation.resource.ValidationComplexListOfStrings;
import org.jboss.resteasy.test.validation.resource.ValidationComplexMapOfListOfArrayOfStrings;
import org.jboss.resteasy.test.validation.resource.ValidationComplexMapOfStrings;
import org.jboss.resteasy.test.validation.resource.ValidationComplexOneString;
import org.jboss.resteasy.test.validation.resource.ValidationComplexOtherGroup;
import org.jboss.resteasy.test.validation.resource.ValidationComplexOtherGroupConstraint;
import org.jboss.resteasy.test.validation.resource.ValidationComplexClassConstraint;
import org.jboss.resteasy.test.validation.resource.ValidationComplexClassConstraint2;
import org.jboss.resteasy.test.validation.resource.ValidationComplexClassInheritanceSubConstraint;
import org.jboss.resteasy.test.validation.resource.ValidationComplexClassInheritanceSuperConstraint;
import org.jboss.resteasy.test.validation.resource.ValidationComplexClassValidator;
import org.jboss.resteasy.test.validation.resource.ValidationComplexClassValidator2;
import org.jboss.resteasy.test.validation.resource.ValidationComplexClassValidatorSubInheritance;
import org.jboss.resteasy.test.validation.resource.ValidationComplexClassValidatorSuperInheritance;
import org.jboss.resteasy.test.validation.resource.ValidationComplexProxyInterface;
import org.jboss.resteasy.test.validation.resource.ValidationComplexProxyResource;
import org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithAllFivePotentialViolations;
import org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithArray;
import org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithClassConstraint;
import org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithFieldAndProperty;
import org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithGraph;
import org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithInvalidField;
import org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithList;
import org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithMap;
import org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithMapOfListOfArrayOfStrings;
import org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithOtherGroups;
import org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithParameters;
import org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithProperty;
import org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithReturnValues;
import org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithSubLocators;
import org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithValidField;
import org.jboss.resteasy.test.validation.resource.ValidationComplexSubResourceWithCrossParameterConstraint;
import org.jboss.resteasy.util.HttpResponseCodes;
import org.jboss.resteasy.utils.PermissionUtil;
import org.jboss.resteasy.utils.PortProviderUtil;
import org.jboss.resteasy.utils.TestUtil;
import org.jboss.resteasy.utils.TimeoutUtil;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.lang.reflect.ReflectPermission;
import java.util.*;
/**
* @tpSubChapter Response
* @tpChapter Integration tests
* @tpTestCaseDetails Complex basic test for Resteasy Validator Provider
* @tpSince RESTEasy 3.0.16
*/
@RunWith(Arquillian.class)
public class ValidationComplexTest {
static final String RESPONSE_ERROR_MSG = "Response has wrong content";
static final String WRONG_ERROR_MSG = "Expected validation error is not in response";
private static Logger logger = Logger.getLogger(ValidationComplexTest.class);
private static final String BASIC_DEPLOYMENT = "basicDeployment";
private static final String CUSTOM_OBJECT_DEPLOYMENT = "customObjectDeployment";
private static final String ASYNC_CUSTOM_OBJECT_DEPLOYMENT = "asyncCustomObjectDeployment";
ResteasyClient client;
@Before
public void init() {
client = new ResteasyClientBuilder().build().register(ValidationComplexFooReaderWriter.class);
}
@After
public void after() throws Exception {
client.close();
}
private static String generateURL(String type, String path, String testName) {
return PortProviderUtil.generateURL(path, String.format("%s%s", type, testName));
}
public static WebArchive addBasicClasses(WebArchive war) {
war.addClasses(ValidationComplexA.class, ValidationComplexArrayOfStrings.class, ValidationComplexB.class,
ValidationComplexMapOfStrings.class,
ValidationComplexListOfStrings.class, ValidationComplexMapOfListOfArrayOfStrings.class, ValidationComplexOneString.class,
ValidationComplexListOfArrayOfStrings.class, ValidationComplexProxyInterface.class,
ValidationComplexOtherGroupConstraint.class, ValidationComplexOtherGroup.class,
ValidationComplexClassValidator.class, ValidationComplexClassInheritanceSubConstraint.class,
ValidationComplexClassValidatorSubInheritance.class,
ValidationComplexInterfaceSuper.class, ValidationComplexInterface.class, ValidationComplexCrossParameterConstraint.class,
ValidationComplexCrossParameterValidator.class, ValidationComplexFooReaderWriter.class,
ValidationComplexFoo.class, ValidationComplexClassConstraint.class,
ValidationComplexInterfaceSub.class, ValidationComplexClassInheritanceSuperConstraint.class,
ValidationComplexClassValidatorSuperInheritance.class,
ValidationComplexClassConstraint2.class, ValidationComplexClassValidator2.class);
// Arquillian in the deployment
war.addAsManifestResource(PermissionUtil.createPermissionsXmlAsset(new ReflectPermission("suppressAccessChecks"),
new RuntimePermission("accessDeclaredMembers"),
new PropertyPermission("arquillian.*", "read")), "permissions.xml");
war.addClasses(TestUtil.class, PortProviderUtil.class);
return war;
}
public static WebArchive addCustomObjectClasses(WebArchive war) {
war.addClasses(ValidationComplexFoo.class, ValidationComplexResourceWithAllFivePotentialViolations.class,
ValidationComplexResourceWithValidField.class, ValidationComplexResourceWithInvalidField.class,
ValidationComplexResourceWithProperty.class, ValidationComplexFooConstraint.class,
ValidationComplexFooValidator.class);
return war;
}
public static Archive<?> basicDeployment(Class<?> clazz) {
WebArchive war = TestUtil.prepareArchive(BASIC_DEPLOYMENT + clazz.getSimpleName());
war = addBasicClasses(war);
return TestUtil.finishContainerPrepare(war, null, clazz);
}
public static Archive<?> customObjectDeployment(Class<?> clazz) {
WebArchive war = TestUtil.prepareArchive(CUSTOM_OBJECT_DEPLOYMENT + clazz.getSimpleName());
war = addBasicClasses(war);
war = addCustomObjectClasses(war);
return TestUtil.finishContainerPrepare(war, null, clazz, ValidationComplexFooReaderWriter.class);
}
public static Archive<?> asyncCustomObjectDeployment(Class<?> clazz) {
WebArchive war = TestUtil.prepareArchive(ASYNC_CUSTOM_OBJECT_DEPLOYMENT + clazz.getSimpleName());
war = addBasicClasses(war);
war = addCustomObjectClasses(war);
Map<String, String> contextParams = new HashMap<>();
contextParams.put("resteasy.async.job.service.enabled", "true");
return TestUtil.finishContainerPrepare(war, contextParams, clazz, ValidationComplexFooReaderWriter.class);
}
@Deployment(name = "basicDeploymentTestResourceWithValidField")
public static Archive<?> basicDeploymentTestResourceWithValidField() {
return basicDeployment(ValidationComplexResourceWithValidField.class);
}
@Deployment(name = "basicDeploymentTestResourceWithInvalidField")
public static Archive<?> basicDeploymentTestResourceWithInvalidField() {
return basicDeployment(ValidationComplexResourceWithInvalidField.class);
}
@Deployment(name = "basicDeploymentTestResourceWithProperty")
public static Archive<?> basicDeploymentTestResourceWithProperty() {
return basicDeployment(ValidationComplexResourceWithProperty.class);
}
@Deployment(name = "basicDeploymentTestResourceWithFieldAndProperty")
public static Archive<?> basicDeploymentTestResourceWithFieldAndProperty() {
return basicDeployment(ValidationComplexResourceWithFieldAndProperty.class);
}
@Deployment(name = "basicDeploymentTestResourceWithClassConstraint")
public static Archive<?> basicDeploymentTestResourceWithClassConstraint() {
return basicDeployment(ValidationComplexResourceWithClassConstraint.class);
}
@Deployment(name = "basicDeploymentTestResourceWithGraph")
public static Archive<?> basicDeploymentTestResourceWithGraph() {
return basicDeployment(ValidationComplexResourceWithGraph.class);
}
@Deployment(name = "basicDeploymentTestResourceWithArray")
public static Archive<?> basicDeploymentTestResourceWithArray() {
return basicDeployment(ValidationComplexResourceWithArray.class);
}
@Deployment(name = "basicDeploymentTestResourceWithMap")
public static Archive<?> basicDeploymentTestResourceWithMap() {
return basicDeployment(ValidationComplexResourceWithMap.class);
}
@Deployment(name = "basicDeploymentTestResourceWithList")
public static Archive<?> basicDeploymentTestResourceWithList() {
return basicDeployment(ValidationComplexResourceWithList.class);
}
@Deployment(name = "basicDeploymentTestResourceWithMapOfListOfArrayOfStrings")
public static Archive<?> basicDeploymentTestResourceWithMapOfListOfArrayOfStrings() {
return basicDeployment(ValidationComplexResourceWithMapOfListOfArrayOfStrings.class);
}
@Deployment(name = "customObjectDeploymentTestResourceWithParameters")
public static Archive<?> customObjectDeploymentTestResourceWithParameters() {
return customObjectDeployment(ValidationComplexResourceWithParameters.class);
}
@Deployment(name = "customObjectDeploymentTestResourceWithReturnValues")
public static Archive<?> customObjectDeploymentTestResourceWithReturnValues() {
return customObjectDeployment(ValidationComplexResourceWithReturnValues.class);
}
@Deployment(name = "customObjectDeploymentTestResourceWithAllFivePotentialViolations")
public static Archive<?> customObjectDeploymentTestResourceWithAllFivePotentialViolations() {
return customObjectDeployment(ValidationComplexResourceWithAllFivePotentialViolations.class);
}
@Deployment(name = "basicDeploymentInterfaceTestSub")
public static Archive<?> basicDeploymentInterfaceTestSub() {
return basicDeployment(ValidationComplexInterfaceSub.class);
}
@Deployment(name = "customObjectDeploymentTestResourceWithSubLocators")
public static Archive<?> customObjectDeploymentTestResourceWithSubLocators() {
return customObjectDeployment(ValidationComplexResourceWithSubLocators.class);
}
@Deployment(name = "asyncCustomObjectDeploymentTestResourceWithAllFivePotentialViolations")
public static Archive<?> asyncCustomObjectDeploymentTestResourceWithAllFivePotentialViolations() {
return asyncCustomObjectDeployment(ValidationComplexResourceWithAllFivePotentialViolations.class);
}
@Deployment(name = "basicDeploymentTestSubResourceWithCrossParameterConstraint")
public static Archive<?> basicDeploymentTestSubResourceWithCrossParameterConstraint() {
return basicDeployment(ValidationComplexSubResourceWithCrossParameterConstraint.class);
}
@Deployment(name = "basicDeploymentTestProxyResource")
public static Archive<?> basicDeploymentTestProxyResource() {
return basicDeployment(ValidationComplexProxyResource.class);
}
@Deployment(name = "basicDeploymentTestResourceWithOtherGroups")
public static Archive<?> basicDeploymentTestResourceWithOtherGroups() {
return basicDeployment(ValidationComplexResourceWithOtherGroups.class);
}
/**
* @tpTestDetails Valid field test
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testFieldValid() throws Exception {
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/", ValidationComplexResourceWithValidField.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
}
/**
* @tpTestDetails Invalid field test
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testFieldInvalid() throws Exception {
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/", ValidationComplexResourceWithInvalidField.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
Object entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 1, 0, 0, 0, 0);
ResteasyConstraintViolation cv = r.getFieldViolations().iterator().next();
logger.info("cv: " + cv);
Assert.assertEquals(WRONG_ERROR_MSG, "size must be between 2 and 4", cv.getMessage());
Assert.assertEquals(WRONG_ERROR_MSG, "abcde", cv.getValue());
response.close();
}
/**
* @tpTestDetails Valid property test
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testPropertyValid() throws Exception {
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/abc/unused", ValidationComplexResourceWithProperty.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
}
/**
* @tpTestDetails Invalid property test
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testPropertyInvalid() throws Exception {
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/abcdef/unused", ValidationComplexResourceWithProperty.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
String entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(entity);
TestUtil.countViolations(r, 0, 1, 0, 0, 0);
ResteasyConstraintViolation cv = r.getPropertyViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "size must be between 2 and 4", cv.getMessage());
Assert.assertEquals(WRONG_ERROR_MSG, "abcdef", cv.getValue());
response.close();
}
/**
* @tpTestDetails Field and property validation test
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testFieldAndProperty() throws Exception {
// Valid
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/abc/wxyz", ValidationComplexResourceWithFieldAndProperty.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
// Invalid
response = client.target(generateURL(BASIC_DEPLOYMENT, "/a/uvwxyz", ValidationComplexResourceWithFieldAndProperty.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
String entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(entity);
TestUtil.countViolations(r, 1, 1, 0, 0, 0);
ResteasyConstraintViolation cv = r.getFieldViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "size must be between 2 and 4", cv.getMessage());
Assert.assertEquals(WRONG_ERROR_MSG, "a", cv.getValue());
cv = r.getPropertyViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "size must be between 3 and 5", cv.getMessage());
Assert.assertEquals(WRONG_ERROR_MSG, "uvwxyz", cv.getValue());
response.close();
}
/**
* @tpTestDetails Check class constraints
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testClassConstraint() throws Exception {
// Valid
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/abc/xyz", ValidationComplexResourceWithClassConstraint.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
// Invalid
response = client.target(generateURL(BASIC_DEPLOYMENT, "/a/b", ValidationComplexResourceWithClassConstraint.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
String entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(entity);
TestUtil.countViolations(r, 0, 0, 1, 0, 0);
ResteasyConstraintViolation cv = r.getClassViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "Concatenation of s and t must have length > 5", cv.getMessage());
Assert.assertEquals(WRONG_ERROR_MSG, "ValidationComplexResourceWithClassConstraint(\"a\", \"b\")", cv.getValue());
logger.info(cv.getValue());
response.close();
}
/**
* @tpTestDetails Graph test
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testGraph() throws Exception {
// Valid
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/abcd/vwxyz", ValidationComplexResourceWithGraph.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
// Invalid
response = client.target(generateURL(BASIC_DEPLOYMENT, "/abc/xyz", ValidationComplexResourceWithGraph.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
Object entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 2, 0, 0, 0, 0);
Iterator<ResteasyConstraintViolation> it = r.getFieldViolations().iterator();
ResteasyConstraintViolation cv1 = it.next();
ResteasyConstraintViolation cv2 = it.next();
if (cv1.getValue().equals("xyz")) {
ResteasyConstraintViolation tmp = cv1;
cv1 = cv2;
cv2 = tmp;
}
Assert.assertTrue(WRONG_ERROR_MSG, cv1.getMessage().startsWith("size must be between 4 and"));
Assert.assertEquals(WRONG_ERROR_MSG, "abc", cv1.getValue());
Assert.assertTrue(WRONG_ERROR_MSG, cv2.getMessage().startsWith("size must be between 5 and"));
Assert.assertEquals(WRONG_ERROR_MSG, "xyz", cv2.getValue());
response.close();
}
/**
* @tpTestDetails Validation of array
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testArray() throws Exception {
// Valid
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/abcde", ValidationComplexResourceWithArray.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
// Invalid
response = client.target(generateURL(BASIC_DEPLOYMENT, "/abc", ValidationComplexResourceWithArray.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
Object entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 1, 0, 0, 0, 0);
ResteasyConstraintViolation cv = r.getFieldViolations().iterator().next();
Assert.assertTrue(WRONG_ERROR_MSG, cv.getMessage().startsWith("size must be between 5 and"));
Assert.assertEquals(WRONG_ERROR_MSG, "abc", cv.getValue());
response.close();
}
/**
* @tpTestDetails Validation of list
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testList() throws Exception {
// Valid
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/abcde", ValidationComplexResourceWithList.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
// Invalid
response = client.target(generateURL(BASIC_DEPLOYMENT, "/abc", ValidationComplexResourceWithList.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
Object entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 1, 0, 0, 0, 0);
ResteasyConstraintViolation cv = r.getFieldViolations().iterator().next();
Assert.assertTrue(WRONG_ERROR_MSG, cv.getMessage().startsWith("size must be between 5 and"));
Assert.assertEquals(WRONG_ERROR_MSG, "abc", cv.getValue());
response.close();
}
/**
* @tpTestDetails Validation of map
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testMap() throws Exception {
// Valid
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/abcde", ValidationComplexResourceWithMap.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
// Invalid
response = client.target(generateURL(BASIC_DEPLOYMENT, "/abc", ValidationComplexResourceWithMap.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
Object entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 1, 0, 0, 0, 0);
ResteasyConstraintViolation cv = r.getFieldViolations().iterator().next();
Assert.assertTrue(WRONG_ERROR_MSG, cv.getMessage().startsWith("size must be between 5 and"));
Assert.assertEquals(WRONG_ERROR_MSG, "abc", cv.getValue());
response.close();
}
/**
* @tpTestDetails Validation of map of list of array of string
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testMapOfListOfArrayOfStrings() throws Exception {
// Valid
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/abcde", ValidationComplexResourceWithMapOfListOfArrayOfStrings.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
// Invalid
response = client.target(generateURL(BASIC_DEPLOYMENT, "/abc", ValidationComplexResourceWithMapOfListOfArrayOfStrings.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
Object entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(String.class.cast(entity));
logger.info("exception: " + r);
TestUtil.countViolations(r, 1, 0, 0, 0, 0);
ResteasyConstraintViolation cv = r.getFieldViolations().iterator().next();
Assert.assertTrue(WRONG_ERROR_MSG, cv.getMessage().startsWith("size must be between 5 and"));
Assert.assertEquals(WRONG_ERROR_MSG, "abc", cv.getValue());
response.close();
}
/**
* @tpTestDetails Test parameters validation
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testParameters() throws Exception {
// Valid native constraint
Response response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/native", ValidationComplexResourceWithParameters.class.getSimpleName()))
.request().post(Entity.entity(new ValidationComplexFoo("a"), "application/foo"));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
// Valid imposed constraint
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/imposed", ValidationComplexResourceWithParameters.class.getSimpleName()))
.request().post(Entity.entity(new ValidationComplexFoo("abcde"), "application/foo"));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
// Valid native and imposed constraints.
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/nativeAndImposed", ValidationComplexResourceWithParameters.class.getSimpleName()))
.request().post(Entity.entity(new ValidationComplexFoo("abc"), "application/foo"));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
// Invalid native constraint
// Valid native and imposed constraints.
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/native", ValidationComplexResourceWithParameters.class.getSimpleName()))
.request().post(Entity.entity(new ValidationComplexFoo("abcdef"), "application/foo"));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
String entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(entity);
TestUtil.countViolations(r, 0, 0, 0, 1, 0);
ResteasyConstraintViolation cv = r.getParameterViolations().iterator().next();
Assert.assertTrue(WRONG_ERROR_MSG, cv.getMessage().equals("s must have length: 1 <= length <= 3"));
Assert.assertEquals(RESPONSE_ERROR_MSG, "ValidationComplexFoo[abcdef]", cv.getValue());
response.close();
// Invalid imposed constraint
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/imposed", ValidationComplexResourceWithParameters.class.getSimpleName()))
.request().post(Entity.entity(new ValidationComplexFoo("abcdef"), "application/foo"));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
entity = response.readEntity(String.class);
r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 0, 0, 0, 1, 0);
cv = r.getParameterViolations().iterator().next();
Assert.assertTrue(WRONG_ERROR_MSG, cv.getMessage().equals("s must have length: 3 <= length <= 5"));
Assert.assertEquals(RESPONSE_ERROR_MSG, "ValidationComplexFoo[abcdef]", cv.getValue());
response.close();
// Invalid native and imposed constraints
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/nativeAndImposed", ValidationComplexResourceWithParameters.class.getSimpleName()))
.request().post(Entity.entity(new ValidationComplexFoo("abcdef"), "application/foo"));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
entity = response.readEntity(String.class);
r = new ViolationReport(entity);
TestUtil.countViolations(r, 0, 0, 0, 2, 0);
Iterator<ResteasyConstraintViolation> it = r.getParameterViolations().iterator();
ResteasyConstraintViolation cv1 = it.next();
ResteasyConstraintViolation cv2 = it.next();
if (cv1.toString().indexOf('1') < 0) {
ResteasyConstraintViolation temp = cv1;
cv1 = cv2;
cv2 = temp;
}
Assert.assertTrue(WRONG_ERROR_MSG, cv1.getMessage().equals("s must have length: 1 <= length <= 3"));
Assert.assertEquals(RESPONSE_ERROR_MSG, "ValidationComplexFoo[abcdef]", cv1.getValue());
Assert.assertTrue(WRONG_ERROR_MSG, cv2.getMessage().equals("s must have length: 3 <= length <= 5"));
Assert.assertEquals(RESPONSE_ERROR_MSG, "ValidationComplexFoo[abcdef]", cv2.getValue());
response.close();
// Valid other parameters
String url = generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/other/ppp", ValidationComplexResourceWithParameters.class.getSimpleName()); // path param
url += ";m=mmm"; // matrix param
url += "?q=qqq"; // query param
Form form = new Form().param("f", "fff");
response = client.target(url).request().header("h", "hhh").cookie(new Cookie("c", "ccc")).post(Entity.form(form));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
// Invalid other parameters
url = generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/other/pppp", ValidationComplexResourceWithParameters.class.getSimpleName()); // path param
url += ";m=mmmm"; // matrix param
url += "?q=qqqq"; // query param
form = new Form().param("f", "ffff");
response = client.target(url).request().header("h", "hhhh").cookie(new Cookie("c", "cccc")).post(Entity.form(form));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
entity = response.readEntity(String.class);
r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 0, 0, 0, 6, 0);
List<String> list = getMessages(r);
Assert.assertTrue(WRONG_ERROR_MSG, list.contains("size must be between 2 and 3; pppp"));
Assert.assertTrue(WRONG_ERROR_MSG, list.contains("size must be between 2 and 3; mmmm"));
Assert.assertTrue(WRONG_ERROR_MSG, list.contains("size must be between 2 and 3; qqqq"));
Assert.assertTrue(WRONG_ERROR_MSG, list.contains("size must be between 2 and 3; ffff"));
Assert.assertTrue(WRONG_ERROR_MSG, list.contains("size must be between 2 and 3; hhhh"));
Assert.assertTrue(WRONG_ERROR_MSG, list.contains("size must be between 2 and 3; cccc"));
response.close();
}
/**
* @tpTestDetails Test return value validation
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testReturnValues() throws Exception {
// Valid native constraint
ValidationComplexFoo foo = new ValidationComplexFoo("a");
Response response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/native", ValidationComplexResourceWithReturnValues.class.getSimpleName()))
.request().post(Entity.entity(foo, "application/foo"));
Assert.assertEquals(HttpResponseCodes.SC_OK, response.getStatus());
Assert.assertEquals(RESPONSE_ERROR_MSG, foo, response.readEntity(ValidationComplexFoo.class));
response.close();
// Valid imposed constraint
foo = new ValidationComplexFoo("abcde");
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/imposed", ValidationComplexResourceWithReturnValues.class.getSimpleName()))
.request().post(Entity.entity(foo, "application/foo"));
Assert.assertEquals(HttpResponseCodes.SC_OK, response.getStatus());
Assert.assertEquals(RESPONSE_ERROR_MSG, foo, response.readEntity(ValidationComplexFoo.class));
response.close();
// Valid native and imposed constraints.
foo = new ValidationComplexFoo("abc");
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/nativeAndImposed", ValidationComplexResourceWithReturnValues.class.getSimpleName()))
.request().post(Entity.entity(foo, "application/foo"));
Assert.assertEquals(HttpResponseCodes.SC_OK, response.getStatus());
Assert.assertEquals(RESPONSE_ERROR_MSG, foo, response.readEntity(ValidationComplexFoo.class));
response.close();
// Invalid native constraint
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/native", ValidationComplexResourceWithReturnValues.class.getSimpleName()))
.request().post(Entity.entity(new ValidationComplexFoo("abcdef"), "application/foo"));
Assert.assertEquals(HttpResponseCodes.SC_INTERNAL_SERVER_ERROR, response.getStatus());
Object entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 0, 0, 0, 0, 1);
ResteasyConstraintViolation cv = r.getReturnValueViolations().iterator().next();
Assert.assertTrue(WRONG_ERROR_MSG, cv.getMessage().equals("s must have length: 1 <= length <= 3"));
Assert.assertEquals(RESPONSE_ERROR_MSG, "ValidationComplexFoo[abcdef]", cv.getValue());
response.close();
// Invalid imposed constraint
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/imposed", ValidationComplexResourceWithReturnValues.class.getSimpleName()))
.request().post(Entity.entity(new ValidationComplexFoo("abcdef"), "application/foo"));
Assert.assertEquals(HttpResponseCodes.SC_INTERNAL_SERVER_ERROR, response.getStatus());
entity = response.readEntity(String.class);
r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 0, 0, 0, 0, 1);
cv = r.getReturnValueViolations().iterator().next();
Assert.assertTrue(WRONG_ERROR_MSG, cv.getMessage().equals("s must have length: 3 <= length <= 5"));
Assert.assertEquals(RESPONSE_ERROR_MSG, "ValidationComplexFoo[abcdef]", cv.getValue());
response.close();
// Invalid native and imposed constraints
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/nativeAndImposed", ValidationComplexResourceWithReturnValues.class.getSimpleName()))
.request().post(Entity.entity(new ValidationComplexFoo("abcdef"), "application/foo"));
Assert.assertEquals(HttpResponseCodes.SC_INTERNAL_SERVER_ERROR, response.getStatus());
entity = response.readEntity(String.class);
r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 0, 0, 0, 0, 2);
Iterator<ResteasyConstraintViolation> it = r.getReturnValueViolations().iterator();
ResteasyConstraintViolation cv1 = it.next();
ResteasyConstraintViolation cv2 = it.next();
if (cv1.toString().indexOf('1') < 0) {
ResteasyConstraintViolation temp = cv1;
cv1 = cv2;
cv2 = temp;
}
Assert.assertTrue(WRONG_ERROR_MSG, cv1.getMessage().equals("s must have length: 1 <= length <= 3"));
Assert.assertEquals(RESPONSE_ERROR_MSG, "ValidationComplexFoo[abcdef]", cv1.getValue());
Assert.assertTrue(WRONG_ERROR_MSG, cv2.getMessage().equals("s must have length: 3 <= length <= 5"));
Assert.assertEquals(RESPONSE_ERROR_MSG, "ValidationComplexFoo[abcdef]", cv2.getValue());
response.close();
}
/**
* @tpTestDetails Check validations before checking return value
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testViolationsBeforeReturnValue() throws Exception {
// Valid
ValidationComplexFoo foo = new ValidationComplexFoo("pqrs");
Response response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/abc/wxyz/unused/unused", ValidationComplexResourceWithAllFivePotentialViolations.class.getSimpleName()))
.request().post(Entity.entity(foo, "application/foo"));
Assert.assertEquals(HttpResponseCodes.SC_OK, response.getStatus());
Assert.assertEquals(foo, response.readEntity(ValidationComplexFoo.class));
response.close();
// Invalid: Should have 1 each of field, property, class, and parameter violations,
// and no return value violations.
foo = new ValidationComplexFoo("p");
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/a/z/unused/unused", ValidationComplexResourceWithAllFivePotentialViolations.class.getSimpleName()))
.request().post(Entity.entity(foo, "application/foo"));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
Object entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 1, 1, 1, 1, 0);
ResteasyConstraintViolation cv = r.getFieldViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "size must be between 2 and 4", cv.getMessage());
Assert.assertEquals(RESPONSE_ERROR_MSG, "a", cv.getValue());
cv = r.getPropertyViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "size must be between 3 and 5", cv.getMessage());
Assert.assertEquals(RESPONSE_ERROR_MSG, "z", cv.getValue());
cv = r.getClassViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "Concatenation of s and t must have length > 5", cv.getMessage());
Assert.assertTrue(WRONG_ERROR_MSG, cv.getValue().startsWith("org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithAllFivePotentialViolations@"));
cv = r.getParameterViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "s must have length: 3 <= length <= 5", cv.getMessage());
Assert.assertEquals(RESPONSE_ERROR_MSG, "ValidationComplexFoo[p]", cv.getValue());
response.close();
}
/**
* @tpTestDetails Validation in inheritence classes
* @tpSince RESTEasy 3.0.16
*/
@Test
@OperateOnDeployment("basicDeploymentInterfaceTestSub")
public void testInheritence() throws Exception {
{
// Valid - inherited annotations
ValidationComplexInterfaceSuper.t = "aaa";
ValidationComplexInterfaceSub.u = "bbb";
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/inherit", ValidationComplexInterfaceSub.class.getSimpleName()))
.request().post(Entity.entity("ccc", MediaType.TEXT_PLAIN_TYPE));
Assert.assertEquals(HttpResponseCodes.SC_OK, response.getStatus());
Assert.assertEquals(RESPONSE_ERROR_MSG, "ccc", response.readEntity(String.class));
response.close();
}
{
// Valid - overridden annotations
ValidationComplexInterfaceSuper.t = "aaa";
ValidationComplexInterfaceSub.u = "bbb";
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/override", ValidationComplexInterfaceSub.class.getSimpleName()))
.request().post(Entity.entity("ccc", MediaType.TEXT_PLAIN_TYPE));
Assert.assertEquals(HttpResponseCodes.SC_OK, response.getStatus());
Assert.assertEquals(RESPONSE_ERROR_MSG, "ccc", response.readEntity(String.class));
response.close();
}
{
// Invalid - inherited class, parameter annotations
ValidationComplexInterfaceSuper.t = "a";
ValidationComplexInterfaceSub.u = "d";
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/inherit", ValidationComplexInterfaceSub.class.getSimpleName()))
.request().post(Entity.entity("e", MediaType.TEXT_PLAIN_TYPE));
logger.info("status: " + response.getStatus());
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
Object entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 0, 0, 2, 1, 0);
response.close();
}
{
// Invalid - overridden class, parameter annotations
ValidationComplexInterfaceSuper.t = "a";
ValidationComplexInterfaceSub.u = "d";
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/override", ValidationComplexInterfaceSub.class.getSimpleName()))
.request().post(Entity.entity("e", MediaType.TEXT_PLAIN_TYPE));
logger.info("status: " + response.getStatus());
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
Object entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 0, 0, 2, 1, 0);
response.close();
}
{
// Invalid - inherited return value annotations
ValidationComplexInterfaceSuper.t = "aaa";
ValidationComplexInterfaceSub.u = "bbb";
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/inherit", ValidationComplexInterfaceSub.class.getSimpleName()))
.request().post(Entity.entity("eeee", MediaType.TEXT_PLAIN_TYPE));
logger.info("status: " + response.getStatus());
Assert.assertEquals(HttpResponseCodes.SC_INTERNAL_SERVER_ERROR, response.getStatus());
Object entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 0, 0, 0, 0, 1);
response.close();
}
{
// Invalid - overridden return value annotations
ValidationComplexInterfaceSuper.t = "aaa";
ValidationComplexInterfaceSub.u = "bbb";
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/override", ValidationComplexInterfaceSub.class.getSimpleName()))
.request().post(Entity.entity("eeee", MediaType.TEXT_PLAIN_TYPE));
logger.info("status: " + response.getStatus());
Assert.assertEquals(HttpResponseCodes.SC_INTERNAL_SERVER_ERROR, response.getStatus());
Object entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 0, 0, 0, 0, 2);
response.close();
}
}
/**
* @tpTestDetails Locators validation
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testLocators() throws Exception {
// Sub-resource locator returns resource with valid field.
Response response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/validField", ValidationComplexResourceWithSubLocators.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
// Sub-resource locator returns resource with invalid field.
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/invalidField", ValidationComplexResourceWithSubLocators.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
String entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(entity);
TestUtil.countViolations(r, 1, 0, 0, 0, 0);
ResteasyConstraintViolation cv = r.getFieldViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "size must be between 2 and 4", cv.getMessage());
Assert.assertEquals(RESPONSE_ERROR_MSG, "abcde", cv.getValue());
response.close();
// Sub-resource locator returns resource with valid property.
// Note: The resource ValidationComplexResourceWithProperty has a @PathParam annotation used by a setter,
// but it is not used when ValidationComplexResourceWithProperty is used a sub-resource. Hence "unused".
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/property/abc/unused", ValidationComplexResourceWithSubLocators.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
// Sub-resource locator returns resource with invalid property.
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/property/abcdef/unused", ValidationComplexResourceWithSubLocators.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
entity = response.readEntity(String.class);
r = new ViolationReport(entity);
TestUtil.countViolations(r, 0, 1, 0, 0, 0);
cv = r.getPropertyViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "size must be between 2 and 4", cv.getMessage());
Assert.assertEquals(RESPONSE_ERROR_MSG, "abcdef", cv.getValue());
response.close();
// Valid
ValidationComplexFoo foo = new ValidationComplexFoo("pqrs");
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/everything/abc/wxyz/unused/unused", ValidationComplexResourceWithSubLocators.class.getSimpleName()))
.request().post(Entity.entity(foo, "application/foo"));
Assert.assertEquals(HttpResponseCodes.SC_OK, response.getStatus());
Assert.assertEquals(RESPONSE_ERROR_MSG, foo, response.readEntity(ValidationComplexFoo.class));
response.close();
// Invalid: Should have 1 each of field, property, class, and parameter violations,and no return value violations.
// Note: expect warning because ValidationComplexResourceWithAllFivePotentialViolations is being used a sub-resource and it has an injectible field:
// WARN org.jboss.resteasy.core.ResourceLocator - Field s of subresource org.jboss.resteasy.test.validation.ValidationComplexTest$ValidationComplexResourceWithAllFivePotentialViolations will not be injected according to spec
foo = new ValidationComplexFoo("p");
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/everything/a/z/unused/unused", ValidationComplexResourceWithSubLocators.class.getSimpleName()))
.request().post(Entity.entity(foo, "application/foo"));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
entity = response.readEntity(String.class);
r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 1, 1, 1, 1, 0);
cv = r.getFieldViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "size must be between 2 and 4", cv.getMessage());
Assert.assertEquals(RESPONSE_ERROR_MSG, "a", cv.getValue());
cv = r.getPropertyViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "size must be between 3 and 5", cv.getMessage());
cv = r.getClassViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "Concatenation of s and t must have length > 5", cv.getMessage());
Assert.assertTrue(RESPONSE_ERROR_MSG, cv.getValue().startsWith("org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithAllFivePotentialViolations@"));
response.close();
// Sub-sub-resource locator returns resource with valid property.
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/locator/sublocator/abc", ValidationComplexResourceWithSubLocators.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
// Sub-resource locator returns resource with invalid property.
response = client.target(generateURL(CUSTOM_OBJECT_DEPLOYMENT, "/locator/sublocator/abcdef", ValidationComplexResourceWithSubLocators.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
entity = response.readEntity(String.class);
r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 1, 0, 0, 0, 0);
cv = r.getFieldViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "size must be between 2 and 3", cv.getMessage());
Assert.assertEquals(RESPONSE_ERROR_MSG, "abcdef", cv.getValue());
response.close();
}
/**
* @tpTestDetails Validation with asynchronous requests
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testAsynch() throws Exception {
// Submit asynchronous job with violations prior to execution of resource method.
ValidationComplexFoo foo = new ValidationComplexFoo("p");
Response response = client.target(generateURL(ASYNC_CUSTOM_OBJECT_DEPLOYMENT, "/a/z/unused/unused?asynch=true", ValidationComplexResourceWithAllFivePotentialViolations.class.getSimpleName()))
.request().post(Entity.entity(foo, "application/foo"));
Assert.assertEquals(HttpServletResponse.SC_ACCEPTED, response.getStatus());
String jobUrl = response.getHeaderString(HttpHeaders.LOCATION);
logger.info("JOB: " + jobUrl);
response.close();
// Get result: Should have 1 each of field, property, class, and parameter violations,
// and no return value violations.
response = client.target(jobUrl).request().get();
for (int i = 0; i < 60; i++) {
Thread.sleep(TimeoutUtil.adjust(1000));
response.close();
response = client.target(jobUrl).request().get();
if (HttpServletResponse.SC_ACCEPTED != response.getStatus()) {
break;
}
}
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
Object entity = response.readEntity(String.class);
ViolationReport r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 1, 1, 1, 1, 0);
ResteasyConstraintViolation cv = r.getFieldViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "size must be between 2 and 4", cv.getMessage());
Assert.assertEquals(RESPONSE_ERROR_MSG, "a", cv.getValue());
cv = r.getPropertyViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "size must be between 3 and 5", cv.getMessage());
Assert.assertEquals(RESPONSE_ERROR_MSG, "z", cv.getValue());
cv = r.getClassViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "Concatenation of s and t must have length > 5", cv.getMessage());
Assert.assertTrue(RESPONSE_ERROR_MSG, cv.getValue().startsWith("org.jboss.resteasy.test.validation.resource.ValidationComplexResourceWithAllFivePotentialViolations@"));
cv = r.getParameterViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "s must have length: 3 <= length <= 5", cv.getMessage());
Assert.assertEquals(RESPONSE_ERROR_MSG, "ValidationComplexFoo[p]", cv.getValue());
response.close();
// Delete job.
response = client.target(jobUrl).request().delete();
Assert.assertEquals(HttpServletResponse.SC_NO_CONTENT, response.getStatus());
response.close();
// Submit asynchronous job with violations in result of resource method.
foo = new ValidationComplexFoo("pqr");
response = client.target(generateURL(ASYNC_CUSTOM_OBJECT_DEPLOYMENT, "/abc/xyz/unused/unused?asynch=true", ValidationComplexResourceWithAllFivePotentialViolations.class.getSimpleName()))
.request().post(Entity.entity(foo, "application/foo"));
Assert.assertEquals(HttpServletResponse.SC_ACCEPTED, response.getStatus());
jobUrl = response.getHeaderString(HttpHeaders.LOCATION);
logger.info("JOB: " + jobUrl);
response.close();
// Get result: Should have no field, property, class, or parameter violations,
// and one return value violation.
response = client.target(jobUrl).request().get();
for (int i = 0; i < 60; i++) {
Thread.sleep(TimeoutUtil.adjust(1000));
response.close();
response = client.target(jobUrl).request().get();
if (HttpServletResponse.SC_ACCEPTED != response.getStatus()) {
break;
}
}
Assert.assertEquals(HttpResponseCodes.SC_INTERNAL_SERVER_ERROR, response.getStatus());
entity = response.readEntity(String.class);
r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 0, 0, 0, 0, 1);
cv = r.getReturnValueViolations().iterator().next();
Assert.assertEquals(WRONG_ERROR_MSG, "s must have length: 4 <= length <= 5", cv.getMessage());
Assert.assertEquals(RESPONSE_ERROR_MSG, "ValidationComplexFoo[pqr]", cv.getValue());
response.close();
// Delete job.
response = client.target(jobUrl).request().delete();
Assert.assertEquals(HttpServletResponse.SC_NO_CONTENT, response.getStatus());
response.close();
}
/**
* @tpTestDetails Validation by cross-parameter constraints
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testCrossParameterConstraint() throws Exception {
// Valid
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/2/3", ValidationComplexSubResourceWithCrossParameterConstraint.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_NO_CONTENT, response.getStatus());
response.close();
// Invalid
response = client.target(generateURL(BASIC_DEPLOYMENT, "/5/7", ValidationComplexSubResourceWithCrossParameterConstraint.class.getSimpleName()))
.request().post(Entity.text(new String()));
Assert.assertEquals(HttpResponseCodes.SC_BAD_REQUEST, response.getStatus());
String header = response.getHeaderString(Validation.VALIDATION_HEADER);
Assert.assertNotNull("Missing validation header", header);
Assert.assertTrue("Wrong validation header", Boolean.valueOf(header));
Object entity = response.readEntity(String.class);
logger.info("entity: " + entity);
ViolationReport r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 0, 0, 0, 1, 0);
ResteasyConstraintViolation violation = r.getParameterViolations().iterator().next();
logger.info("violation: " + violation);
Assert.assertEquals(WRONG_ERROR_MSG, "Parameters must total <= 7", violation.getMessage());
logger.info("violation value: " + violation.getValue());
Assert.assertEquals(RESPONSE_ERROR_MSG, "[5, 7]", violation.getValue());
response.close();
}
/**
* @tpTestDetails Validation with client proxies
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testProxy() throws Exception {
// Valid
ValidationComplexProxyInterface client = this.client.target(generateURL(BASIC_DEPLOYMENT, "/", ValidationComplexProxyResource.class.getSimpleName()))
.proxy(ValidationComplexProxyInterface.class);
client.s("abcd");
String result = client.g();
Assert.assertEquals("abcd", result);
// Invalid
client.s("abcde");
try {
client.g();
} catch (InternalServerErrorException e) {
Response response = e.getResponse();
logger.info("status: " + response.getStatus());
String header = response.getHeaderString(Validation.VALIDATION_HEADER);
Assert.assertNotNull("Missing validation header", header);
Assert.assertTrue("Wrong validation header", Boolean.valueOf(header));
Object entity = response.readEntity(String.class);
logger.info("entity: " + entity);
ViolationReport r = new ViolationReport(String.class.cast(entity));
TestUtil.countViolations(r, 0, 0, 0, 0, 1);
ResteasyConstraintViolation violation = r.getReturnValueViolations().iterator().next();
logger.info("violation: " + violation);
Assert.assertEquals(WRONG_ERROR_MSG, "size must be between 2 and 4", violation.getMessage());
Assert.assertEquals(RESPONSE_ERROR_MSG, "abcde", violation.getValue());
response.close();
} catch (Exception e) {
throw new RuntimeException("expected InternalServerErrorException", e);
}
}
/**
* @tpTestDetails Check other groups validation
* @tpSince RESTEasy 3.0.16
*/
@Test
public void testOtherGroups() throws Exception {
// Test invalid field, property, parameter, and class.
Response response = client.target(generateURL(BASIC_DEPLOYMENT, "/test/a/z", ValidationComplexResourceWithOtherGroups.class.getSimpleName()))
.request().post(Entity.text(new String()));
String entity = response.readEntity(String.class);
logger.info("entity: " + entity);
Assert.assertEquals(RESPONSE_ERROR_MSG, "z", entity);
response.close();
}
private List<String> getMessages(ViolationReport r) {
List<String> list = new ArrayList<>();
list.addAll(getMessagesFromList(r.getFieldViolations()));
list.addAll(getMessagesFromList(r.getPropertyViolations()));
list.addAll(getMessagesFromList(r.getClassViolations()));
list.addAll(getMessagesFromList(r.getParameterViolations()));
list.addAll(getMessagesFromList(r.getReturnValueViolations()));
return list;
}
private List<String> getMessagesFromList(List<ResteasyConstraintViolation> rcvs) {
List<String> list = new ArrayList<>();
for (Iterator<ResteasyConstraintViolation> it = rcvs.iterator(); it.hasNext(); ) {
ResteasyConstraintViolation rcv = it.next();
list.add(rcv.getMessage() + "; " + rcv.getValue());
}
return list;
}
}