/** * Copyright 2013 the original author or authors. * * 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 io.neba.core.resourcemodels.registration; import io.neba.api.annotations.ResourceModel; import io.neba.core.resourcemodels.adaptation.ResourceToModelAdapterUpdater; import io.neba.core.resourcemodels.metadata.ResourceModelMetaDataRegistrar; import io.neba.core.util.OsgiBeanSource; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isA; import static org.mockito.Mockito.*; /** * @author Olaf Otto */ @RunWith(MockitoJUnitRunner.class) public class ModelRegistrarTest { private ConfigurableListableBeanFactory factory; private Bundle bundle; private BundleContext context; private Map<String, OsgiBeanSource<Object>> addedBeanSources; private Set<Object> beans = new HashSet<>(); @Mock private ModelRegistry registry; @Mock private ResourceToModelAdapterUpdater updater; @Mock private ResourceModelMetaDataRegistrar resourceModelMetaDataRegistrar; @InjectMocks private ModelRegistrar testee; @Before @SuppressWarnings({"rawtypes", "unchecked"}) public void prepareModelRegistrar() { this.addedBeanSources = new HashMap<>(); Answer registerModel = invocation -> { String[] resourceTypes = (String[]) invocation.getArguments()[0]; OsgiBeanSource<Object> osgiBeanSource = (OsgiBeanSource<Object>) invocation.getArguments()[1]; for (String type : resourceTypes) { addedBeanSources.put(type, osgiBeanSource); } return null; }; doAnswer(registerModel).when(this.registry).add(isA(String[].class), isA(OsgiBeanSource.class)); } @Before public void mockBundleContext() { this.bundle = mock(Bundle.class); when(this.bundle.getBundleId()).thenReturn(12345L); this.context = mock(BundleContext.class); when(this.context.getBundle()).thenReturn(this.bundle); } @Test public void testModelRegistration() throws Exception { withBeanFactory(); withResourceModelsInApplicationContext("bean1", "bean2"); registerResourceModels(); assertBeanSourcesForAllBeansAddedToRegistry(); } @Test public void testRegistrarRemovesBundleFromRegistryWhenBundleStops() throws Exception { sendStopEventToRegistrar(); assertRegistrarRemovesBundleFromRegistry(); } private void assertRegistrarRemovesBundleFromRegistry() { verify(this.registry).removeResourceModels(eq(this.bundle)); } private void sendStopEventToRegistrar() { this.testee.unregister(this.bundle); } private void assertBeanSourcesForAllBeansAddedToRegistry() { assertThat(this.addedBeanSources, notNullValue()); assertThat(this.addedBeanSources.size(), is(this.beans.size())); Set<Object> beansFromBeanSources = this.addedBeanSources.values().stream().map(OsgiBeanSource::getBean).collect(Collectors.toSet()); assertThat(this.beans, is(beansFromBeanSources)); } private void withResourceModelsInApplicationContext(String... beanNames) { when(this.factory.getBeanNamesForType(eq(Object.class))).thenReturn(beanNames); for (String name : beanNames) { mockResourceModelWithBeanName(name); } } private void mockResourceModelWithBeanName(String name) { ResourceModel type = mockResourceModelAnnotation(name); when(this.factory.findAnnotationOnBean(eq(name), eq(ResourceModel.class))).thenReturn(type); this.beans.add(name); when(this.factory.getBean(eq(name))).thenReturn(name); } private ResourceModel mockResourceModelAnnotation(String name) { ResourceModel type = mock(ResourceModel.class); when(type.types()).thenReturn(new String[] {"/junit/test/" + name}); return type; } private void registerResourceModels() { this.testee.registerModels(this.context, this.factory); } private void withBeanFactory() { this.factory = mock(ConfigurableListableBeanFactory.class); } }