/**
* Licensed to the Austrian Association for Software Tool Integration (AASTI)
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. The AASTI licenses this file to you 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.openengsb.ui.common.editor;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.wicket.Component;
import org.apache.wicket.extensions.ajax.markup.html.AjaxEditableLabel;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.util.tester.WicketTester;
import org.junit.Before;
import org.junit.Test;
import org.openengsb.core.api.descriptor.AttributeDefinition;
import org.openengsb.core.api.l10n.PassThroughStringLocalizer;
import org.openengsb.ui.common.editor.fields.AbstractField;
public class ServiceEditorPanelTest {
private WicketTester tester;
private ServiceEditorPanel editor;
private Map<String, String> defaultValues;
private AttributeDefinition attribOption;
private AttributeDefinition attribBoolean;
private final AttributeDefinition attrib = newAttribute("attrib", "name", "desc").build();
private final AttributeDefinition attribNoDesc = newAttribute("attribNoDesc", "name", "").build();
private Map<String, String> editorValues;
@Before
public void setup() {
Locale.setDefault(Locale.ENGLISH);
tester = new WicketTester();
attribOption = newAttribute("attribOption", "option", "").option("label_a", "1").option("label_b", "2").build();
attribBoolean = newAttribute("attribBool", "bool", "").asBoolean().build();
}
@Test
public void testEditingStringAttribute_shouldRenderTextFieldWithPresetValues() throws Exception {
startEditorPanel(attrib);
tester.debugComponentTrees();
TextField<?> tf = getEditorFieldFormComponent(attrib.getId(), TextField.class);
assertThat(tf.getValue(), is(defaultValues.get(attrib.getId())));
}
@Test
public void testAttributeWithDescription_shouldRenderTooltipImageWithTitle() throws Exception {
startEditorPanel(attrib);
assertThat(((Image) getEditorField(attrib.getId()).get("tooltip")).isVisible(), is(true));
}
@Test
public void testAttributeWithoutDescription_shouldShowNoTooltipImage() throws Exception {
startEditorPanel(attribNoDesc);
assertThat(getEditorField(attribNoDesc.getId()).get("tooltip").isVisible(), is(false));
}
@Test
public void testOptionAttribute_shouldBeDisplayedAsDropDown() throws Exception {
startEditorPanel(attribOption);
DropDownChoice<?> choice = getEditorFieldFormComponent(attribOption.getId(), DropDownChoice.class);
assertThat(choice.getChoices().size(), is(attribOption.getOptions().size()));
}
@Test
public void testChoicesInDropDownChoice_shouldBeInSameOrderAsOptionAttribute() throws Exception {
startEditorPanel(attribOption);
@SuppressWarnings("unchecked")
List<String> choice = getEditorFieldFormComponent(attribOption.getId(), DropDownChoice.class).getChoices();
for (int i = 0; i < attribOption.getOptions().size(); ++i) {
assertThat(choice.get(i), is(attribOption.getOptions().get(i).getValue()));
}
}
@Test
public void testBoolAttribute_shouldBeDisplayedAsCheckBox() throws Exception {
startEditorPanel(attribBoolean);
CheckBox cb = getEditorFieldFormComponent(attribBoolean.getId(), CheckBox.class);
assertThat(cb, notNullValue());
}
@Test
public void testContainsInitialPropertiesFields_shouldContainProperties() throws Exception {
Map<String, Object> props = new Hashtable<String, Object>();
props.put("testpropx", "42");
props.put("foo", "bar");
startEditorPanel(props, attribOption);
Label label1 = (Label) tester.getComponentFromLastRenderedPage("panel:properties:0:key");
assertThat(label1.getDefaultModelObjectAsString(), is("foo"));
Component comp = tester.getComponentFromLastRenderedPage("panel:properties:0:values:1:value");
@SuppressWarnings("unchecked")
AjaxEditableLabel<String> value1 = (AjaxEditableLabel<String>) comp;
assertThat((String) value1.getDefaultModelObject(), is("bar"));
Label label2 = (Label) tester.getComponentFromLastRenderedPage("panel:properties:1:key");
assertThat(label2.getDefaultModelObjectAsString(), is("testpropx"));
@SuppressWarnings("unchecked")
AjaxEditableLabel<String> value2 =
(AjaxEditableLabel<String>) tester.getComponentFromLastRenderedPage("panel:properties:1:values:1:value");
assertThat((String) value2.getDefaultModelObject(), is("42"));
}
@Test
public void testContainsInitialPropertiesFieldsWithArray_shouldContainProperties() throws Exception {
Map<String, Object> props = new Hashtable<String, Object>();
props.put("testpropx", new String[]{ "42", "foo" });
startEditorPanel(props, attribOption);
Label label1 = (Label) tester.getComponentFromLastRenderedPage("panel:properties:0:key");
assertThat(label1.getDefaultModelObjectAsString(), is("testpropx"));
tester.debugComponentTrees();
@SuppressWarnings("unchecked")
AjaxEditableLabel<String> value1 =
(AjaxEditableLabel<String>) tester.getComponentFromLastRenderedPage("panel:properties:0:values:1:value");
assertThat((String) value1.getDefaultModelObject(), is("42"));
@SuppressWarnings("unchecked")
AjaxEditableLabel<String> value2 =
(AjaxEditableLabel<String>) tester.getComponentFromLastRenderedPage("panel:properties:0:values:2:value");
assertThat((String) value2.getDefaultModelObject(), is("foo"));
}
@Test
public void testDeleteProperty_shouldWork() throws Exception {
Map<String, Object> props = new Hashtable<String, Object>();
props.put("testpropx", new String[]{ "42", "foo" });
props.put("testpropy", new String[]{ "ping", "pong" });
startEditorPanel(props, attribOption);
String path = "panel:properties:0:key";
Label label1 = (Label) tester.getComponentFromLastRenderedPage(path);
String before = label1.getDefaultModelObjectAsString();
tester.executeAjaxEvent("panel:properties:0:buttonKey", "onclick");
label1 = (Label) tester.getComponentFromLastRenderedPage(path);
String after = label1.getDefaultModelObjectAsString();
assertThat(before, is("testpropx"));
assertThat(after, is("testpropy"));
}
@Test
public void testDeletePropertyValue_shouldWork() throws Exception {
Map<String, Object> props = new Hashtable<String, Object>();
props.put("testpropx", new String[]{ "42", "foo" });
startEditorPanel(props, attribOption);
String path = "panel:properties:0:values:1:value";
@SuppressWarnings("unchecked")
AjaxEditableLabel<String> value1 =
(AjaxEditableLabel<String>) tester.getComponentFromLastRenderedPage(path);
String before = (String) value1.getDefaultModelObject();
tester.executeAjaxEvent("panel:properties:0:values:1:buttonValue", "onclick");
@SuppressWarnings("unchecked")
AjaxEditableLabel<String> value2 =
(AjaxEditableLabel<String>) tester.getComponentFromLastRenderedPage(path);
String after = (String) value2.getDefaultModelObject();
assertThat(before, is("42"));
assertThat(after, is("foo"));
}
private AttributeDefinition.Builder newAttribute(String id, String name, String desc) {
return AttributeDefinition.builder(new PassThroughStringLocalizer()).id(id).name(name).description(desc);
}
private void startEditorPanel(final Map<String, Object> properties,
final AttributeDefinition... attributes) {
editorValues = new HashMap<String, String>();
defaultValues = new HashMap<String, String>();
for (AttributeDefinition a : attributes) {
editorValues.put(a.getId(), a.getDefaultValue().getString(Locale.ENGLISH));
defaultValues.put(a.getId(), a.getDefaultValue().getString(Locale.ENGLISH));
}
@SuppressWarnings("rawtypes")
Form form = mock(Form.class);
when(form.getRootForm()).thenReturn(form);
editor =
tester.startComponentInPage(new ServiceEditorPanel("panel", Arrays.asList(attributes), editorValues,
properties, form));
}
private void startEditorPanel(final AttributeDefinition... attributes) {
startEditorPanel(new Hashtable<String, Object>(), attributes);
}
@SuppressWarnings("unchecked")
private <T> T getEditorFieldFormComponent(String attributeId, Class<T> componentType) {
String id = editor.getId() + ":" + buildFormComponentId(attributeId);
Component c = tester.getComponentFromLastRenderedPage(id);
assertThat(c, notNullValue());
assertThat(c, instanceOf(componentType));
return (T) c;
}
public String buildFormComponentId(String attributeId) {
return "fields:" + attributeId + ":row:field";
}
private AbstractField<?> getEditorField(String attributeId) {
return (AbstractField<?>) getEditorFieldFormComponent(attributeId, FormComponent.class).getParent();
}
}