/*
* 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.form;
import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyListOf;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doThrow;
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 java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.NoSuchElementException;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import com.vaadin.ui.UI;
import de.unioninvestment.eai.portal.portlet.crud.config.ApplyFiltersConfig;
import de.unioninvestment.eai.portal.portlet.crud.config.ContainsFilterConfig;
import de.unioninvestment.eai.portal.portlet.crud.config.CustomFilterConfig;
import de.unioninvestment.eai.portal.portlet.crud.config.EqualsFilterConfig;
import de.unioninvestment.eai.portal.portlet.crud.config.FilterConfig;
import de.unioninvestment.eai.portal.portlet.crud.config.FormActionConfig;
import de.unioninvestment.eai.portal.portlet.crud.config.GreaterOrEqualFilterConfig;
import de.unioninvestment.eai.portal.portlet.crud.config.IncludeFilterConfig;
import de.unioninvestment.eai.portal.portlet.crud.config.SQLFilterConfig;
import de.unioninvestment.eai.portal.portlet.crud.config.SearchConfig;
import de.unioninvestment.eai.portal.portlet.crud.config.SearchTableConfig;
import de.unioninvestment.eai.portal.portlet.crud.config.SearchTablesConfig;
import de.unioninvestment.eai.portal.portlet.crud.config.TableConfig;
import de.unioninvestment.eai.portal.portlet.crud.domain.exception.BusinessException;
import de.unioninvestment.eai.portal.portlet.crud.domain.exception.TimeoutException;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.Component;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.ContainerRow;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.DataContainer;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.DataContainer.FilterPolicy;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.Form;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.FormAction;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.FormActions;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.FormFields;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.MultiOptionListFormField;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.OptionListFormField;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.Page;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.Portlet;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.Tab;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.Table;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.Tabs;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.All;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.Any;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.Contains;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.CustomFilter;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.CustomFilterFactory;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.CustomFilterMatcher;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.EndsWith;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.Equal;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.Filter;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.Greater;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.Less;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.Not;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.Nothing;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.RegExpFilter;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.SQLFilter;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.SQLWhereFactory;
import de.unioninvestment.eai.portal.portlet.crud.domain.model.filter.StartsWith;
import de.unioninvestment.eai.portal.portlet.crud.domain.support.InitializingUI;
import static de.unioninvestment.eai.portal.portlet.crud.domain.form.SearchFormTestUtility.*;
public class SearchFormActionTest {
@SuppressWarnings("serial")
static abstract class UIMock extends UI implements InitializingUI {
}
private SearchFormAction searchAction;
private FormFields formFields;
@Mock
private Form formMock;
@Mock
private Page pageMock;
@Mock
private Table tableMock;
@Mock
private DataContainer dbContainerMock;
@Mock
private DataContainer dbContainerMock2;
@Mock
private FormActionConfig formActionConfigMock;
@Mock
private FormActionConfig formActionConfigMock2;
@Mock
private OptionListFormField selectionFormField;
@Mock
private Table table2Mock;
@Mock
private Form form2Mock;
@Mock
private Tabs tabsMock;
@Mock
private Tab tab2Mock;
@Mock
private Tab tab1Mock;
@Mock
private Table table3Mock;
private ApplyFiltersConfig filtersConfig;
@Mock
private Portlet portletMock;
@Mock
private TableConfig tableConfigMock;
@Mock
private TableConfig table2ConfigMock;
@Mock
private SQLWhereFactory sqlWhereFactoryMock;
@Mock
private Form formMock2;
@Mock
private SearchConfig searchConfigMock;
@Mock
private SearchConfig searchConfigMock2;
@Mock
private ApplyFiltersConfig applyFiltersMock;
@Mock
private ApplyFiltersConfig applyFiltersMock2;
@Mock
private SQLFilterConfig sqlFilterConfigMock;
@Mock
private FormFields formFieldsMock;
@Mock
private MultiOptionListFormField multiSelectFormFieldMock;
@Mock
private CustomFilterFactory customFilterFactoryMock;
@Mock
private UIMock uiMock;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
searchAction = new SearchFormAction(formActionConfigMock, portletMock);
searchAction.setWhereFactory(sqlWhereFactoryMock);
when(selectionFormField.getName()).thenReturn("selection1");
when(selectionFormField.getValue()).thenReturn("value1");
when(tableMock.getId()).thenReturn("table");
formFields = new FormFields(createFormField("field1", "title1",
"prompt1", "filterValue1"), selectionFormField);
when(formMock.getFields()).thenReturn(formFields);
// register application with thread
UI.setCurrent(uiMock);
when(uiMock.getLocale()).thenReturn(Locale.GERMANY);
}
@After
public void tearDown() {
// deregister from thread
UI.setCurrent(null);
}
@Test
public void shouldIndicateExisitingWhereFilter() {
when(formActionConfigMock.getSearch()).thenReturn(searchConfigMock);
when(searchConfigMock.getApplyFilters()).thenReturn(applyFiltersMock);
ArrayList<FilterConfig> filters = new ArrayList<FilterConfig>();
filters.add(sqlFilterConfigMock);
when(applyFiltersMock.getFilters()).thenReturn(filters);
assertThat(searchAction.whereFilterExists(), is(true));
}
@Test
public void shouldReturnFalseIfNoSQLFilter() {
when(formActionConfigMock.getSearch()).thenReturn(searchConfigMock);
when(searchConfigMock.getApplyFilters()).thenReturn(applyFiltersMock);
ArrayList<FilterConfig> filters = new ArrayList<FilterConfig>();
when(applyFiltersMock.getFilters()).thenReturn(filters);
assertThat(searchAction.whereFilterExists(), is(false));
}
@Test
public void shouldApplyDefaultStartsWithFilterOnTextColumn() {
formFields = new FormFields(createFormField("field1", "title1",
"prompt1", "filterValue1"));
when(formMock.getFields()).thenReturn(formFields);
stubContainerColumnType("field1", String.class);
mockPageWithFormAndTable();
searchAction.execute(formMock);
verify(dbContainerMock)
.replaceFilters(
asList((Filter) new StartsWith("field1",
"filterValue1", false)), false, true);
}
@Test
public void shouldApplyDefaultStartsWithFilterOnMultipleColumnsWrappingMultipleFiltersByAllFilter() {
formFields = new FormFields(createFormField("field1", "title1",
"prompt1", "filterValue1"), createFormField("field2", "title2",
"prompt2", "filterValue2"));
when(formMock.getFields()).thenReturn(formFields);
stubContainerColumnType("field1", String.class);
stubContainerColumnType("field2", String.class);
mockPageWithFormAndTable();
searchAction.execute(formMock);
verify(dbContainerMock)
.replaceFilters(
asList((Filter) new StartsWith("field1",
"filterValue1", false), new StartsWith(
"field2", "filterValue2", false)), false, true);
}
private void stubContainerColumnType(String columnName, final Class<?> type) {
when(dbContainerMock.getType(columnName)).thenAnswer(
new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation)
throws Throwable {
return type;
}
});
}
@Test
public void shouldNotApplyFilterOnMissingColumn() {
mockPageWithFormAndTable();
formFields = new FormFields(createFormField("field1", "title1",
"prompt1", "filterValue1"));
when(formMock.getFields()).thenReturn(formFields);
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(new ArrayList<Filter>(), false, true);
}
@Test
public void shouldCallReplaceWithTimeout() {
searchAction.setTimeout(42);
mockPageWithFormAndTable();
formFields = new FormFields(createFormField("field1", "title1",
"prompt1", "filterValue1"));
when(formMock.getFields()).thenReturn(formFields);
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(new ArrayList<Filter>(), false,
true, 42);
}
@Test(expected = BusinessException.class)
@SuppressWarnings({ "unchecked", "rawtypes" })
public void shouldCallReplaceWithTimeoutOnSQLTimeout() {
searchAction.setTimeout(42);
mockPageWithFormAndTable();
formFields = new FormFields(createFormField("field1", "title1",
"prompt1", "filterValue1"));
when(formMock.getFields()).thenReturn(formFields);
doThrow(new TimeoutException("portlet.crud.warn.searchQueryTimeout"))
.when(dbContainerMock).replaceFilters(new ArrayList<Filter>(),
false, true, 42);
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(new ArrayList<Filter>(), false,
true, 42);
ArgumentCaptor<List> filterListArgumentCaptor = ArgumentCaptor
.forClass(List.class);
verify(dbContainerMock).replaceFilters(
filterListArgumentCaptor.capture(), false);
List filterList = filterListArgumentCaptor.getValue();
assertEquals(1, filterList.size());
assertTrue(filterList.iterator().next() instanceof Nothing);
}
@Test
public void shouldNotApplyFilterWithExplicitOtherTable() {
prepareSimpleFormFieldToStringColumnSearch("filterValue", String.class);
createExplicitFilterConfiguration();
GreaterOrEqualFilterConfig filter = createGreaterOrEqualsFilter(
"field1", "column1");
filter.setTable("table2");
filtersConfig.getFilters().add(filter);
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(new ArrayList<Filter>(), false, true);
}
@Test
public void shouldNotApplyFilterOnEmptyField() {
mockPageWithFormAndTable();
formFields = new FormFields(createFormField("field1", "title1",
"prompt1", ""));
when(formMock.getFields()).thenReturn(formFields);
stubContainerColumnType("field1", String.class);
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(new ArrayList<Filter>(), false, true);
}
@Test
public void shouldApplyDefaultEqualFilterForSelectionFields() {
mockPageWithFormAndTable();
formFields = new FormFields(createSelectFormField("field1", "title1",
"prompt1", "filterValue1",
Collections.singletonMap("filterValue1", "Filterwert 1")));
when(formMock.getFields()).thenReturn(formFields);
stubContainerColumnType("field1", String.class);
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(
asList((Filter) new Equal("field1", "filterValue1")), false, true);
}
@Test
public void shouldApplyDefaultEqualFiltersForDateField() {
mockPageWithFormAndTable();
formFields = new FormFields(createDateFormField("field1", "title1",
"prompt1", "dd.MM.yyyy", "20.05.2011"));
when(formMock.getFields()).thenReturn(formFields);
stubContainerColumnType("field1", Timestamp.class);
searchAction.execute(formMock);
Greater beginDateFilter = new Greater("field1", new GregorianCalendar(
2011, 04, 20).getTime(), true);
Less endDateFilter = new Less("field1", timestamp(2011, 4, 21), false);
verify(dbContainerMock).replaceFilters(
asList((Filter) new All(Arrays.asList((Filter) beginDateFilter,
endDateFilter))), false, true);
}
private Timestamp timestamp(int i, int j, int k) {
return new Timestamp(new GregorianCalendar(i, j, k).getTimeInMillis());
}
@SuppressWarnings("unchecked")
@Test
public void shouldNotFilterOnInitializationIfTableHasANothingPolicy() {
mockPageWithFormAndTable();
formFields = new FormFields(createFormField("field1", "title1",
"prompt1", "1.0"));
when(formMock.getFields()).thenReturn(formFields);
stubContainerColumnType("field1", BigDecimal.class);
when(uiMock.isInitializing()).thenReturn(true);
when(dbContainerMock.getFilterPolicy())
.thenReturn(FilterPolicy.NOTHING);
searchAction.execute(formMock);
verify(dbContainerMock, never()).replaceFilters(any(List.class),
eq(false));
}
@SuppressWarnings("unchecked")
@Test
public void shouldNotFilterOnInitializationIfTableHasANothingAtAllPolicy() {
mockPageWithFormAndTable();
formFields = new FormFields(createFormField("field1", "title1",
"prompt1", "1.0"));
when(formMock.getFields()).thenReturn(formFields);
stubContainerColumnType("field1", BigDecimal.class);
when(uiMock.isInitializing()).thenReturn(true);
when(dbContainerMock.getFilterPolicy()).thenReturn(
FilterPolicy.NOTHING_AT_ALL);
searchAction.execute(formMock);
verify(dbContainerMock, never()).replaceFilters(any(List.class),
eq(false));
}
@Test
public void shouldApplyDefaultEqualFilterForCheckboxFields() {
mockPageWithFormAndTable();
formFields = new FormFields(createCheckboxFormField("field1", "title1",
"prompt1", "filterValue1"));
when(formMock.getFields()).thenReturn(formFields);
stubContainerColumnType("field1", String.class);
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(
asList((Filter) new Equal("field1", "filterValue1")), false, true);
}
@Test
public void shouldApplyDefaultEqualFilterToNumberField() {
mockPageWithFormAndTable();
formFields = new FormFields(createFormField("field1", "title1",
"prompt1", "1,0"));
when(formMock.getFields()).thenReturn(formFields);
stubContainerColumnType("field1", BigDecimal.class);
when(uiMock.getLocale()).thenReturn(Locale.GERMANY);
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(
asList((Filter) new Equal("field1", new BigDecimal("1"))),
false, true);
}
@Test
public void shouldApplyConfiguredEqualFilter() {
verifyFilterByConfiguration(createEqualsFilter("field1", "column1"),
new Equal("column1", "filterValue1"));
}
@Test
public void shouldApplyConfiguredEqualFilterToNumberField() {
verifyFilterByConfiguration(createEqualsFilter("field1", "column1"),
new Equal("column1", 1.0), "1,0", Double.class);
}
@Test
@Ignore
public void shouldParsingNumberFieldWithWrongLocal() {
verifyFilterByConfiguration(createEqualsFilter("field1", "column1"),
new Equal("column1", 1.0), "1.0", Double.class);
}
@Test
public void shouldApplyConfiguredStartsWithFilter() {
verifyFilterByConfiguration(
createStartsWithFilter("field1", "column1", true),
new StartsWith("column1", "filterValue1", true));
}
@Test
public void shouldApplyConfiguredContainsFilter() {
verifyFilterByConfiguration(
createContainsFilter("field1", "column1", true), new Contains(
"column1", "filterValue1", true));
}
@Test
public void shouldApplyConfiguredStartsWithFilterAsCaseInsensitive() {
verifyFilterByConfiguration(
createStartsWithFilter("field1", "column1", false),
new StartsWith("column1", "filterValue1", false));
}
@Test
public void shouldApplyConfiguredCustomFilter() {
searchAction.setCustomFilterFactory(customFilterFactoryMock);
CustomFilterMatcher matcher = new CustomFilterMatcher() {
@Override
public boolean matches(ContainerRow row) {
return true;
}
};
CustomFilterConfig customFilterConfig = createCustomFilter();
CustomFilter customFilter = new CustomFilter(matcher, false);
when(customFilterFactoryMock.createCustomFilter(customFilterConfig))
.thenReturn(customFilter);
verifyFilterByConfiguration(customFilterConfig, customFilter);
}
@Test
public void shouldApplyConfiguredEndsWithFilter() {
verifyFilterByConfiguration(
createEndsWithFilter("field1", "column1", true), new EndsWith(
"column1", "filterValue1", true));
}
@Test
public void shouldApplyConfiguredRegexpFilter() {
verifyFilterByConfiguration(
createRegexpFilter("field1", "column1", "i"), new RegExpFilter(
"column1", "filterValue1", "i"));
}
@Test
public void shouldApplyConfiguredGreaterFilter() {
verifyFilterByConfiguration(createGreaterFilter("field1", "column1"),
new Greater("column1", "filterValue1", false));
}
@Test
public void shouldApplyConfiguredGreaterOrEqualsFilterWithDateField() {
verifyDateFilterByConfiguration(
createGreaterOrEqualsFilter("field1", "column1"), new Greater(
"column1",
new GregorianCalendar(2011, 4, 20).getTime(), true),
"20.05.2011", java.sql.Date.class);
}
@Test
public void shouldApplyConfiguredGreaterFilterWithDateField() {
verifyDateFilterByConfiguration(
createGreaterFilter("field1", "column1"), new Greater(
"column1",
new GregorianCalendar(2011, 4, 21).getTime(), true),
"20.05.2011", java.sql.Date.class);
}
@Test
public void shouldApplyConfiguredLessFilterWithDateField() {
verifyDateFilterByConfiguration(
createLessFilter("field1", "column1"),
new Less("column1", new GregorianCalendar(2011, 4, 20)
.getTime(), false), "20.05.2011", java.sql.Date.class);
}
@Test
public void shouldApplyConfiguredLessOrEqualFilterWithDateField() {
verifyDateFilterByConfiguration(
createLessOrEqualsFilter("field1", "column1"), new Less(
"column1",
new GregorianCalendar(2011, 4, 21).getTime(), false),
"20.05.2011", java.sql.Date.class);
}
@Test
public void shouldApplyConfiguredGreaterOrEqualFilter() {
verifyFilterByConfiguration(
createGreaterOrEqualsFilter("field1", "column1"), new Greater(
"column1", "filterValue1", true));
}
@Test
public void shouldApplyConfiguredLessOrEqualFilter() {
verifyFilterByConfiguration(
createLessOrEqualsFilter("field1", "column1"), new Less(
"column1", "filterValue1", true));
}
@Test
public void shouldApplyConfiguredLessFilter() {
verifyFilterByConfiguration(createLessFilter("field1", "column1"),
new Less("column1", "filterValue1", false));
}
private void verifyFilterByConfiguration(FilterConfig filterConfig,
Filter expectedFilter) {
verifyFilterByConfiguration(filterConfig, expectedFilter,
"filterValue1", String.class);
}
private void verifyFilterByConfiguration(FilterConfig filterConfig,
Filter expectedFilter, String fieldValue, Class<?> columnDataType) {
prepareSimpleFormFieldToStringColumnSearch(fieldValue, columnDataType);
createExplicitFilterConfiguration();
filtersConfig.getFilters().add(filterConfig);
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(asList((Filter) expectedFilter),
false, true);
}
private void verifyDateFilterByConfiguration(FilterConfig filterConfig,
Filter expectedFilter, String fieldValue, Class<?> columnDataType) {
mockPageWithFormAndTable();
formFields = new FormFields(createDateFormField("field1", "title1",
"prompt1", "dd.MM.yyyy", fieldValue));
when(formMock.getFields()).thenReturn(formFields);
stubContainerColumnType("column1", columnDataType);
createExplicitFilterConfiguration();
filtersConfig.getFilters().add(filterConfig);
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(asList((Filter) expectedFilter),
false, true);
}
@Test
public void shouldApplyAnyFilterWithSubfilters() {
prepareSimpleFormFieldToStringColumnSearch("filterValue1", String.class);
createExplicitFilterConfiguration();
filtersConfig.getFilters().add(
createAnyFilter(
createStartsWithFilter("field1", "column1", true),
createEndsWithFilter("field1", "column1", true)));
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(
asList((Filter) new Any(Arrays.asList((Filter) new StartsWith(
"column1", "filterValue1", true), new EndsWith(
"column1", "filterValue1", true)))), false, true);
}
@Test
public void shouldNotApplyEmptyAnyFilter() {
prepareSimpleFormFieldToStringColumnSearch("", String.class);
createExplicitFilterConfiguration();
filtersConfig.getFilters().add(
createAnyFilter(
createStartsWithFilter("field1", "column1", true),
createEndsWithFilter("field1", "column1", true)));
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(new LinkedList<Filter>(), false, true);
}
@Test
public void shouldNotApplyEmptyAllFilter() {
prepareSimpleFormFieldToStringColumnSearch("", String.class);
createExplicitFilterConfiguration();
filtersConfig.getFilters().add(
createAllFilter(
createStartsWithFilter("field1", "column1", true),
createEndsWithFilter("field1", "column1", true)));
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(new LinkedList<Filter>(), false, true);
}
@Test
public void shouldApplySqlWhereFilter() {
prepareSimpleFormFieldToStringColumnSearch("filterValue1", String.class);
createExplicitFilterConfiguration();
filtersConfig
.getFilters()
.add(createSqlWhereFilter("column1",
"in (select column1 from bla where x = $field.CDATE.value)"));
SQLFilter filter = new SQLFilter("column1",
"in (select column1 from bla where x = ?)",
Arrays.asList((Object) "Test"));
when(
sqlWhereFactoryMock
.createFilter("column1",
"in (select column1 from bla where x = $field.CDATE.value)"))
.thenReturn(filter);
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(asList((Filter) filter), false, true);
}
@Test
public void shouldApplyNotFilterWithSubfiltersAsEncapsulatedByAll() {
prepareSimpleFormFieldToStringColumnSearch("filterValue1", String.class);
createExplicitFilterConfiguration();
filtersConfig.getFilters().add(
createNotFilter(
createStartsWithFilter("field1", "column1", true),
createEndsWithFilter("field1", "column1", true)));
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(
asList((Filter) new Not(Arrays.asList((Filter) new StartsWith(
"column1", "filterValue1", true), new EndsWith(
"column1", "filterValue1", true)))), false, true);
}
@Test
public void shouldNotApplyEmptyNotFilter() {
prepareSimpleFormFieldToStringColumnSearch("", String.class);
createExplicitFilterConfiguration();
filtersConfig.getFilters().add(
createNotFilter(
createStartsWithFilter("field1", "column1", true),
createEndsWithFilter("field1", "column1", true)));
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(new LinkedList<Filter>(), false, true);
}
@Test
public void shouldApplyAllFilterWithSubfilters() {
prepareSimpleFormFieldToStringColumnSearch("filterValue1", String.class);
createExplicitFilterConfiguration();
filtersConfig.getFilters().add(
createAllFilter(
createStartsWithFilter("field1", "column1", true),
createEndsWithFilter("field1", "column1", true)));
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(
asList((Filter) new All(Arrays.asList((Filter) new StartsWith(
"column1", "filterValue1", true), new EndsWith(
"column1", "filterValue1", true)))), false, true);
}
@Test(expected = BusinessException.class)
public void shouldThrowBusinessExceptionWhenRequiresFilterAndFormHasNoFilter() {
when(formActionConfigMock.getSearch()).thenReturn(searchConfigMock);
when(searchConfigMock.isRequiresFilter()).thenReturn(true);
searchAction = new SearchFormAction(formActionConfigMock, portletMock);
when(formMock.hasFilter()).thenReturn(false);
searchAction.execute(formMock);
}
@Test
public void shouldSearchWhenRequiresFilterAndFormHasFilter() {
when(formActionConfigMock.getSearch()).thenReturn(searchConfigMock);
when(searchConfigMock.isRequiresFilter()).thenReturn(true);
searchAction = new SearchFormAction(formActionConfigMock, portletMock);
when(formMock.hasFilter()).thenReturn(true);
mockPageWithFormAndTable();
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(anyListOf(Filter.class),
anyBoolean(), anyBoolean());
}
@Test
public void shouldSearchWhenNotRequiresFilterAndFormHasNoFilter() {
when(formActionConfigMock.getSearch()).thenReturn(searchConfigMock);
when(searchConfigMock.isRequiresFilter()).thenReturn(false);
searchAction = new SearchFormAction(formActionConfigMock, portletMock);
when(formMock.hasFilter()).thenReturn(false);
mockPageWithFormAndTable();
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(anyListOf(Filter.class),
anyBoolean(), anyBoolean());
}
@Test(expected = NoSuchElementException.class)
public void shouldThrowExceptionOnUnkownFormField() {
prepareSimpleFormFieldToStringColumnSearch("filterValue1", String.class);
createExplicitFilterConfiguration();
filtersConfig.getFilters().add(
createEqualsFilter("unknownField", "column1"));
searchAction.execute(formMock);
}
private void prepareSimpleFormFieldToStringColumnSearch(String fieldValue,
Class<?> columnDataType) {
mockPageWithFormAndTable();
formFields = new FormFields(createFormField("field1", "title1",
"prompt1", fieldValue));
when(formMock.getFields()).thenReturn(formFields);
stubContainerColumnType("column1", columnDataType);
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionOnUnsupportedColumnType() {
mockPageWithFormAndTable();
formFields = new FormFields(createFormField("field1", "title1",
"prompt1", "filterValue1"));
when(formMock.getFields()).thenReturn(formFields);
stubContainerColumnType("column1", Collection.class);
createExplicitFilterConfiguration();
filtersConfig.getFilters().add(createEqualsFilter("field1", "column1"));
searchAction.execute(formMock);
}
@Test
public void shouldIgnoreExplicitFilterForUnkownColumn() {
prepareSimpleFormFieldToStringColumnSearch("filterValue1", String.class);
createExplicitFilterConfiguration();
filtersConfig.getFilters().add(
createEqualsFilter("field1", "unknownColumn"));
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(new ArrayList<Filter>(), false, true);
}
private void createExplicitFilterConfiguration() {
SearchConfig search = new SearchConfig();
filtersConfig = new ApplyFiltersConfig();
search.setApplyFilters(filtersConfig);
when(formActionConfigMock.getSearch()).thenReturn(search);
}
@Test
public void shouldFindTableBelowForm() {
mockPageWithFormAndTable();
List<Table> tables = searchAction.findSearchableTables(formMock);
assertThat(tables.size(), is(1));
assertThat(tables.get(0), is(tableMock));
}
private void mockPageWithFormAndTable() {
when(formMock.getPanel()).thenReturn(pageMock);
when(pageMock.findNextElement(Component.class, formMock)).thenReturn(
tableMock);
when(tableMock.getContainer()).thenReturn(dbContainerMock);
}
@Test
public void shouldIncludeFilters() {
mockPageWith2FormsAnd2Tables();
searchAction = new SearchFormAction(formActionConfigMock2, portletMock);
searchAction.execute(formMock2);
ArrayList<Filter> filters = new ArrayList<Filter>();
filters.add(new Equal("column1", "filterValue1"));
verify(dbContainerMock2, times(1)).replaceFilters(
asList((Filter) new All(filters)), false, true);
}
private void mockPageWith2FormsAnd2Tables() {
when(formActionConfigMock.getId()).thenReturn("id1");
List<FilterConfig> filterConfigs = new ArrayList<FilterConfig>();
EqualsFilterConfig filterConfig = new EqualsFilterConfig();
filterConfig.setField("field1");
filterConfig.setColumn("column1");
filterConfigs.add(filterConfig);
when(applyFiltersMock.getFilters()).thenReturn(filterConfigs);
when(searchConfigMock.getApplyFilters()).thenReturn(applyFiltersMock);
when(formActionConfigMock.getSearch()).thenReturn(searchConfigMock);
SearchFormAction searchFormAction = new SearchFormAction(
formActionConfigMock, portletMock);
FormActionConfig formActionConfig = new FormActionConfig();
formActionConfig.setId("id1");
formActionConfig.setTitle("title1");
FormAction fAction = new FormAction(portletMock, formActionConfig,
searchFormAction, null);
FormActions formActions = new FormActions(asList(fAction));
formActions.attachToForm(formMock);
when(formMock.getActions()).thenReturn(formActions);
when(formMock.getFields()).thenReturn(formFields);
when(formMock.getPanel()).thenReturn(pageMock);
// ************
List<FilterConfig> filterConfigs2 = new ArrayList<FilterConfig>();
IncludeFilterConfig filterConfig2 = new IncludeFilterConfig();
filterConfig2.setAction(formActionConfigMock);
filterConfigs2.add(filterConfig2);
when(applyFiltersMock2.getFilters()).thenReturn(filterConfigs2);
when(searchConfigMock2.getApplyFilters()).thenReturn(applyFiltersMock2);
when(formActionConfigMock2.getSearch()).thenReturn(searchConfigMock2);
SearchFormAction searchFormAction2 = new SearchFormAction(
formActionConfigMock2, portletMock);
FormActionConfig formActionConfig2 = new FormActionConfig();
formActionConfig2.setId("id1");
formActionConfig2.setTitle("title1");
FormAction fAction2 = new FormAction(portletMock, formActionConfig2,
searchFormAction2, null);
FormActions actions2 = new FormActions(asList(fAction2));
actions2.attachToForm(formMock2);
when(formMock2.getActions()).thenReturn(actions2);
when(formMock2.getFields()).thenReturn(formFields);
when(formMock2.getPanel()).thenReturn(pageMock);
// ******
when(pageMock.findNextElement(Component.class, formMock)).thenReturn(
tableMock);
when(pageMock.findNextElement(Component.class, tableMock)).thenReturn(
formMock2);
when(pageMock.findNextElement(Component.class, formMock2)).thenReturn(
table2Mock);
when(tableMock.getContainer()).thenReturn(dbContainerMock);
when(table2Mock.getContainer()).thenReturn(dbContainerMock2);
when(portletMock.getElementById("id1")).thenReturn(fAction);
// *****
when(dbContainerMock.getType(any(String.class))).thenAnswer(
new Answer<Class<?>>() {
@Override
public Class<?> answer(InvocationOnMock invocation)
throws Throwable {
return String.class;
}
});
when(dbContainerMock2.getType(any(String.class))).thenAnswer(
new Answer<Class<?>>() {
@Override
public Class<?> answer(InvocationOnMock invocation)
throws Throwable {
return String.class;
}
});
}
@Test
public void shouldHandleMultiSelectFilter() {
mockPageWithMultiSelectFieldFormAndTable(false);
searchAction = new SearchFormAction(formActionConfigMock2, portletMock);
searchAction.execute(formMock);
verify(dbContainerMock).replaceFilters(
asList((Filter) new Any(asList((Filter) new Equal("column1",
"b"), new Equal("column1", "c"), new Equal("column1",
"a")))), false, true);
}
@Test(expected = IllegalArgumentException.class)
public void shouldFailWithInvalidMultiSelectFilterConfig() {
mockPageWithMultiSelectFieldFormAndTable(true);
searchAction = new SearchFormAction(formActionConfigMock, portletMock);
searchAction.execute(formMock);
}
private void mockPageWithMultiSelectFieldFormAndTable(
boolean invalidFilterConfig) {
when(formActionConfigMock.getId()).thenReturn("id1");
when(formMock.getPanel()).thenReturn(pageMock);
when(formMock.getFields()).thenReturn(formFieldsMock);
when(formFieldsMock.get("multiSelectField")).thenReturn(
multiSelectFormFieldMock);
when(multiSelectFormFieldMock.getName()).thenReturn("column1");
when(multiSelectFormFieldMock.getValues()).thenReturn(
new HashSet<String>(Arrays.asList("a", "b", "c")));
/*******/
if (invalidFilterConfig) {
List<FilterConfig> filterConfigs = new ArrayList<FilterConfig>();
ContainsFilterConfig filterConfig = new ContainsFilterConfig();
filterConfig.setField("multiSelectField");
filterConfig.setColumn("column1");
filterConfigs.add(filterConfig);
when(applyFiltersMock.getFilters()).thenReturn(filterConfigs);
when(searchConfigMock.getApplyFilters()).thenReturn(
applyFiltersMock);
}
/*********/
else {
formFields = new FormFields(multiSelectFormFieldMock);
when(formMock.getFields()).thenReturn(formFields);
}
when(formActionConfigMock.getSearch()).thenReturn(searchConfigMock);
// when(searchConfigMock.getApplyFilters()).thenReturn(filtersConfig);
SearchFormAction searchFormAction = new SearchFormAction(
formActionConfigMock, portletMock);
FormActionConfig formActionConfig = new FormActionConfig();
formActionConfig.setId("id1");
formActionConfig.setTitle("title1");
FormAction fAction = new FormAction(portletMock, formActionConfig,
searchFormAction, null);
FormActions formActions = new FormActions(asList(fAction));
formActions.attachToForm(formMock);
when(formMock.getActions()).thenReturn(formActions);
when(formMock.getPanel()).thenReturn(pageMock);
when(pageMock.findNextElement(Component.class, formMock)).thenReturn(
tableMock);
when(tableMock.getContainer()).thenReturn(dbContainerMock);
when(portletMock.getElementById("id1")).thenReturn(fAction);
// *****
when(dbContainerMock.getType(any(String.class))).thenAnswer(
new Answer<Class<?>>() {
@Override
public Class<?> answer(InvocationOnMock invocation)
throws Throwable {
return String.class;
}
});
}
@Test
public void shouldFindTwoTablesBelowForm() {
mockPageWithFormAndTable();
when(pageMock.findNextElement(Component.class, tableMock)).thenReturn(
table2Mock);
List<Table> tables = searchAction.findSearchableTables(formMock);
assertThat(tables.size(), is(2));
assertThat(tables.get(0), is(tableMock));
assertThat(tables.get(1), is(table2Mock));
}
@Test
public void shouldReturnConfiguredTables() {
when(tableConfigMock.getId()).thenReturn("table");
when(table2ConfigMock.getId()).thenReturn("table2");
when(formMock.getPanel()).thenReturn(pageMock);
when(pageMock.getPortlet()).thenReturn(portletMock);
when(portletMock.getElementById("table")).thenReturn(tableMock);
when(portletMock.getElementById("table2")).thenReturn(table2Mock);
SearchConfig search = new SearchConfig();
search.setTables(new SearchTablesConfig());
SearchTableConfig searchTableConfig = new SearchTableConfig();
searchTableConfig.setId(tableConfigMock);
search.getTables().getTable().add(searchTableConfig);
SearchTableConfig searchTable2Config = new SearchTableConfig();
searchTable2Config.setId(table2ConfigMock);
search.getTables().getTable().add(searchTable2Config);
when(formActionConfigMock.getSearch()).thenReturn(search);
List<Table> tables = searchAction.findSearchableTables(formMock);
assertThat(tables.size(), is(2));
assertThat(tables.get(0), is(tableMock));
assertThat(tables.get(1), is(table2Mock));
}
@Test
public void shouldFindNotFindTableBelowForm() {
mockPageWithFormAndTable();
when(pageMock.findNextElement(Component.class, tableMock)).thenReturn(
form2Mock);
when(pageMock.findNextElement(Component.class, form2Mock)).thenReturn(
table2Mock);
List<Table> tables = searchAction.findSearchableTables(formMock);
assertThat(tables.size(), is(1));
assertThat(tables.get(0), is(tableMock));
}
@Test
public void shouldFindTablesInSubTabs() {
mockPageWithFormAndTable();
when(pageMock.findNextElement(Component.class, tableMock)).thenReturn(
tabsMock);
when(tabsMock.getElements()).thenReturn(
Arrays.asList(tab1Mock, tab2Mock));
when(tab1Mock.findNextElement(Component.class, null)).thenReturn(
table2Mock);
when(tab2Mock.findNextElement(Component.class, null)).thenReturn(
table3Mock);
List<Table> tables = searchAction.findSearchableTables(formMock);
assertThat(tables.size(), is(3));
assertThat(tables.get(0), is(tableMock));
assertThat(tables.get(1), is(table2Mock));
assertThat(tables.get(2), is(table3Mock));
}
}