/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF 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 de.unioninvestment.eai.portal.portlet.crud.scripting.model; import static java.util.Arrays.asList; import static java.util.Collections.singletonMap; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.sameInstance; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isA; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import groovy.lang.Closure; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import com.vaadin.data.util.sqlcontainer.RowId; import com.vaadin.ui.Component; import com.vaadin.ui.Table.ColumnGenerator; import de.unioninvestment.eai.portal.portlet.crud.domain.events.ModeChangeEvent; import de.unioninvestment.eai.portal.portlet.crud.domain.events.ModeChangeEventHandler; import de.unioninvestment.eai.portal.portlet.crud.domain.events.RowChangeEvent; import de.unioninvestment.eai.portal.portlet.crud.domain.events.RowChangeEventHandler; import de.unioninvestment.eai.portal.portlet.crud.domain.events.SelectionEvent; import de.unioninvestment.eai.portal.portlet.crud.domain.events.SelectionEventHandler; import de.unioninvestment.eai.portal.portlet.crud.domain.events.TableDoubleClickEvent; import de.unioninvestment.eai.portal.portlet.crud.domain.events.TableDoubleClickEventHandler; import de.unioninvestment.eai.portal.portlet.crud.domain.model.ContainerBlob; import de.unioninvestment.eai.portal.portlet.crud.domain.model.ContainerClob; import de.unioninvestment.eai.portal.portlet.crud.domain.model.ContainerRow; import de.unioninvestment.eai.portal.portlet.crud.domain.model.ContainerRowId; import de.unioninvestment.eai.portal.portlet.crud.domain.model.DataContainer; import de.unioninvestment.eai.portal.portlet.crud.domain.model.DatabaseContainerRowId; import de.unioninvestment.eai.portal.portlet.crud.domain.model.Table; import de.unioninvestment.eai.portal.portlet.crud.domain.model.Table.DynamicColumnChanges; import de.unioninvestment.eai.portal.portlet.crud.domain.model.Table.Mode; import de.unioninvestment.eai.portal.support.vaadin.groovy.VaadinBuilder; public class ScriptTableTest { @Mock private Table tableMock; private Set<ContainerRowId> selectionRowId = new HashSet<ContainerRowId>(); private ScriptTable scriptTable; @Mock private Closure<?> onSelectionChangeMock; @Mock private Closure<?> onModeMock; @Mock private Closure<?> onRowChangeClosureMock; @Mock private Closure<?> onDoubleClickClosureMock; @Mock private Closure<?> otherDoubleClickClosureMock; @Captor private ArgumentCaptor<ModeChangeEventHandler<Table, Mode>> modeChangeEventCaptor; @Captor private ArgumentCaptor<RowChangeEventHandler> rowChangeEventCaptor; @Mock private DataContainer databaseContainerMock; @Mock private ScriptContainer scriptContainerMock; @Mock private RowId rowIdMock; private ContainerRowId containerRowId; @Mock private ContainerRow containerRowMock; @Captor private ArgumentCaptor<TableDoubleClickEventHandler> doubleClickEventCaptor; @Captor private ArgumentCaptor<Map<String,Object>> defaultValueMapCaptor; @Mock private ContainerClob containerClobMock; @Mock private ContainerBlob containerBlobMock; @Before public void setUp() { MockitoAnnotations.initMocks(this); scriptTable = new ScriptTable(tableMock); scriptTable.setContainer(scriptContainerMock); when(tableMock.getContainer()).thenReturn(databaseContainerMock); when(rowIdMock.getId()).thenReturn(new Object[] { 1, 2 }); containerRowId = new DatabaseContainerRowId(rowIdMock, asList("A", "B")); } @Test public void shouldFireSelectionChangeEvent() { selectionRowId.add(containerRowId); ArgumentCaptor<SelectionEventHandler> selectionEventCaptor = ArgumentCaptor .forClass(SelectionEventHandler.class); verify(tableMock).addSelectionEventHandler( selectionEventCaptor.capture()); scriptTable.setOnSelectionChange(onSelectionChangeMock); SelectionEvent selectionEvent = new SelectionEvent(tableMock, selectionRowId); selectionEventCaptor.getValue().onSelectionChange(selectionEvent); verify(onSelectionChangeMock).call(eq(scriptTable), any(ScriptTableSelection.class)); } @Test public void shouldFireSelectionChangeEventClosureNull() { selectionRowId.add(containerRowId); ArgumentCaptor<SelectionEventHandler> selectionEventCaptor = ArgumentCaptor .forClass(SelectionEventHandler.class); verify(tableMock).addSelectionEventHandler( selectionEventCaptor.capture()); SelectionEvent selectionEvent = new SelectionEvent(tableMock, selectionRowId); selectionEventCaptor.getValue().onSelectionChange(selectionEvent); verify(onSelectionChangeMock, never()).call(eq(scriptTable), any(ScriptTableSelection.class)); } @Test public void shouldFireModeChangeEvent() { verify(tableMock).addModeChangeEventHandler( modeChangeEventCaptor.capture()); scriptTable.setOnModeChange(onModeMock); ModeChangeEvent<Table, Mode> modeChangeEvent = new ModeChangeEvent<Table, Mode>( tableMock, Mode.EDIT); modeChangeEventCaptor.getValue().onModeChange(modeChangeEvent); verify(onModeMock).call(scriptTable, "EDIT"); } @Test public void shouldFireRowChangeEvent() { verify(tableMock).addRowChangeEventHandler( rowChangeEventCaptor.capture()); scriptTable.setOnRowChange(onRowChangeClosureMock); Map<String, Object> changedValues = singletonMap("FIELDNAME", (Object) "OLDVALUE"); RowChangeEvent rowChangeEvent = new RowChangeEvent(containerRowMock, changedValues); rowChangeEventCaptor.getValue().rowChange(rowChangeEvent); verify(onRowChangeClosureMock).call(any(ScriptTable.class), any(ScriptRow.class), eq(changedValues)); } @Test public void shouldFireModeChangeEventClosureNull() { verify(tableMock).addModeChangeEventHandler( modeChangeEventCaptor.capture()); ModeChangeEvent<Table, Mode> modeChangeEvent = new ModeChangeEvent<Table, Mode>( tableMock, Mode.EDIT); modeChangeEventCaptor.getValue().onModeChange(modeChangeEvent); verify(onModeMock, never()).call(scriptTable, Mode.EDIT); } @Test public void shouldFireDoubleClickEvent() { scriptTable.setOnDoubleClick(onDoubleClickClosureMock); verify(tableMock).addDoubleClickEventHandler( doubleClickEventCaptor.capture()); TableDoubleClickEvent doubleClickEvent = new TableDoubleClickEvent( tableMock, containerRowMock); doubleClickEventCaptor.getValue().onDoubleClick(doubleClickEvent); verify(onDoubleClickClosureMock).call(any(ScriptTable.class), any(ScriptRow.class)); } @Test public void shouldRemoveExistingEventHandlerOnNullDoubleClickEventHandler() { scriptTable.setOnDoubleClick(onDoubleClickClosureMock); verify(tableMock).addDoubleClickEventHandler( doubleClickEventCaptor.capture()); scriptTable.setOnDoubleClick(null); verify(tableMock).removeDoubleClickEventHandler( doubleClickEventCaptor.getValue()); } @Test public void shouldNotAddDoubleClickEventHandlerTwice() { scriptTable.setOnDoubleClick(onDoubleClickClosureMock); scriptTable.setOnDoubleClick(otherDoubleClickClosureMock); verify(tableMock, times(1)).addDoubleClickEventHandler(any(TableDoubleClickEventHandler.class)); } @Test public void shouldIgnoreNullDoubleClickEventHandler() { scriptTable.setOnDoubleClick(null); verify(tableMock, never()).addDoubleClickEventHandler(any(TableDoubleClickEventHandler.class)); } @Test public void shouldCallRefreshOnTable() { scriptTable.refresh(); verify(tableMock).refresh(); } @Test public void addGeneratedColumnShouldConvertClosureToColumnGenerator() { // gegeben eine Closure zur Generierung der Zellen String columnId = "columnId"; @SuppressWarnings("unchecked") Closure<Component> generatorClosure = mock(Closure.class); // wenn addGeneratedColumn mit dieser Closure aufgerufen wird scriptTable.addGeneratedColumn(columnId, generatorClosure); // dann wird diese Closure in einen Table.ColumnGenerator gewrappt verify(tableMock).addGeneratedColumn(eq(columnId), eq(columnId), isA(com.vaadin.ui.Table.ColumnGenerator.class)); } @Test public void columnGeneratorShouldCallClosure() { // gegeben eine Closure zur Generierung der Zellen String columnId = "columnId"; @SuppressWarnings("unchecked") Closure<Component> generatorClosure = mock(Closure.class); com.vaadin.ui.Table source = new com.vaadin.ui.Table(); Object itemId = "itemId"; ContainerRow rowMock = mock(ContainerRow.class); when(tableMock.getRowByItemId(itemId)).thenReturn(rowMock); // wenn addGeneratedColumn mit dieser Closure aufgerufen wird scriptTable.addGeneratedColumn(columnId, generatorClosure); // und wenn dann der Table.ColumnGenerator-Wrapper aufgerufen wird ArgumentCaptor<com.vaadin.ui.Table.ColumnGenerator> captor = ArgumentCaptor .forClass(com.vaadin.ui.Table.ColumnGenerator.class); verify(tableMock).addGeneratedColumn(eq(columnId), eq(columnId), captor.capture()); ColumnGenerator generator = captor.getValue(); generator.generateCell(source, itemId, columnId); // dann wird intern die Closure zur Generierung der Zellen benutzt verify(generatorClosure).call(isA(ScriptRow.class), isA(VaadinBuilder.class)); } @Test public void shouldDelegateRemoveGeneratedColumn() { scriptTable.removeGeneratedColumn("columnId"); verify(tableMock).removeGeneratedColumn("columnId"); } @Test public void shouldDelegateRenderOnce() { @SuppressWarnings("unchecked") Closure<Component> changes = mock(Closure.class); scriptTable.renderOnce(changes); verify(tableMock).renderOnce(isA(DynamicColumnChanges.class)); } @Test public void shouldDelegateHasGeneratedColumn() { scriptTable.hasGeneratedColumn("columnId"); verify(tableMock).hasGeneratedColumn("columnId"); } @Test public void shouldDelegateClearAllGeneratedColumns() { scriptTable.clearAllGeneratedColumns(); verify(tableMock).clearAllGeneratedColumns(); } @Test public void shouldDelegateGetVisibleColumns() { scriptTable.getVisibleColumns(); verify(tableMock).getVisibleColumns(); } @Test public void shouldDelegateSetVisibleColumns() { List<String> columnIds = Arrays.asList(new String[] { "1", "2", "3" }); scriptTable.setVisibleColumns(columnIds); verify(tableMock).setVisibleColumns(columnIds); } @Test public void shouldDelegateCreateNewRow() { // Gegeben einige Werte für eine neue Zeile Map<String, Object> values = createValuesForNewRow(); when(tableMock.createNewRow((Map<String,Object>)any())).thenReturn(containerRowMock); // wenn per createNewRow eine neue Zeile hinzugefügt wird scriptTable.createNewRow(values); // dann sollte dies an die Modell-Table delegiert werden verify(tableMock).createNewRow(defaultValueMapCaptor.capture()); assertThat(defaultValueMapCaptor.getValue().size(), is(5)); assertThat(defaultValueMapCaptor.getValue().get("1"), is((Object)"Fitze")); assertThat(defaultValueMapCaptor.getValue().get("2"), is((Object)"Fatze")); assertThat(defaultValueMapCaptor.getValue().get("3"), is((Object)"Foo")); assertThat(defaultValueMapCaptor.getValue().get("4"), is((Object)containerClobMock)); assertThat(defaultValueMapCaptor.getValue().get("5"), is((Object)containerBlobMock)); } private Map<String, Object> createValuesForNewRow() { Map<String, Object> values = new HashMap<String, Object>(); values.put("1", "Fitze"); values.put("2", "Fatze"); values.put("3", "Foo"); values.put("4", new ScriptClob(containerClobMock)); values.put("5", new ScriptBlob(containerBlobMock)); return values; } @Test public void getRowByIdShouldReturnRow() { when(tableMock.getRow(containerRowId)).thenReturn(containerRowMock); ScriptRow scriptRow = scriptTable.getRowById(new ScriptRowId( containerRowId)); assertThat(scriptRow.getRow(), is(sameInstance(containerRowMock))); } @Test public void getRowByIdShouldReturnNullWhenNoSuchRowExists() { when(tableMock.getRow(containerRowId)).thenReturn(null); assertNull(scriptTable.getRowById(new ScriptRowId(containerRowId))); } @Test public void getSelectedRows() { Set<ScriptRowId> selectedRowIds = new HashSet<ScriptRowId>(); addScriptRowId(selectedRowIds); addScriptRowId(selectedRowIds); addScriptRowId(selectedRowIds); ScriptTableSelection selection = new ScriptTableSelection( databaseContainerMock, selectedRowIds); ScriptTable spy = Mockito.spy(scriptTable); when(spy.getSelection()).thenReturn(selection); assertThat(spy.getSelectedRows().size(), is(equalTo(3))); } private void addScriptRowId(Set<ScriptRowId> selectedRowIds) { selectedRowIds.add(createScriptRowId()); } private ScriptRowId createScriptRowId() { return new ScriptRowId(new DatabaseContainerRowId(mock(RowId.class), asList("A", "B"))); } @Test public void shouldDelegateSetTableActionVisibility() { scriptTable.setTableActionVisibility("ID", false); verify(tableMock).setTableActionVisibility("ID", false); } }