/******************************************************************************* * Copyright (c) 2012,2015 EclipseSource and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Holger Staudacher - initial API and implementation * Ivan Iliev - added tests for ServletConfigurationTracker ******************************************************************************/ package com.eclipsesource.jaxrs.publisher.internal; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.Dictionary; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.servlet.Servlet; import javax.servlet.ServletException; import org.glassfish.jersey.server.ServerProperties; import org.glassfish.jersey.servlet.ServletContainer; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.service.http.HttpContext; import org.osgi.service.http.HttpService; import org.osgi.service.http.NamespaceException; import com.eclipsesource.jaxrs.publisher.ApplicationConfiguration; import com.eclipsesource.jaxrs.publisher.ServletConfiguration; @RunWith( MockitoJUnitRunner.class ) public class JerseyContext_Test { private JerseyContext jerseyContext; @Mock private ServletContainer servletContainer; @Mock private HttpService httpService; @Mock private RootApplication rootApplication; @Before public void setUp() { Configuration configuration = createConfiguration( "/test", false, 23L ); ServletConfiguration servletConfigurationService = mock( ServletConfiguration.class ); JerseyContext original = new JerseyContext( httpService, configuration, servletConfigurationService, new ServiceContainer( mock( BundleContext.class ) ) ); jerseyContext = spy( original ); doReturn( rootApplication ).when( jerseyContext ).getRootApplication(); } @Test public void testAddResource() throws ServletException, NamespaceException { Object resource = new Object(); jerseyContext.addResource( resource ); verify( rootApplication ).addResource( resource ); verify( httpService ).registerServlet( eq( "/test" ), any( ServletContainer.class ), any( Dictionary.class ), any( HttpContext.class ) ); } @Test public void testRemoveSingleResource() throws ServletException, NamespaceException { Object resource = new Object(); jerseyContext.addResource( resource ); jerseyContext.removeResource( resource ); verify( rootApplication ).addResource( resource ); verify( rootApplication ).removeResource( resource ); verify( httpService ).registerServlet( eq( "/test" ), any( ServletContainer.class ), any( Dictionary.class ), any( HttpContext.class ) ); verify( httpService ).unregister( "/test" ); } @Test public void testRemoveResource() throws ServletException, NamespaceException { when( rootApplication.hasResources() ).thenReturn( true ); Object resource = new Object(); Object resource2 = new Object(); jerseyContext.addResource( resource ); jerseyContext.addResource( resource2 ); jerseyContext.removeResource( resource ); verify( rootApplication ).addResource( resource ); verify( rootApplication ).addResource( resource2 ); verify( rootApplication ).removeResource( resource ); verify( httpService ).registerServlet( eq( "/test" ), any( ServletContainer.class ), any( Dictionary.class ), any( HttpContext.class ) ); verify( httpService, never() ).unregister( "/test" ); } @Test public void testEliminate() throws ServletException, NamespaceException { Object resource = new Object(); Set<Object> list = new HashSet<Object>(); list.add( resource ); when( rootApplication.getResources() ).thenReturn( list ); jerseyContext.addResource( resource ); List<Object> resources = jerseyContext.eliminate(); verify( rootApplication ).addResource( resource ); verify( httpService ).unregister( "/test" ); assertEquals( 1, resources.size() ); assertEquals( resource, resources.get( 0 ) ); } @Test public void testEliminateDoesNotFailWithException() throws ServletException, NamespaceException { doThrow( Exception.class ).when( httpService ).unregister( anyString() ); Object resource = new Object(); Set<Object> list = new HashSet<Object>(); list.add( resource ); when( rootApplication.getResources() ).thenReturn( list ); jerseyContext.addResource( resource ); List<Object> resources = jerseyContext.eliminate(); verify( rootApplication ).addResource( resource ); verify( httpService ).unregister( "/test" ); assertEquals( 1, resources.size() ); assertEquals( resource, resources.get( 0 ) ); } @Test( expected = IllegalStateException.class ) public void testConvertsServletException() throws ServletException, NamespaceException { doThrow( new ServletException() ).when( httpService ).registerServlet( anyString(), any( Servlet.class ), any( Dictionary.class ), any( HttpContext.class ) ); jerseyContext.addResource( new Object() ); } @Test( expected = IllegalStateException.class ) public void testConvertsNamespaceException() throws ServletException, NamespaceException { doThrow( new NamespaceException( "test" ) ) .when( httpService ).registerServlet( anyString(), any( Servlet.class ), any( Dictionary.class ), any( HttpContext.class ) ); jerseyContext.addResource( new Object() ); } @Test public void testDoesNotRegster_METAINF_SERVICES_LOOKUP_DISABLE() { Configuration configuration = createConfiguration( "/test", false, 23L ); ServletConfiguration servletConfigurationService = mock( ServletConfiguration.class ); JerseyContext context = new JerseyContext( httpService, configuration, servletConfigurationService, new ServiceContainer( mock( BundleContext.class ) ) ); Map<String, Object> properties = context.getRootApplication().getProperties(); assertEquals( false, properties.get( ServerProperties.METAINF_SERVICES_LOOKUP_DISABLE ) ); } @Test public void testRegsters_FEATURE_AUTO_DISCOVERY_DISABLE() { Configuration configuration = createConfiguration( "/test", false, 23L ); ServletConfiguration servletConfigurationService = mock( ServletConfiguration.class ); JerseyContext context = new JerseyContext( httpService, configuration, servletConfigurationService, new ServiceContainer( mock( BundleContext.class ) ) ); Map<String, Object> properties = context.getRootApplication().getProperties(); assertEquals( true, properties.get( ServerProperties.FEATURE_AUTO_DISCOVERY_DISABLE ) ); } @Test public void testAddResourceWithServletConfigurationServicePresent() throws Exception { Configuration configuration = createConfiguration( "/test", false, 23L ); ServletConfiguration servletConfigurationService = mock( ServletConfiguration.class ); JerseyContext withConfiguration = spy( new JerseyContext( httpService, configuration, servletConfigurationService, new ServiceContainer( mock( BundleContext.class ) ) ) ); Object resource = new Object(); withConfiguration.addResource( resource ); verify( servletConfigurationService, times( 1 ) ).getHttpContext( any( HttpService.class ), anyString() ); verify( servletConfigurationService, times( 1 ) ).getInitParams( any( HttpService.class ), anyString() ); } @Test public void testAddsApplicationConfigurationsOnStart() { BundleContext context = mock( BundleContext.class ); ServiceContainer container = new ServiceContainer( context ); ServiceReference reference = mock( ServiceReference.class ); ApplicationConfiguration appConfig = mock( ApplicationConfiguration.class ); Map<String, Object> map = new HashMap<>(); map.put( "foo", "bar" ); when( appConfig.getProperties() ).thenReturn( map ); when( context.getService( reference ) ).thenReturn( appConfig ); container.add( reference ); Configuration configuration = createConfiguration( "/test", false, 23L ); ServletConfiguration servletConfigurationService = mock( ServletConfiguration.class ); JerseyContext jerseyContext = new JerseyContext( httpService, configuration, servletConfigurationService, container ); Map<String, Object> properties = jerseyContext.getRootApplication().getProperties(); assertEquals( properties.get( "foo" ), "bar" ); } @Test public void testUpdateConfigurationBeforeServletRegistered() { Configuration configuration = createConfiguration("/test2", true, 15000L); jerseyContext.updateConfiguration( configuration ); verify(jerseyContext).updateConfiguration( configuration ); verify(jerseyContext, never()).safeUnregister( "/test" ); verify(jerseyContext, never()).registerServletWhenNotAlreadyRegistered(); } @Test public void testUpdateConfigurationAfterServletRegistered() { Object resource = new Object(); jerseyContext.addResource( resource ); Configuration configuration = createConfiguration( "/test2", true, 15000L ); jerseyContext.updateConfiguration( configuration ); verify( jerseyContext ).updateConfiguration( configuration ); verify( jerseyContext ).safeUnregister( "/test" ); verify( jerseyContext, times( 2 ) ).registerServletWhenNotAlreadyRegistered(); } @Test public void testUpdateAppConfiguration() { BundleContext context = mock( BundleContext.class ); ServiceContainer container = new ServiceContainer( context ); ServiceReference reference = mock( ServiceReference.class ); ApplicationConfiguration appConfig = mock( ApplicationConfiguration.class ); Map<String, Object> map = new HashMap<>(); map.put( "foo", "bar" ); when( appConfig.getProperties() ).thenReturn( map ); when( context.getService( reference ) ).thenReturn( appConfig ); container.add( reference ); jerseyContext.updateAppConfiguration( container ); verify( rootApplication ).addProperties( map ); } @Test public void testUpdateServletConfigurationBeforeServletRegistered() { ServletConfiguration configuration = mock ( ServletConfiguration.class); jerseyContext.updateServletConfiguration( configuration ); verify( jerseyContext ).updateServletConfiguration( configuration ); verify( jerseyContext, never() ).safeUnregister( "/test" ); verify( jerseyContext, never() ).registerServletWhenNotAlreadyRegistered(); } @Test public void testUpdateServletConfigurationAfterServletRegistered() { Object resource = new Object(); jerseyContext.addResource( resource ); ServletConfiguration configuration = mock ( ServletConfiguration.class); jerseyContext.updateServletConfiguration( configuration ); verify( jerseyContext ).updateServletConfiguration( configuration ); verify( jerseyContext ).safeUnregister( "/test" ); verify( jerseyContext, times( 2 ) ).registerServletWhenNotAlreadyRegistered(); } private Configuration createConfiguration( String path, boolean wadlDisable, long publishDelay ) { Configuration configuration = mock( Configuration.class ); when( configuration.getRoothPath() ).thenReturn( path ); when( configuration.getPublishDelay() ).thenReturn( publishDelay ); return configuration; } }