/**

   Copyright 2010 OpenEngSB Division, Vienna University of Technology

   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.openengsb.ui.web.editor;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.wicket.MarkupContainer;
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.markup.html.panel.Panel;
import org.apache.wicket.util.tester.FormTester;
import org.apache.wicket.util.tester.TestPanelSource;
import org.apache.wicket.util.tester.WicketTester;
import org.junit.Before;
import org.junit.Test;
import org.openengsb.core.config.descriptor.AttributeDefinition;

@SuppressWarnings("serial")
public class EditorTest {

    private WicketTester tester;
    private EditorPanel editor;
    private AttributeDefinition stringAttrib;
    private AttributeDefinition attribWithNoDescription;
    private Map<String, String> defaultValues;
    @Before
    public void setup() {
        stringAttrib = AttributeDefinition.builder().id("id_a").name("name_a").description("desc_a").build();
        attribWithNoDescription = AttributeDefinition.builder().id("id_b").name("name_b").build();
        final HashMap<String, String> values = new HashMap<String, String>();
        values.put(stringAttrib.getId(), stringAttrib.getId() + "_default");
        values.put(attribWithNoDescription.getId(), attribWithNoDescription.getId() + "_default");
        defaultValues = Collections.unmodifiableMap(values);
        tester = new WicketTester();
        editor = (EditorPanel) tester.startPanel(new TestPanelSource() {
            @Override
            public Panel getTestPanel(String panelId) {
                return new EditorPanel(panelId, Arrays.asList(stringAttrib, attribWithNoDescription), values);
            }
        });
    }

    @Test
    public void editingStringAttribute_shouldRenderTextFieldWithPresetValues() throws Exception {
        TextField<?> tf = getEditorFieldFormComponent(stringAttrib.getId(), TextField.class);
        assertThat(tf.getValue(), is(defaultValues.get(stringAttrib.getId())));
    }

    @Test
    public void attributeWithDescription_shouldRenderTooltipImageWithTitle() throws Exception {
        assertThat(((Image) getEditorField(stringAttrib.getId()).get("tooltip")).isVisible(), is(true));
    }

    @Test
    public void attributeWithoutDescription_shouldShowNoTooltipImage() throws Exception {
        assertThat(getEditorField(attribWithNoDescription.getId()).get("tooltip").isVisible(), is(false));
    }

    @Test
    public void submittingFormWithoutChange_shouldReturnInitialValues() throws Exception {
        FormTester formTester = tester.newFormTester(editor.getId() + ":form");
        formTester.submit();
        assertThat(editor.getValues(), is(defaultValues));
    }

    @Test
    public void submittingFormWithChanges_shouldReflectChangesInValues() throws Exception {
        FormTester formTester = tester.newFormTester(editor.getId() + ":form");
        setFormValue(stringAttrib.getId(), "new_value_a");
        formTester.submit();
        assertThat(editor.getValues().get(stringAttrib.getId()), is("new_value_a"));
    }

    // because of the dynamics of the editor, we have to look up the fields
    // another way
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private <T> T getEditorFieldFormComponent(String attributeId, Class<T> componentType) {
        Form<?> form = (Form<?>) editor.get("form");
        MarkupContainer fields = (MarkupContainer) form.get(1);
        for (int i = 0; i < fields.size(); ++i) {
            MarkupContainer row = (MarkupContainer) fields.get(i);
            FormComponent c = (FormComponent) ((Panel) row.get(0)).get(1);
            if (c.getInputName().equals("fields:" + attributeId + ":row:field")) {
                assertThat(c, is(componentType));
                return (T) c;
            }
        }
        fail("no form component '" + attributeId + "' found");
        throw new UnsupportedOperationException();
    }

    private EditorField getEditorField(String attributeId) {
        return (EditorField) getEditorFieldFormComponent(attributeId, FormComponent.class).getParent();
    }

    private void setFormValue(String attributeId, String value) {
        tester.getServletRequest().setParameter(
                getEditorFieldFormComponent(attributeId, FormComponent.class).getInputName(), value);
    }
}

@@ -725,31 +725,38 @@
 org.
-junit.Assert.assertThat
+hamcrest.Matchers.notNullValue
 ;%0Aim
@@ -784,20 +784,26 @@
 .Assert.
-fail
+assertThat
 ;%0A%0Aimpor
@@ -923,30 +923,73 @@
 che.
-wicket.MarkupContainer
+commons.logging.Log;%0Aimport org.apache.commons.logging.LogFactory
 ;%0Aim
@@ -1011,37 +1011,25 @@
 .wicket.
-markup.html.form.Form
+Component
 ;%0Aimport
@@ -1555,16 +1555,82 @@
 Test %7B%0A%0A
+    private final Log log = LogFactory.getLog(EditorTest.class);%0A%0A
     priv
@@ -4093,103 +4093,8 @@
  %7D%0A%0A
-    // because of the dynamics of the editor, we have to look up the fields%0A    // another way%0A
     
@@ -4115,22 +4115,8 @@
 ngs(
-%7B %22rawtypes%22, 
 %22unc
@@ -4122,18 +4122,16 @@
 checked%22
- %7D
 )%0A    pr
@@ -4228,232 +4228,81 @@
     
-Form%3C?%3E form = (Form%3C?%3E) editor.get(%22form%22);%0A        MarkupContainer fields = (MarkupContainer) form.get(1);%0A        for (int i = 0; i %3C fields.size(); ++i) %7B%0A            MarkupContainer row = (MarkupContainer) fields.get(i)
+String id = editor.getId() + %22:form:fields:%22 + attributeId + %22:row:field%22
 ;%0A  
@@ -4307,24 +4307,16 @@
         
-    Form
 Componen
@@ -4325,148 +4325,100 @@
 c = 
-(FormComponent) ((Panel) row.get(0)).get(1);%0A            if (c.getInputName().equals(%22fields:%22 + attributeId + %22:row:field%22)) %7B%0A    
+tester.getComponentFromLastRenderedPage(id);%0A        assertThat(c, notNullValue());%0A
         
     
@@ -4409,28 +4409,24 @@
 ));%0A        
-    
 assertThat(c
@@ -4447,24 +4447,16 @@
 Type));%0A
-        
         
@@ -4473,146 +4473,8 @@
  c;%0A
-            %7D%0A        %7D%0A        fail(%22no form component '%22 + attributeId + %22' found%22);%0A        throw new UnsupportedOperationException();%0A
     

simplify form component lookup in editor tests