Skip to content

Commit

Permalink
Add integration test for #827
Browse files Browse the repository at this point in the history
  • Loading branch information
BalusC committed Jul 28, 2024
1 parent 5d7816d commit f51fccf
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.omnifaces.test.taghandler.validatebean;

import java.io.Serializable;

import javax.validation.constraints.NotNull;

@FlightNumberConstraint
public class FlightNumber implements Serializable {

private static final long serialVersionUID = 1L;

@NotNull
private String airlineDesignator;

@NotNull
private Integer flightIdentifier;

public FlightNumber() {
//
}

public FlightNumber(String airlineDesignator, Integer flightIdentifier) {
this.airlineDesignator = airlineDesignator;
this.flightIdentifier = flightIdentifier;
}

public String getAirlineDesignator() {
return airlineDesignator;
}

public void setAirlineDesignator(String airlineDesignator) {
this.airlineDesignator = airlineDesignator;
}

public Integer getFlightIdentifier() {
return flightIdentifier;
}

public void setFlightIdentifier(Integer flightIdentifier) {
this.flightIdentifier = flightIdentifier;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.omnifaces.test.taghandler.validatebean;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

@Constraint(validatedBy = { FlightNumberValidator.class })
@Documented
@Target({ TYPE, METHOD, FIELD })
@Retention(RUNTIME)
public @interface FlightNumberConstraint {
String message() default "Invalid flight number";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.omnifaces.test.taghandler.validatebean;

import static java.util.Optional.ofNullable;
import static org.omnifaces.util.Messages.throwConverterException;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

@FacesConverter(value="flightNumberConverter", forClass=FlightNumber.class)
public class FlightNumberConverter implements Converter<FlightNumber> {

@Override
public String getAsString(FacesContext context, UIComponent component, FlightNumber modelValue) {
if (modelValue == null) {
return "";
}

return ofNullable(modelValue.getAirlineDesignator()).orElse("")
+ ofNullable(modelValue.getFlightIdentifier()).map(String::valueOf).orElse("");
}

@Override
public FlightNumber getAsObject(FacesContext context, UIComponent component, String submittedValue) {
if (submittedValue == null || submittedValue.trim().isEmpty()) {
return null;
}

String flightNumberAsString = submittedValue.trim().toUpperCase();

if (!flightNumberAsString.matches("[A-Z]{2}[0-9]{1,4}")) {
throwConverterException("Flight number must consist of 2-character airline designator and 1-4 digit flight identifier");
}

String airlineDesignator = flightNumberAsString.substring(0, 2);
Integer flightIdentifier = Integer.parseInt(flightNumberAsString.substring(2));

return new FlightNumber(airlineDesignator, flightIdentifier);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.omnifaces.test.taghandler.validatebean;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class FlightNumberValidator implements ConstraintValidator<FlightNumberConstraint, FlightNumber> {

private static final Set<Integer> AA_DISALLOWED_FLIGHT_IDENTIFIERS = new HashSet<>(Arrays.asList(11, 77));

@Override
public void initialize(FlightNumberConstraint constraintAnnotation) {
//
}

@Override
public boolean isValid(FlightNumber flightNumber, ConstraintValidatorContext context) {
if ("AA".equals(flightNumber.getAirlineDesignator())) {
return !AA_DISALLOWED_FLIGHT_IDENTIFIERS.contains(flightNumber.getFlightIdentifier());
}

return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,24 @@ public class ValidateBeanIT extends OmniFacesIT {
@FindBy(id="validateClassLevelWithFormEntityComposite:form:command")
private WebElement validateClassLevelWithFormEntityCompositeCommand;

@FindBy(id="validateBeanWithCustomTypeAsProperty:flightNumbers:0:input")
private WebElement validateBeanWithCustomTypeAsPropertyFlightNumber1;

@FindBy(id="validateBeanWithCustomTypeAsProperty:flightNumbers:0:message")
private WebElement validateBeanWithCustomTypeAsPropertyFlightNumber1Message;

@FindBy(id="validateBeanWithCustomTypeAsProperty:flightNumbers:1:input")
private WebElement validateBeanWithCustomTypeAsPropertyFlightNumber2;

@FindBy(id="validateBeanWithCustomTypeAsProperty:flightNumbers:1:message")
private WebElement validateBeanWithCustomTypeAsPropertyFlightNumber2Message;

@FindBy(id="validateBeanWithCustomTypeAsProperty:command")
private WebElement validateBeanWithCustomTypeAsPropertyCommand;

@FindBy(id="validateBeanWithCustomTypeAsProperty:messages")
private WebElement validateBeanWithCustomTypeAsPropertyMessages;

@Deployment(testable=false)
public static WebArchive createDeployment() {
return buildWebArchive(ValidateBeanIT.class)
Expand Down Expand Up @@ -897,4 +915,34 @@ public void validateClassLevelWithFormEntityComposite() {
assertEquals("actionSuccess", messages.getText());
}

@Test
void validateBeanWithCustomTypeAsProperty() {
open("ValidateBeanITWithCustomTypeAsProperty.xhtml");
validateBeanWithCustomTypeAsPropertyFlightNumber2.sendKeys("AA11");
guardAjax(validateBeanWithCustomTypeAsPropertyCommand).click();
assertEquals("", validateBeanWithCustomTypeAsPropertyFlightNumber1Message.getText());
assertEquals("flightNumberLabel: Invalid flight number", validateBeanWithCustomTypeAsPropertyFlightNumber2Message.getText());
assertEquals("", validateBeanWithCustomTypeAsPropertyMessages.getText());

validateBeanWithCustomTypeAsPropertyFlightNumber1.clear();
validateBeanWithCustomTypeAsPropertyFlightNumber1.sendKeys("AA11");
guardAjax(validateBeanWithCustomTypeAsPropertyCommand).click();
assertEquals("flightNumberLabel: Invalid flight number", validateBeanWithCustomTypeAsPropertyFlightNumber1Message.getText());
assertEquals("flightNumberLabel: Invalid flight number", validateBeanWithCustomTypeAsPropertyFlightNumber2Message.getText());
assertEquals("", validateBeanWithCustomTypeAsPropertyMessages.getText());

validateBeanWithCustomTypeAsPropertyFlightNumber2.clear();
validateBeanWithCustomTypeAsPropertyFlightNumber2.sendKeys("AA22");
guardAjax(validateBeanWithCustomTypeAsPropertyCommand).click();
assertEquals("flightNumberLabel: Invalid flight number", validateBeanWithCustomTypeAsPropertyFlightNumber1Message.getText());
assertEquals("", validateBeanWithCustomTypeAsPropertyFlightNumber2Message.getText());
assertEquals("", validateBeanWithCustomTypeAsPropertyMessages.getText());

validateBeanWithCustomTypeAsPropertyFlightNumber1.clear();
validateBeanWithCustomTypeAsPropertyFlightNumber1.sendKeys("AA33");
guardAjax(validateBeanWithCustomTypeAsPropertyCommand).click();
assertEquals("", validateBeanWithCustomTypeAsPropertyFlightNumber1Message.getText());
assertEquals("", validateBeanWithCustomTypeAsPropertyFlightNumber2Message.getText());
assertEquals("actionSuccess", validateBeanWithCustomTypeAsPropertyMessages.getText());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.omnifaces.test.taghandler.validatebean;

import static org.omnifaces.util.Faces.isValidationFailed;
import static org.omnifaces.util.Messages.addGlobalInfo;
import static org.omnifaces.util.Messages.addGlobalWarn;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.inject.Named;
import javax.validation.Valid;

import org.omnifaces.cdi.ViewScoped;

@Named
@ViewScoped
public class ValidateBeanITWithCustomTypeAsProperty implements Serializable {

private static final long serialVersionUID = 1L;

@Valid
private List<FlightNumber> flightNumbers;

@PostConstruct
public void init() {
flightNumbers = Arrays.asList(new FlightNumber("AA", 708), null);
}

public void action() {
if (isValidationFailed()) {
addGlobalWarn(" actionValidationFailed");
}
else {
addGlobalInfo("actionSuccess");
}
}

public List<FlightNumber> getFlightNumbers() {
return flightNumbers;
}

public void setFlightNumbers(List<FlightNumber> flightNumbers) {
this.flightNumbers = flightNumbers;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!--
Copyright OmniFaces
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
https://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.
-->
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:cc="http://xmlns.jcp.org/jsf/composite/components"
xmlns:o="http://omnifaces.org/ui"
xmlns:of="http://omnifaces.org/functions"
>
<h:head>
<title>ValidateBeanITWithCustomTypeAsProperty</title>
</h:head>

<h:body>
<h:form id="validateBeanWithCustomTypeAsProperty">
<ol>
<ui:repeat id="flightNumbers" value="#{validateBeanITWithCustomTypeAsProperty.flightNumbers}" varStatus="loop">
<li>
<h:inputText id="input" value="#{validateBeanITWithCustomTypeAsProperty.flightNumbers[loop.index]}" label="flightNumberLabel" required="true">
<f:converter converterId="flightNumberConverter" />
</h:inputText>
<h:message id="message" for="input" />
</li>
</ui:repeat>
</ol>

<h:commandButton id="command" value="submit" action="#{validateBeanITWithCustomTypeAsProperty.action}">
<f:ajax execute="@form" render="@form" />
</h:commandButton>

<h:messages id="messages" redisplay="false" />

<o:validateBean value="#{validateBeanITWithCustomTypeAsProperty}" showMessageFor="@violating" />
</h:form>
</h:body>
</html>

0 comments on commit f51fccf

Please sign in to comment.