/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.gwc.layer; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.is; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.FeatureTypeInfo; import org.geoserver.catalog.LayerGroupInfo; import org.geoserver.catalog.LayerInfo; import org.geoserver.catalog.ResourceInfo; import org.geoserver.catalog.StyleInfo; import org.geoserver.catalog.event.impl.CatalogModifyEventImpl; import org.geoserver.catalog.event.impl.CatalogPostModifyEventImpl; import org.geoserver.gwc.GWC; import org.geowebcache.filter.parameters.ParameterFilter; import org.junit.Before; import org.junit.Test; import com.google.common.collect.ImmutableSet; public class CatalogStyleChangeListenerTest { private final String STYLE_NAME = "highways"; private String STYLE_NAME_MODIFIED = STYLE_NAME + "_modified"; private final String PREFIXED_RESOURCE_NAME = "mock:Layer"; private GWC mockMediator; private ResourceInfo mockResourceInfo; private LayerInfo mockLayerInfo; private StyleInfo mockStyle; private GeoServerTileLayer mockTileLayer; private GeoServerTileLayerInfoImpl mockTileLayerInfo; private CatalogModifyEventImpl styleNameModifyEvent; private CatalogStyleChangeListener listener; @Before public void setUp() throws Exception { mockMediator = mock(GWC.class); mockStyle = mock(StyleInfo.class); when(mockStyle.prefixedName()).thenReturn(STYLE_NAME); mockResourceInfo = mock(FeatureTypeInfo.class); when(mockResourceInfo.prefixedName()).thenReturn(PREFIXED_RESOURCE_NAME); mockLayerInfo = mock(LayerInfo.class); when(mockLayerInfo.getResource()).thenReturn(mockResourceInfo); mockTileLayer = mock(GeoServerTileLayer.class); mockTileLayerInfo = mock(GeoServerTileLayerInfoImpl.class); ImmutableSet<String> empty = ImmutableSet.of(); when(mockTileLayerInfo.cachedStyles()).thenReturn(empty); when(mockTileLayer.getLayerInfo()).thenReturn(mockLayerInfo); when(mockTileLayer.getInfo()).thenReturn(mockTileLayerInfo); when(mockTileLayer.getName()).thenReturn(PREFIXED_RESOURCE_NAME); when(mockMediator.getTileLayersForStyle(eq(STYLE_NAME))).thenReturn( Collections.singletonList(mockTileLayer)); Catalog mockCatalog = mock(Catalog.class); listener = new CatalogStyleChangeListener(mockMediator, mockCatalog); styleNameModifyEvent = new CatalogModifyEventImpl(); styleNameModifyEvent.setSource(mockStyle); styleNameModifyEvent.setPropertyNames(Arrays.asList("name")); styleNameModifyEvent.setOldValues(Arrays.asList(STYLE_NAME)); styleNameModifyEvent.setNewValues(Arrays.asList(STYLE_NAME_MODIFIED)); } @Test public void testIgnorableChange() throws Exception { // not a name change styleNameModifyEvent.setPropertyNames(Arrays.asList("fileName")); listener.handleModifyEvent(styleNameModifyEvent); // name didn't change at all styleNameModifyEvent.setPropertyNames(Arrays.asList("name")); styleNameModifyEvent.setOldValues(Arrays.asList(STYLE_NAME)); styleNameModifyEvent.setNewValues(Arrays.asList(STYLE_NAME)); listener.handleModifyEvent(styleNameModifyEvent); // not a style change styleNameModifyEvent.setSource(mock(LayerInfo.class)); listener.handleModifyEvent(styleNameModifyEvent); // a change in the name of the default style should not cause a truncate verify(mockMediator, never()).truncateByLayerAndStyle(anyString(), anyString()); // nor a save, as the default style name is dynamic verify(mockMediator, never()).save((GeoServerTileLayer) anyObject()); verify(mockTileLayer, never()).getInfo(); verify(mockTileLayerInfo, never()).cachedStyles(); } @Test public void testRenameDefaultStyle() throws Exception { // this is another case of an ignorable change. Renaming the default style shall have no // impact. listener.handleModifyEvent(styleNameModifyEvent); // a change in the name of the default style should not cause a truncate verify(mockMediator, never()).truncateByLayerAndStyle(anyString(), anyString()); // nor a save, as the default style name is dynamic verify(mockMediator, never()).save((GeoServerTileLayer) anyObject()); verify(mockTileLayer, atLeastOnce()).getInfo(); verify(mockTileLayerInfo, atLeastOnce()).cachedStyles(); } @Test public void testRenameAlternateStyle() throws Exception { Set<ParameterFilter> params = new HashSet<ParameterFilter>(); StyleParameterFilter newStyleFilter = new StyleParameterFilter(); newStyleFilter.setStyles(ImmutableSet.of(STYLE_NAME)); params.add(newStyleFilter); TileLayerInfoUtil.setCachedStyles(mockTileLayerInfo, null, ImmutableSet.of(STYLE_NAME)); verify(mockTileLayerInfo).addParameterFilter((ParameterFilter) argThat(allOf(hasProperty("key", is("STYLES")), hasProperty("styles", is(ImmutableSet.of(STYLE_NAME)))))); ImmutableSet<String> styles = ImmutableSet.of(STYLE_NAME); when(mockTileLayerInfo.cachedStyles()).thenReturn(styles); listener.handleModifyEvent(styleNameModifyEvent); verify(mockTileLayerInfo).addParameterFilter((ParameterFilter) argThat(allOf(hasProperty("key", is("STYLES")), hasProperty("styles", is(ImmutableSet.of(STYLE_NAME_MODIFIED)))))); verify(mockTileLayer, times(1)).resetParameterFilters(); verify(mockMediator, times(1)).truncateByLayerAndStyle(eq(PREFIXED_RESOURCE_NAME), eq(STYLE_NAME)); verify(mockMediator, times(1)).save(same(mockTileLayer)); } @SuppressWarnings("unchecked") @Test public void testLayerInfoDefaultOrAlternateStyleChanged() throws Exception { when(mockMediator.getLayerInfosFor(same(mockStyle))).thenReturn( Collections.singleton(mockLayerInfo)); when(mockMediator.getLayerGroupsFor(same(mockStyle))).thenReturn(Collections.EMPTY_LIST); CatalogPostModifyEventImpl postModifyEvent = new CatalogPostModifyEventImpl(); postModifyEvent.setSource(mockStyle); listener.handlePostModifyEvent(postModifyEvent); verify(mockMediator, times(1)).truncateByLayerAndStyle(eq(PREFIXED_RESOURCE_NAME), eq(STYLE_NAME)); } @SuppressWarnings("unchecked") @Test public void testLayerGroupInfoImplicitOrExplicitStyleChanged() throws Exception { LayerGroupInfo mockGroup = mock(LayerGroupInfo.class); when(GWC.tileLayerName(mockGroup)).thenReturn("mockGroup"); when(mockMediator.getLayerInfosFor(same(mockStyle))).thenReturn(Collections.EMPTY_LIST); when(mockMediator.getLayerGroupsFor(same(mockStyle))).thenReturn( Collections.singleton(mockGroup)); CatalogPostModifyEventImpl postModifyEvent = new CatalogPostModifyEventImpl(); postModifyEvent.setSource(mockStyle); listener.handlePostModifyEvent(postModifyEvent); verify(mockMediator, times(1)).truncate(eq("mockGroup")); } }