/** * Copyright (c) Codice Foundation * * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. * **/ package org.codice.ddf.ui.searchui.query.endpoint; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.Collections; import javax.servlet.ServletContext; import javax.servlet.ServletException; import org.codice.ddf.persistence.PersistentStore; import org.codice.ddf.ui.searchui.query.actions.ActionRegistryImpl; import org.cometd.bayeux.ChannelId; import org.cometd.bayeux.MarkedReference; import org.cometd.bayeux.server.BayeuxServer; import org.cometd.bayeux.server.LocalSession; import org.cometd.bayeux.server.SecurityPolicy; import org.cometd.bayeux.server.ServerChannel; import org.cometd.bayeux.server.ServerMessage; import org.cometd.bayeux.server.ServerSession; import org.cometd.server.BayeuxServerImpl; import org.cometd.server.CometdServlet; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.osgi.framework.BundleContext; import org.osgi.service.event.EventAdmin; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ddf.catalog.CatalogFramework; import ddf.catalog.filter.FilterBuilder; public class CometdEndpointTest { private static final Logger LOGGER = LoggerFactory.getLogger(CometdEndpointTest.class); private static final String MOCK_SESSION_ID = "1234-5678-9012-3456"; private BayeuxServer bayeuxServer = mock(BayeuxServerImpl.class); private CometdEndpoint cometdEndpoint; private ServerSession mockServerSession = mock(ServerSession.class); private ServerMessage mockServerMessage = mock(ServerMessage.class); /** * @throws java.lang.Exception */ @Before public void setUp() throws Exception { when(mockServerSession.getId()).thenReturn(MOCK_SESSION_ID); // Return a new mock of LocalSession each time newLocalSession is // called on the BayeuxServer when(bayeuxServer.newLocalSession(Mockito.anyString())) .thenAnswer(new Answer<LocalSession>() { public LocalSession answer(InvocationOnMock invocation) { LocalSession localSession = mock(LocalSession.class); when(localSession.getServerSession()) .thenReturn(mock(ServerSession.class)); return localSession; } }); // Mock enough of the behavior of the createChannelIfAbsent method to // ensure proper processing of CometD Service annotations when(bayeuxServer.createChannelIfAbsent(Mockito.anyString())) .thenAnswer(new Answer<MarkedReference<ServerChannel>>() { public MarkedReference<ServerChannel> answer( InvocationOnMock invokation) { String channelName = invokation.getArguments()[0].toString(); LOGGER.debug("Channel Name: " + channelName); if (null == channelName) { return null; } ChannelId channelId = new ChannelId(channelName); ServerChannel serverChannel = mock(ServerChannel.class); when(serverChannel.getChannelId()).thenReturn(channelId); when(serverChannel.getId()).thenReturn(channelName); @SuppressWarnings("unchecked") MarkedReference<ServerChannel> markedReference = (MarkedReference<ServerChannel>) mock( MarkedReference.class); // Mark with value of true indicates that the serverChannel // did not previously exist. Implementation of test setup // needs to change if there is a later need to maintain // whether a channel has already been created when(markedReference.isMarked()).thenReturn(true); when(markedReference.getReference()).thenReturn(serverChannel); return markedReference; } }); // Call the actual BayeuxServer methods, rather than the mock methods, // when setting/getting the security policy. Mockito.doCallRealMethod().when(bayeuxServer) .setSecurityPolicy(Mockito.any(SecurityPolicy.class)); Mockito.doCallRealMethod().when(bayeuxServer).getSecurityPolicy(); // Associate the BayeuxServer with a CometdServlet CometdServlet cometdServlet = mock(CometdServlet.class); ServletContext servletContext = mock(ServletContext.class); when(cometdServlet.getServletContext()).thenReturn(servletContext); when(servletContext.getAttribute(BayeuxServer.ATTRIBUTE)).thenReturn(bayeuxServer); // Create the CometdEndpoint, passing in the mocked CometdServlet cometdEndpoint = new CometdEndpoint(cometdServlet, mock(CatalogFramework.class), mock(FilterBuilder.class), mock(PersistentStore.class), mock(BundleContext.class), mock(EventAdmin.class), new ActionRegistryImpl(Collections.EMPTY_LIST)); } /** * @throws java.lang.Exception */ @After public void tearDown() throws Exception { } /** * Test method that verifies the {@link org.cometd.bayeux.server.SecurityPolicy#canHandshake(BayeuxServer, ServerSession, ServerMessage)} * method of the custom {@link org.cometd.bayeux.server.SecurityPolicy} * associated with the {@link org.cometd.bayeux.server.BayeuxServer} created * by the {@link CometdEndpoint} registers users with the * {@link org.codice.ddf.ui.searchui.query.controller.NotificationController}. * * @throws ServletException */ @Test public void testCanHandshakeRegistersUserWithNotificationController() throws ServletException { cometdEndpoint.init(); SecurityPolicy securityPolicy = bayeuxServer.getSecurityPolicy(); assertNotNull("BayeuxServer's SecurityPolicy is null", securityPolicy); // Verify that the mock ServerSession is not already being managed by // the org.codice.ddf.ui.searchui.query.controller.NotificationController assertNull(cometdEndpoint.notificationController.getSessionByUserId(MOCK_SESSION_ID)); // Invoke the canHandshake method of the SecurityPolicy securityPolicy.canHandshake(bayeuxServer, mockServerSession, mockServerMessage); // Verify that the user userId/ServerSession pair are now being managed // by the org.codice.ddf.ui.searchui.query.controller.NotificationController assertEquals("NotificationController did not return the expected ServerSession", mockServerSession, cometdEndpoint.notificationController.getSessionByUserId(MOCK_SESSION_ID)); } }