/* * Copyright 2014 Rick Grashel. * * Licensed 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 net.sourceforge.stripes.action; import java.net.HttpURLConnection; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import javax.servlet.http.HttpServletResponse; import org.testng.Assert; import org.testng.annotations.Test; import net.sourceforge.stripes.FilterEnabledTestBase; import net.sourceforge.stripes.mock.MockRoundtrip; import net.sourceforge.stripes.util.Log; import net.sourceforge.stripes.validation.SimpleError; import net.sourceforge.stripes.validation.TypeConverter; import net.sourceforge.stripes.validation.Validate; import net.sourceforge.stripes.validation.ValidateNestedProperties; import net.sourceforge.stripes.validation.ValidationError; import net.sourceforge.stripes.validation.ValidationErrorHandler; import net.sourceforge.stripes.validation.ValidationErrors; import net.sourceforge.stripes.validation.ValidationMethod; /** * This is a series of tests for Stripes REST action beans. */ @RestActionBean @UrlBinding("/test/custom-validation-error-handler/{person}") public class RestWithCustomValidationErrorHandlerActionBeanTest extends FilterEnabledTestBase implements ActionBean, ValidationErrorHandler { private static final Log log = Log.getInstance(RestWithCustomValidationErrorHandlerActionBeanTest.class); @Validate(on = "head", required = true) private String id; @ValidateNestedProperties( { @Validate( field = "id", required = true, on = "boundPersonEvent" ) }) @Validate(converter = PersonTypeConverter.class) private Person person; @Override public Resolution handleValidationErrors( ValidationErrors errors ) throws Exception { return new ErrorResolution( HttpServletResponse.SC_BAD_REQUEST, "yay! custom error validation handler" ); } public Resolution customHttpVerb() { return new JsonResolution("Yay! This is a custom HTTP verb!"); } public Resolution get() { Map< String, Object> response = new HashMap< String, Object>(); response.put("foo", "bar"); response.put("hello", "world"); response.put("person", new Person()); Map< String, Number> nested = new HashMap< String, Number>(); nested.put("one", 1); nested.put("two", 2); response.put("numbers", nested); return new JsonResolution(response); } @POST public Resolution boundPersonEvent() { return new JsonResolution(getPerson()); } public Resolution jsonResolutionWithExclusion() { Person p = new Person(); return new JsonResolution(p, "firstName"); } @ValidationMethod(on = "head") public void validateHeadCall(ValidationErrors errors) { errors.addGlobalError(new SimpleError("The head request was not valid for whatever custom reason.")); } public Resolution head() { return new JsonResolution("Successful head!"); } public Resolution testUnhandledExceptionEvent() { throw new RuntimeException("Some Unhandled Exception Occurred!"); } @POST public Resolution onlySupportsPost() { return new JsonResolution("Successful onlySupportsPost()!"); } public void setId(String id) { this.id = id; } public String getId() { return this.id; } public void setPerson(Person person) { this.person = person; } public Person getPerson() { return this.person; } private ActionBeanContext context; public ActionBeanContext getContext() { return this.context; } public void setContext(ActionBeanContext context) { this.context = context; } @Test(groups = "fast") public void testCustomValidationError() throws Exception { MockRoundtrip trip = new MockRoundtrip(getMockServletContext(), getClass()); trip.getRequest().setMethod("HEAD"); trip.execute("head"); Assert.assertEquals(trip.getResponse().getStatus(), HttpURLConnection.HTTP_BAD_REQUEST); Assert.assertEquals(trip.getResponse().getErrorMessage(), "yay! custom error validation handler"); logTripResponse(trip); } private void logTripResponse(MockRoundtrip trip) { log.debug("TRIP RESPONSE: [Event=" + trip.getActionBean(getClass()).getContext().getEventName() + "] [Status=" + trip.getResponse().getStatus() + "] [Message=" + trip.getResponse().getOutputString() + "] [Error Message=" + trip.getResponse().getErrorMessage() + "]"); } public static class Person { String id = null; String firstName = "John"; String lastName = "Doe"; List< String> favoriteFoods = new ArrayList< String>(); List< Person> children = new ArrayList<Person>(); public void setChildren( List< Person > children ) { this.children = children; } public List< Person > getChildren() { return this.children; } public void setId( String id ) { this.id = id; } public String getId() { return this.id; } public void setFavoriteFoods(List< String> favoriteFoods) { this.favoriteFoods = favoriteFoods; } public List< String> getFavoriteFoods() { return this.favoriteFoods; } public String getFirstName() { return this.firstName; } public String getLastName() { return this.lastName; } public void setFirstName(String firstName) { this.firstName = firstName; } public void setLastName(String lastName) { this.lastName = lastName; } } public static class PersonTypeConverter implements TypeConverter<Person> { public void setLocale(Locale locale) { } public Locale getLocale() { return Locale.getDefault(); } public Person convert(String input, Class<? extends Person> targetType, Collection<ValidationError> errors) { Person p = new Person(); p.setId(input); return p; } } }