package org.beanfabrics.validation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Locale;
import junit.framework.JUnit4TestAdapter;
import org.beanfabrics.BnModelObserver;
import org.beanfabrics.ModelProvider;
import org.beanfabrics.Path;
import org.beanfabrics.model.AbstractPM;
import org.beanfabrics.model.Options;
import org.beanfabrics.model.PMManager;
import org.beanfabrics.model.TextPM;
import org.beanfabrics.support.OnChange;
import org.beanfabrics.support.Service;
import org.junit.Test;
/**
* This test checks if the validation state of a parent presentation model is
* set correctly under certain circumstances:
* <p>
* Precondition: The parent PM (<code>AgentsModel</code>) has two mandatory
* child PMs. After setting the value of the first child PM by assigning a
* service to the parent's context this (first) PM is expected to be valid.
* <p>
* As a consequence it is expected that the composite validation state of the
* parent PM only contains a validation state for the second PM notifying to be
* mandatory and still not to be set.
* <p>
* To fulfill this condition {@link CompositeValidationState#equals(Object)} had
* to override it's super implementation.
*
* @author Max Gensthaler
*/
public class CompositeValidationStateTest {
static interface UIService {
public String[] getServerProjects();
}
static class AgentsModel extends AbstractPM {
@Service
protected UIService uiService;
protected final ProjectModel selectedProject = new ProjectModel();
protected final TextPM selectedAgent = new TextPM();
public AgentsModel() {
init();
PMManager.setup(this);
}
private void init() {
selectedProject.setMandatory(true);
selectedAgent.setMandatory(true);
}
@OnChange(path = "this.selectedProject")
protected void updateSelectedAgent() {
boolean b = selectedProject.isValid();
selectedAgent.setEditable(b);
}
}
static class ProjectModel extends TextPM {
public ProjectModel() {
PMManager.setup(this);
}
@Service
public void setUIService(UIService uiService) {
String[] serverProjects = uiService.getServerProjects();
// create options
Options<String> projectOpts = new Options<String>();
for (String project : serverProjects) {
projectOpts.put(project, project);
}
setOptions(projectOpts);
// init text value
if (serverProjects.length == 1) {
setText(serverProjects[0]);
setEditable(false);
}
}
@Override
public void revalidate() {
if (getOptions() == null || getOptions().size() == 0) {
setValidationState(new ValidationState("create server project"));
} else {
super.revalidate();
}
}
}
public static junit.framework.Test suite() {
return new JUnit4TestAdapter(CompositeValidationStateTest.class);
}
@Test
public void fireEvents() {
Locale.setDefault(Locale.ENGLISH);
final AgentsModel pm = new AgentsModel();
ModelProvider prov = new ModelProvider();
prov.setPresentationModel(pm);
final BnModelObserver ob = new BnModelObserver();
ob.setPath(new Path("this"));
ob.setModelProvider(prov);
final int[] count = new int[1];
final boolean[] isValid = new boolean[] { true };
ob.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
// printEvent("", evt);
if ("presentationModel".equals(evt.getPropertyName())) {
count[0]++;
isValid[0] = ob.getPresentationModel().isValid();
}
}
// private void printEvent(String prefix, EventObject evt) {
// System.out.println(prefix + evt);
// if (evt instanceof BnPropertyChangeEvent) {
// printEvent(prefix + " ", ((BnPropertyChangeEvent) evt).getCause());
// }
// }
});
pm.getContext().addService(UIService.class, new UIService() {
public String[] getServerProjects() {
return new String[] { "testproject" };
}
});
assertEquals("pm.selectedProject.getText()", "testproject", pm.selectedProject.getText());
assertTrue("pm.selectedProject.isValid()", pm.selectedProject.isValid());
// assertEquals("old validation message before fix", "create server project", getFirstNonCompositeState(pm.getValidationState()).getMessage());
assertEquals("validation message", "This value is mandatory", getFirstNonCompositeState(pm.getValidationState()).getMessage());
assertFalse("pm.isValid()", pm.isValid());
assertEquals("count[0]", 9, count[0]);
assertFalse("isValid[0]", isValid[0]);
}
private ValidationState getFirstNonCompositeState(ValidationState validationState) {
while (validationState instanceof CompositeValidationState) {
validationState = ((CompositeValidationState)validationState).getChildren().get(0);
}
return validationState;
}
}