/* * 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.domain.model; import com.google.common.collect.ImmutableSet; import com.vaadin.data.Container; import com.vaadin.data.Container.Ordered; import com.vaadin.data.Item; import com.vaadin.data.util.filter.And; import com.vaadin.data.util.filter.Compare; import com.vaadin.data.util.filter.Like; import com.vaadin.data.util.filter.Or; import de.unioninvestment.eai.portal.portlet.crud.domain.container.EditorSupport; import de.unioninvestment.eai.portal.portlet.crud.domain.events.*; import de.unioninvestment.eai.portal.portlet.crud.domain.model.DataContainer.ExportWithExportSettings; import de.unioninvestment.eai.portal.portlet.crud.domain.model.DataContainer.FilterPolicy; import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.*; import de.unioninvestment.eai.portal.support.vaadin.filter.AdvancedStringFilter; import de.unioninvestment.eai.portal.support.vaadin.filter.NothingFilter; import de.unioninvestment.eai.portal.support.vaadin.junit.LiferayContext; import de.unioninvestment.eai.portal.support.vaadin.mvp.EventBus; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.*; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import java.math.BigDecimal; import java.sql.SQLTimeoutException; import java.text.DateFormat; import java.text.NumberFormat; import java.util.*; import static java.util.Arrays.asList; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.isA; import static org.mockito.Mockito.*; public abstract class AbstractDataContainerTest<C extends AbstractDataContainer, V extends Ordered> { @Captor private ArgumentCaptor<com.vaadin.data.Container.Filter> filterCaptor; @Mock protected CreateEventHandler createEventHandlerMock; @Mock protected BeforeCommitEventHandler beforeCommitEventHandlerMock; @Mock protected InsertEventHandler insertEventHandlerMock; @Mock protected UpdateEventHandler updateEventHandlerMock; @Mock protected DeleteEventHandler deleteEventHandlerMock; @Mock protected CommitEventHandler commitEventHandlerMock; protected List<EditorSupport> editors = new ArrayList<EditorSupport>(); protected C container; protected V vaadinContainerMock; @Mock protected HashMap<String, String> displayPatternMock; protected HashMap<String, String> displayPattern = new HashMap<String, String>(); @Mock protected EditorSupport editorSupportMock; @Mock private ExportWithExportSettings exportMock; @Mock private ContainerRowId rowIdMock1, rowIdMock2; @Mock private Item itemMock1, itemMock2; @Mock private ContainerRow rowMock1, rowMock2; @Mock private DataContainer.EachRowCallback eachRowCallbackMock; @Mock private EventBus eventBusMock; @Rule public LiferayContext liferayContext = new LiferayContext(); @Before public final void setUp() { MockitoAnnotations.initMocks(this); editors.add(editorSupportMock); vaadinContainerMock = createVaadinContainer(); container = createDataContainer(); container.setEditors(editors); } /** * die zurückgelieferte Implementierung muss sowohl das {@code Container}, * als auch das {@code Filterable} Interface implementieren. Wenn es sich um * ein Mock handelt, könnte es wie folgt aussehen: * * <pre> * Mockito.mock(Container.class, * Mockito.withSettings().extraInterfaces(Filterable.class)) * </pre> * * @return */ public abstract C createDataContainer(); public abstract V createVaadinContainer(); @Test public void shouldRegisterOnCreateEvents() { container.addCreateEventHandler(createEventHandlerMock); assertTrue(container.getOnCreateEventRouter().contains( createEventHandlerMock)); } @Test public void shouldRegisterBeforeCommitEvents() { container.addBeforeCommitEventHandler(beforeCommitEventHandlerMock); assertTrue(container.getBeforeCommitEventRouter().contains( beforeCommitEventHandlerMock)); } @Test public void shouldRegisterOnInsertEvents() { container.addInsertEventHandler(insertEventHandlerMock); assertTrue(container.getOnInsertEventRouter().contains( insertEventHandlerMock)); } @Test public void shouldRegisterOnUpdateEvents() { container.addUpdateEventHandler(updateEventHandlerMock); assertTrue(container.getOnUpdateEventRouter().contains( updateEventHandlerMock)); } @Test public void shouldRegisterOnDeleteEvents() { container.addDeleteEventHandler(deleteEventHandlerMock); assertTrue(container.getOnDeleteEventRouter().contains( deleteEventHandlerMock)); } @Test public void shouldRegisterOnCommitEvents() { container.addCommitEventHandler(commitEventHandlerMock); assertTrue(container.getOnCommitEventRouter().contains( commitEventHandlerMock)); } @Test(expected = IllegalStateException.class) public void shouldFailWithoutTransactionOnAddRow() { container.addRow(); } @Test public void shouldReturnContainerType() { container.setVaadinContainer(vaadinContainerMock); when(vaadinContainerMock.getType("test")).thenAnswer( new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { return Integer.class; } }); Class<?> type = container.getType("test"); assertTrue(type.isAssignableFrom(Integer.class)); } @Test public void shouldNotRemoveDurableFilters() { container.setVaadinContainer(vaadinContainerMock); Filter equalFilter1 = new Equal("a", "b"); Filter equalFilter2 = new Equal("c", "d", true); Filter equalFilter3 = new Equal("e", "f"); container.addFilters(asList(equalFilter1, equalFilter2, equalFilter3)); container.removeAllFilters(); List<Filter> filterList = container.getFilterList(); assertThat(filterList.size(), is(1)); assertThat(filterList.contains(equalFilter2), is(true)); verify((Filterable) vaadinContainerMock, times(2)) .replaceContainerFilter( any(com.vaadin.data.Container.Filter.class)); } @Test public void shouldReplaceFilters() { container.setVaadinContainer(vaadinContainerMock); List<Filter> newFilters = asList((Filter) new Equal("MYCOL", "MYVALUE")); com.vaadin.data.Container.Filter newVaadinFilter = container .buildVaadinFilter(new All(newFilters)); container.replaceFilters(newFilters, true); verify((Filterable) vaadinContainerMock).replaceContainerFilter( newVaadinFilter); } @Test public void shouldRemoveAllFilters() { container.setVaadinContainer(vaadinContainerMock); Filter equalFilter1 = new Equal("a", "b"); Filter equalFilter2 = new Equal("c", "d", true); Filter equalFilter3 = new Equal("e", "f"); container.addFilters(asList(equalFilter1, equalFilter2, equalFilter3)); container.removeAllFilters(true); List<Filter> filterList = container.getFilterList(); assertThat(filterList.size(), is(0)); verify((Filterable) vaadinContainerMock).removeAllContainerFilters(); } @Test public void shouldAddEqualFilter() { shouldAddFilterType(new Equal("ID", 1), Compare.Equal.class); } @Test public void shouldAddGreaterFilter() { shouldAddFilterType(new Greater("ID", 1, false), Compare.Greater.class); } @Test public void shouldAddGreaterOrEqualFilter() { shouldAddFilterType(new Greater("ID", 1, true), Compare.GreaterOrEqual.class); } @Test public void shouldAddLessFilter() { shouldAddFilterType(new Less("ID", 1, false), Compare.Less.class); } @Test public void shouldAddLessOrEqualFilter() { shouldAddFilterType(new Less("ID", 1, true), Compare.LessOrEqual.class); } @Test public void shouldAddNothingFilter() { shouldAddFilterType(new Nothing(), NothingFilter.class); } @Test public void shouldAddIsNullFilter() { com.vaadin.data.util.filter.IsNull isNull = shouldAddFilterType(new IsNull("ID"), com.vaadin.data.util.filter.IsNull.class); assertThat(isNull.getPropertyId(), is((Object)"ID")); } @Test public void shouldAddWildcardFilter() { Like likeFilter = shouldAddFilterType(new Wildcard("ID", "Te*t", false), Like.class); assertThat(likeFilter.getValue(), is("Te%t")); } @Test public void shouldAddAnyFilter() { shouldAddFilterType( new Any(Arrays.asList(new Filter[] { new Contains("NAME", "abcdef", false), new Equal("ID", 1) })), Or.class); } @Test public void shouldAddNotFilterWithAllSubfilter() { container.setVaadinContainer(vaadinContainerMock); Not filter = new Not(Arrays.asList(new Filter[] { new Contains("NAME", "abcdef", false), new Equal("ID", 1) })); container.addFilters(asList((Filter) filter)); verify((Filterable) vaadinContainerMock).replaceContainerFilter( filterCaptor.capture()); assertThat(container.getFilterList(), hasItems((Filter) filter)); assertThat(filterCaptor.getValue(), instanceOf(com.vaadin.data.util.filter.Not.class)); And subfilter = (And) ((com.vaadin.data.util.filter.Not) filterCaptor .getValue()).getFilter(); Iterator<com.vaadin.data.Container.Filter> andIterator = subfilter .getFilters().iterator(); assertThat( andIterator.next(), anyOf(instanceOf(AdvancedStringFilter.class), instanceOf(Like.class))); assertThat(andIterator.next(), instanceOf(com.vaadin.data.util.filter.Compare.Equal.class)); } @Test(expected = IllegalArgumentException.class) public void shouldNotAddFilter() { container.setVaadinContainer(vaadinContainerMock); container.addFilters(asList((Filter) new Filter(false) { private static final long serialVersionUID = 1L; // })); } @Test public void shouldAddNotFilterWithSingleSubfilter() { container.setVaadinContainer(vaadinContainerMock); Filter filter = new Not(Arrays.asList(new Filter[] { new Contains( "NAME", "abc%def", false) })); container.addFilters(asList(filter)); verify((Filterable) vaadinContainerMock).replaceContainerFilter( filterCaptor.capture()); assertThat(container.getFilterList(), hasItems((Filter) filter)); assertThat(filterCaptor.getValue(), instanceOf(com.vaadin.data.util.filter.Not.class)); assertThat( ((com.vaadin.data.util.filter.Not) filterCaptor.getValue()) .getFilter(), anyOf(instanceOf(AdvancedStringFilter.class), instanceOf(Like.class))); } @Test public void shouldAddAllFilter() { container.setVaadinContainer(vaadinContainerMock); shouldAddFilterType( new All(Arrays.asList(new Filter[] { new Contains("NAME", "abc%def", false), new Equal("ID", 1) })), And.class); } @Test public void shouldNotAddEmptyAllFilter() { shouldNotAddFilterType(new All(new ArrayList<Filter>())); } @Test public void shouldNotAddEmptyAnyFilter() { shouldNotAddFilterType(new Any(new ArrayList<Filter>())); } @Test public void shouldNotAddEmptyNotFilter() { shouldNotAddFilterType(new Not(null)); } @Test public void shouldGetCustomNumberFormat() { container.setVaadinContainer(vaadinContainerMock); when(vaadinContainerMock.getType(anyString())).thenAnswer( new Answer<Class<BigDecimal>>() { @Override public Class<BigDecimal> answer(InvocationOnMock invocation) throws Throwable { return BigDecimal.class; } }); when(displayPatternMock.get(anyString())).thenReturn("#,##0.00"); NumberFormat format = (NumberFormat) container.getFormat("testCol"); assertThat(format.format(123123l), is("123,123.00")); } @Test public void shouldGetCustomDateFormat() { container.setVaadinContainer(vaadinContainerMock); when(vaadinContainerMock.getType(anyString())).thenAnswer( new Answer<Class<Date>>() { @Override public Class<Date> answer(InvocationOnMock invocation) throws Throwable { return Date.class; } }); when(displayPatternMock.get(anyString())) .thenReturn("dd.MM.yyyy HH:mm"); DateFormat format = (DateFormat) container.getFormat("testCol"); assertThat(format.format(new GregorianCalendar(2013, 5, 25, 8, 31) .getTime()), is("25.06.2013 08:31")); } @Test public void shouldGetNullFormatByWrongType() { container.setVaadinContainer(vaadinContainerMock); when(vaadinContainerMock.getType(anyString())).thenAnswer( new Answer<Class<String>>() { @Override public Class<String> answer(InvocationOnMock invocation) throws Throwable { return String.class; } }); when(displayPatternMock.get(anyString())).thenReturn("#,##0.00"); NumberFormat format = (NumberFormat) container.getFormat("testCol"); assertThat(format, nullValue()); } private void shouldNotAddFilterType(Filter filter) { container.setVaadinContainer(vaadinContainerMock); container.addFilters(asList(filter)); verify((Filterable) vaadinContainerMock, never()).addContainerFilter( any(com.vaadin.data.Container.Filter.class)); } @SuppressWarnings("unchecked") protected <T extends com.vaadin.data.Container.Filter> T shouldAddFilterType(Filter filter, Class<T> vaadinClass) { container.setVaadinContainer(vaadinContainerMock); container.addFilters(asList(filter)); verify((Filterable) vaadinContainerMock).replaceContainerFilter( filterCaptor.capture()); assertThat(container.getFilterList(), hasItems((Filter) filter)); com.vaadin.data.Container.Filter vaadinFilter = filterCaptor.getValue(); assertThat(vaadinFilter, instanceOf(vaadinClass)); return (T) vaadinFilter; } public static void returnFollowingColumnType(DataContainer containerMock, String columnName, final Class<?> columnType) { when(containerMock.getType(columnName)).thenAnswer( new Answer<Class<Object>>() { @SuppressWarnings("unchecked") @Override public Class<Object> answer(InvocationOnMock invocation) throws Throwable { return (Class<Object>) columnType; } }); } @Test public void addFilterShouldApplyNothingFilterIfTheNewFilterlistOnlyContainsDurableFilters() { container.setVaadinContainer(vaadinContainerMock); container.setFilterPolicy(FilterPolicy.NOTHING_AT_ALL); Filter equalFilter1 = new Equal("a", "b", true); container.addFilters(asList(equalFilter1)); verify((Filterable) vaadinContainerMock).replaceContainerFilter( isA(NothingFilter.class)); } @Test public void replaceFilterShouldApplyNothingFilterIfTheNewFilterlistIsDurable() { container.setVaadinContainer(vaadinContainerMock); container.setFilterPolicy(FilterPolicy.NOTHING_AT_ALL); Filter equalFilter1 = new Equal("a", "b", true); container.replaceFilters(asList(equalFilter1), true); verify((Filterable) vaadinContainerMock).replaceContainerFilter( isA(NothingFilter.class)); } @Test public void replaceFilterShouldApplyNothingFilterIfTheNewFilterlistIsEmpty() { container.setVaadinContainer(vaadinContainerMock); container.setFilterPolicy(FilterPolicy.NOTHING_AT_ALL); Filter nonDurableFilter = new Equal("a", "b", false); container.addFilters(asList(nonDurableFilter)); container.replaceFilters(new LinkedList<Filter>(), true); verify((Filterable) vaadinContainerMock).replaceContainerFilter( isA(Compare.Equal.class)); verify((Filterable) vaadinContainerMock).replaceContainerFilter( isA(NothingFilter.class)); } @Test public void replaceFilterShouldApplyNothingFilterOnTimeoutException() { container.setVaadinContainer(vaadinContainerMock); Filter nonDurableFilter = new Equal("a", "b", false); container.addFilters(asList(nonDurableFilter)); doThrow(new RuntimeException(new SQLTimeoutException("Test"))).when( ((Filterable) vaadinContainerMock)).removeAllContainerFilters(); try { container.replaceFilters(new LinkedList<Filter>(), true); fail("Should throw timeout exception"); } catch (RuntimeException e) { assertThat(container.getFilterList(), is(asList((Filter) new Nothing()))); } } @Test public void addFilterShouldReApplyExistingDurableFiltersIfANonDurableFilterIsAdded() { container.setVaadinContainer(vaadinContainerMock); container.setFilterPolicy(FilterPolicy.NOTHING_AT_ALL); Filter durableFilter = new Equal("a", "b", true); Filter nonDurableFilter = new Equal("a", "b", false); container.addFilters(asList(durableFilter)); container.addFilters(asList(nonDurableFilter)); verify((Filterable) vaadinContainerMock, times(2)) .replaceContainerFilter(filterCaptor.capture()); assertThat(filterCaptor.getAllValues().get(0), instanceOf(NothingFilter.class)); com.vaadin.data.Container.Filter allFilter = filterCaptor .getAllValues().get(1); assertThat(allFilter, instanceOf(And.class)); Collection<com.vaadin.data.Container.Filter> subFilters = ((And) allFilter) .getFilters(); assertThat(subFilters.size(), is(2)); } @Test public void shouldCallExportCallbackWithExportSettings() { container.withExportSettings(exportMock); verify(exportMock).export(); } @Test public void shouldIterateOverImmutableRowsByIds() { AbstractDataContainer containerMock = createPartialContainerMock(); when(rowIdMock1.getInternalId()).thenReturn(1); when(rowIdMock2.getInternalId()).thenReturn(2); // spy stubbing doReturn(rowIdMock1).when(containerMock).convertInternalRowId(1); doReturn(rowIdMock2).when(containerMock).convertInternalRowId(2); doReturn(rowMock1).when(containerMock).getRow(rowIdMock1, false, true); doReturn(rowMock2).when(containerMock).getRow(rowIdMock2, false, true); containerMock.eachImmutableRow(ImmutableSet.of(rowIdMock1, rowIdMock2), eachRowCallbackMock); verify(eachRowCallbackMock).doWithRow(rowMock1); verify(eachRowCallbackMock).doWithRow(rowMock2); } @Test public void shouldIterateOverImmutableRowsByIdsIgnoringMissingRows() { AbstractDataContainer containerMock = createPartialContainerMock(); when(rowIdMock1.getInternalId()).thenReturn(1); when(rowIdMock2.getInternalId()).thenReturn(2); // spy stubbing doReturn(rowIdMock1).when(containerMock).convertInternalRowId(1); doReturn(rowIdMock2).when(containerMock).convertInternalRowId(2); doReturn(rowMock1).when(containerMock).getRow(rowIdMock1, false, true); doReturn(null).when(containerMock).getRow(rowIdMock2, false, true); containerMock.eachImmutableRow(ImmutableSet.of(rowIdMock1, rowIdMock2), eachRowCallbackMock); verify(eachRowCallbackMock).doWithRow(rowMock1); verifyNoMoreInteractions(eachRowCallbackMock); } @Test public void shouldIterateOverRowsByIdsInsideATransaction() { AbstractDataContainer containerMock = createPartialContainerMock(); when(rowIdMock1.getInternalId()).thenReturn(1); when(rowIdMock2.getInternalId()).thenReturn(2); // spy stubbing doReturn(rowIdMock1).when(containerMock).convertInternalRowId(1); doReturn(rowIdMock2).when(containerMock).convertInternalRowId(2); doReturn(rowMock1).when(containerMock).getRow(rowIdMock1, true, false); doReturn(rowMock2).when(containerMock).getRow(rowIdMock2, true, false); containerMock.eachRow(ImmutableSet.of(rowIdMock1, rowIdMock2), eachRowCallbackMock); InOrder inOrder = inOrder(containerMock, eachRowCallbackMock); inOrder.verify(containerMock).commit(); inOrder.verify(eachRowCallbackMock).doWithRow(rowMock1); inOrder.verify(eachRowCallbackMock).doWithRow(rowMock2); inOrder.verify(containerMock).commit(); } @Test public void shouldIterateOverRowsByIdsIgnoringMissingRows() { AbstractDataContainer containerMock = createPartialContainerMock(); when(rowIdMock1.getInternalId()).thenReturn(1); when(rowIdMock2.getInternalId()).thenReturn(2); // spy stubbing doReturn(rowIdMock1).when(containerMock).convertInternalRowId(1); doReturn(rowIdMock2).when(containerMock).convertInternalRowId(2); doReturn(rowMock1).when(containerMock).getRow(rowIdMock1, true, false); doReturn(null).when(containerMock).getRow(rowIdMock2, true, false); containerMock.eachRow(ImmutableSet.of(rowIdMock1, rowIdMock2), eachRowCallbackMock); InOrder inOrder = inOrder(containerMock, eachRowCallbackMock); inOrder.verify(containerMock).commit(); inOrder.verify(eachRowCallbackMock).doWithRow(rowMock1); inOrder.verify(containerMock).commit(); } private AbstractDataContainer createPartialContainerMock() { AbstractDataContainer containerMock = spy(new AbstractDataContainer(eventBusMock, null, null, null) { @Override protected Container createVaadinContainer() { return null; } @Override public boolean isInsertable() { return false; } @Override public boolean isUpdateable() { return false; } @Override public boolean isDeleteable() { return false; } @Override public Class<?> getType(String name) { return null; } @Override public void rollback() { } @Override public void commit() { } @Override public List<String> getPrimaryKeyColumns() { return null; } @Override public List<String> getColumns() { return null; } @Override public ContainerRow convertItemToRow(Item item, boolean transactional, boolean immutable) { return null; } @Override public ContainerRowId convertInternalRowId(Object internalId) { return null; } @Override public void refresh() { } @Override public ContainerClob getCLob(ContainerRowId rowId, String columnName) { return null; } @Override public boolean isCLob(String columnName) { return false; } @Override public ContainerBlob getBLob(ContainerRowId rowId, String columnName) { return null; } @Override public boolean isBLobEmpty(ContainerRowId rowId, String columnName) { return false; } @Override public boolean isBLob(String columnName) { return false; } }); containerMock.setVaadinContainer(vaadinContainerMock); return containerMock; } }