/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates.
*
* 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 org.kie.workbench.common.forms.jbpm.server.service.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.kie.workbench.common.forms.commons.layout.impl.DynamicFormLayoutTemplateGenerator;
import org.kie.workbench.common.forms.fields.shared.fieldTypes.basic.selectors.listBox.definition.EnumListBoxFieldDefinition;
import org.kie.workbench.common.forms.fields.shared.fieldTypes.relations.multipleSubform.definition.MultipleSubFormFieldDefinition;
import org.kie.workbench.common.forms.fields.shared.fieldTypes.relations.subForm.definition.SubFormFieldDefinition;
import org.kie.workbench.common.forms.fields.test.TestFieldManager;
import org.kie.workbench.common.forms.jbpm.model.authoring.JBPMFormModel;
import org.kie.workbench.common.forms.jbpm.model.authoring.JBPMVariable;
import org.kie.workbench.common.forms.jbpm.server.service.formGeneration.impl.runtime.BPMNRuntimeFormGeneratorService;
import org.kie.workbench.common.forms.jbpm.server.service.impl.model.LogEntry;
import org.kie.workbench.common.forms.jbpm.server.service.impl.model.Person;
import org.kie.workbench.common.forms.jbpm.server.service.impl.model.PersonType;
import org.kie.workbench.common.forms.jbpm.server.service.impl.model.PersonalData;
import org.kie.workbench.common.forms.jbpm.service.bpmn.util.BPMNVariableUtils;
import org.kie.workbench.common.forms.model.FieldDefinition;
import org.kie.workbench.common.forms.model.FormDefinition;
import org.kie.workbench.common.forms.model.JavaModel;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
public abstract class BPMNFormGenerationTest<MODEL extends JBPMFormModel> {
@Mock
private ClassLoader classLoader;
protected BPMNRuntimeFormGeneratorService generatorService;
protected DynamicBPMNFormGeneratorImpl generator;
private MODEL model;
@Before
public void initTest() {
generatorService = new BPMNRuntimeFormGeneratorService(new TestFieldManager(),
new DynamicFormLayoutTemplateGenerator());
generator = new DynamicBPMNFormGeneratorImpl(generatorService);
}
protected abstract String getModelId();
protected abstract MODEL getModel(String modelId,
List<JBPMVariable> variables);
protected abstract Collection<FormDefinition> getModelForms(MODEL model,
ClassLoader classLoader);
@Test
public void testSimpleVariables() {
List<JBPMVariable> variables = new ArrayList<>();
variables.add(new JBPMVariable("employee",
String.class.getName()));
variables.add(new JBPMVariable("manager",
String.class.getName()));
variables.add(new JBPMVariable("performance",
Integer.class.getName()));
variables.add(new JBPMVariable("approved",
Boolean.class.getName()));
model = getModel(getModelId(),
variables);
Collection<FormDefinition> forms = getModelForms(model,
classLoader);
try {
verify(classLoader,
never()).loadClass(anyString());
} catch (ClassNotFoundException e) {
fail("We shouldn't be here: " + e.getMessage());
}
assertNotNull("There should one form",
forms);
assertEquals("There should one form",
1,
forms.size());
FormDefinition form = forms.iterator().next();
assertEquals(getModelId() + BPMNVariableUtils.TASK_FORM_SUFFIX,
form.getId());
assertEquals(getModelId() + BPMNVariableUtils.TASK_FORM_SUFFIX,
form.getName());
assertEquals(form.getModel(),
model);
assertEquals("There should be 4 fields",
4,
form.getFields().size());
variables.forEach(variable -> {
FieldDefinition field = form.getFieldByBinding(variable.getName());
assertFieldStatus(field,
variable);
});
}
@Test
public void testComplexFieldsFromClassLoader() {
testComplexFields(true);
}
@Test
public void testComplexFieldsFromGeneralClassLoader() {
testComplexFields(false);
}
protected void testComplexFields(boolean fromClassLoader) {
if (fromClassLoader) {
try {
when(classLoader.loadClass(Person.class.getName())).then(new Answer<Class<?>>() {
@Override
public Class<?> answer(InvocationOnMock invocationOnMock) throws Throwable {
return Person.class;
}
});
} catch (ClassNotFoundException e) {
fail("We shouldn't be here: " + e.getMessage());
}
}
List<JBPMVariable> variables = new ArrayList<>();
variables.add(new JBPMVariable("person",
Person.class.getName()));
model = getModel(getModelId(),
variables);
Collection<FormDefinition> forms = getModelForms(model,
classLoader);
Map<String, FormDefinition> allForms = new HashMap<>();
forms.forEach(form -> allForms.put(form.getId(),
form));
try {
verify(classLoader,
times(3)).loadClass(anyString());
} catch (ClassNotFoundException e) {
fail(e.getMessage());
}
assertNotNull("There should some forms",
forms);
assertEquals("There should 4 forms",
4,
forms.size());
FormDefinition form = allForms.get(getModelId() + BPMNVariableUtils.TASK_FORM_SUFFIX);
checkBPMForm(form,
allForms);
form = findFormForModel(Person.class.getName(),
allForms);
checkPersonForm(form,
allForms);
form = findFormForModel(PersonalData.class.getName(),
allForms);
checkPersonalDataForm(form,
allForms);
form = findFormForModel(LogEntry.class.getName(),
allForms);
checkLogEntryForm(form);
}
protected FormDefinition findFormForModel(String className,
Map<String, FormDefinition> allForms) {
return allForms.values().stream().filter(formDefinition -> {
if (formDefinition.getModel() instanceof JavaModel) {
return ((JavaModel) formDefinition.getModel()).getType().equals(className);
}
return false;
}).findFirst().orElse(null);
}
private void checkLogEntryForm(FormDefinition form) {
assertNotNull(form);
assertEquals(2,
form.getFields().size());
FieldDefinition field = form.getFieldByBinding("date");
assertFieldStatus(field,
"date",
Date.class.getName());
field = form.getFieldByBinding("text");
assertFieldStatus(field,
"text",
String.class.getName());
}
private void checkPersonalDataForm(FormDefinition form,
Map<String, FormDefinition> allForms) {
assertNotNull(form);
assertEquals(2,
form.getFields().size());
FieldDefinition field = form.getFieldByBinding("address");
assertFieldStatus(field,
"address",
String.class.getName());
field = form.getFieldByBinding("phone");
assertFieldStatus(field,
"phone",
String.class.getName());
}
private void checkBPMForm(FormDefinition form,
Map<String, FormDefinition> allForms) {
assertNotNull(form);
assertEquals(getModelId() + BPMNVariableUtils.TASK_FORM_SUFFIX,
form.getId());
assertEquals(getModelId() + BPMNVariableUtils.TASK_FORM_SUFFIX,
form.getName());
assertEquals(1,
form.getFields().size());
FieldDefinition field = form.getFieldByBinding("person");
assertFieldStatus(field,
"person",
Person.class.getName());
assertTrue(field instanceof SubFormFieldDefinition);
SubFormFieldDefinition subForm = (SubFormFieldDefinition) field;
assertNotNull(subForm.getNestedForm());
assertNotNull(allForms.get(subForm.getNestedForm()));
}
private void checkPersonForm(FormDefinition form,
Map<String, FormDefinition> allForms) {
assertNotNull(form);
assertTrue(form.getModel() instanceof JavaModel);
assertEquals(4,
form.getFields().size());
FieldDefinition field = form.getFieldByBinding("name");
assertFieldStatus(field,
"name",
String.class.getName());
field = form.getFieldByBinding("type");
assertFieldStatus(field,
"type",
PersonType.class.getName());
assertTrue(field instanceof EnumListBoxFieldDefinition);
field = form.getFieldByBinding("personalData");
assertFieldStatus(field,
"personalData",
PersonalData.class.getName());
assertTrue(field instanceof SubFormFieldDefinition);
SubFormFieldDefinition subForm = (SubFormFieldDefinition) field;
assertNotNull(subForm.getNestedForm());
assertNotNull(allForms.get(subForm.getNestedForm()));
field = form.getFieldByBinding("log");
assertFieldStatus(field,
"log",
LogEntry.class.getName());
assertTrue(field instanceof MultipleSubFormFieldDefinition);
MultipleSubFormFieldDefinition multipleSubForm = (MultipleSubFormFieldDefinition) field;
assertNotNull(multipleSubForm.getCreationForm());
assertEquals(multipleSubForm.getCreationForm(),
multipleSubForm.getEditionForm());
FormDefinition nestedForm = allForms.get(multipleSubForm.getCreationForm());
assertNotNull(nestedForm);
assertNotNull(multipleSubForm.getColumnMetas());
assertEquals(nestedForm.getFields().size(),
multipleSubForm.getColumnMetas().size());
multipleSubForm.getColumnMetas().forEach(columnMeta -> {
FieldDefinition nestedField = nestedForm.getFieldByBinding(columnMeta.getProperty());
assertNotNull(nestedField);
assertEquals(nestedField.getLabel(),
columnMeta.getLabel());
});
}
private void assertFieldStatus(FieldDefinition field,
JBPMVariable variable) {
assertFieldStatus(field,
variable.getName(),
variable.getType());
}
private void assertFieldStatus(FieldDefinition field,
String name,
String className) {
assertNotNull(field);
assertEquals(name,
field.getName());
assertEquals(name.toLowerCase(),
field.getName().toLowerCase());
assertEquals(name,
field.getBinding());
assertEquals(className,
field.getStandaloneClassName());
}
}