/******************************************************************************* * Copyright (c) 2014 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: * EclipseSource - initial API and implementation ******************************************************************************/ package com.eclipsesource.tabris.tracking; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.lang.Thread.UncaughtExceptionHandler; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import org.eclipse.swt.widgets.Display; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.ArgumentCaptor; import com.eclipsesource.tabris.test.util.TabrisEnvironment; import com.eclipsesource.tabris.tracking.TrackingEvent.EventType; import com.eclipsesource.tabris.tracking.internal.DispatchTask; import com.eclipsesource.tabris.tracking.internal.EventDispatcher; import com.eclipsesource.tabris.ui.Action; import com.eclipsesource.tabris.ui.ActionConfiguration; import com.eclipsesource.tabris.ui.ActionListener; import com.eclipsesource.tabris.ui.Page; import com.eclipsesource.tabris.ui.PageConfiguration; import com.eclipsesource.tabris.ui.TransitionListener; import com.eclipsesource.tabris.ui.UI; import com.eclipsesource.tabris.ui.UIConfiguration; import com.eclipsesource.tabris.ui.action.SearchActionListener; public class TrackingTest { @Rule public TabrisEnvironment environment = new TabrisEnvironment(); private Display display; @Before public void setUp() { display = new Display(); } @Test( expected = IllegalArgumentException.class ) public void testFailsWithNullTracker() { new Tracking( ( Tracker )null ); } @Test( expected = IllegalArgumentException.class ) public void testFailsWithNullTrackerButOtherTrackers() { new Tracking( null, new Tracker[] { mock( Tracker.class ) } ); } @Test( expected = IllegalArgumentException.class ) public void testFailsWithNullOtherTrackers() { new Tracking( mock( Tracker.class ), ( Tracker[] )null ); } @Test public void testAddsOneTracker() { Tracker tracker = mock( Tracker.class ); Tracking tracking = new Tracking( tracker ); List<Tracker> trackers = tracking.getTrackers(); assertSame( tracker, trackers.get( 0 ) ); assertEquals( 1, trackers.size() ); } @Test public void testAddsMoreTrackers() { Tracker tracker1 = mock( Tracker.class ); Tracker tracker2 = mock( Tracker.class ); Tracker tracker3 = mock( Tracker.class ); Tracking tracking = new Tracking( tracker1, tracker2, tracker3 ); List<Tracker> trackers = tracking.getTrackers(); assertSame( tracker1, trackers.get( 0 ) ); assertSame( tracker2, trackers.get( 1 ) ); assertSame( tracker3, trackers.get( 2 ) ); assertEquals( 3, trackers.size() ); } @Test( expected = IllegalArgumentException.class ) public void testAttachFailsWithNullConfiguration() { Tracking tracking = new Tracking( mock( Tracker.class ) ); tracking.attach( null ); } @Test public void testAttachAddsTransitionListener() { Tracking tracking = new Tracking( mock( Tracker.class ) ); UIConfiguration configuration = mock( UIConfiguration.class ); tracking.attach( configuration ); verify( configuration ).addTransitionListener( any( TransitionListener.class ) ); } @Test public void testAttachAddsActionListener() { Tracking tracking = new Tracking( mock( Tracker.class ) ); UIConfiguration configuration = mock( UIConfiguration.class ); tracking.attach( configuration ); verify( configuration ).addActionListener( any( SearchActionListener.class ) ); } @Test( expected = IllegalArgumentException.class ) public void testFailsWithNullExceptionHandler() { EventDispatcher dispatcher = mock( EventDispatcher.class ); Tracking tracking = new Tracking( dispatcher, new ArrayList<Tracker>() ); tracking.setUncaughtExceptionHandler( null ); } @Test public void testSetsExceptionHandlerOnDispatcher() { UncaughtExceptionHandler handler = mock( UncaughtExceptionHandler.class ); EventDispatcher dispatcher = mock( EventDispatcher.class ); Tracking tracking = new Tracking( dispatcher, new ArrayList<Tracker>() ); tracking.setUncaughtExceptionHandler( handler ); verify( dispatcher ).setUncaughtExceptionHandler( handler ); } @Test public void testDispatchesPageTransition() { EventDispatcher dispatcher = mock( EventDispatcher.class ); Tracking tracking = new Tracking( dispatcher, new ArrayList<Tracker>() ); PageConfiguration pageConfiguration = mock( PageConfiguration.class ); UIConfiguration configuration = mock( UIConfiguration.class ); tracking.attach( configuration ); fakePageTransition( configuration, pageConfiguration ); ArgumentCaptor<DispatchTask> captor = ArgumentCaptor.forClass( DispatchTask.class ); verify( dispatcher ).dispatch( captor.capture() ); assertSame( EventType.PAGE_VIEW, captor.getValue().getEvent().getType() ); assertNotNull( captor.getValue().getEvent().getInfo() ); assertSame( "foo", captor.getValue().getEvent().getDetail() ); assertSame( tracking.getTrackers(), captor.getValue().getTrackers() ); } private void fakePageTransition( UIConfiguration configuration, PageConfiguration pageConfiguration ) { ArgumentCaptor<TransitionListener> captor = ArgumentCaptor.forClass( TransitionListener.class ); verify( configuration ).addTransitionListener( captor.capture() ); UI ui = mock( UI.class ); when( ui.getDisplay() ).thenReturn( display ); when( ui.getPageConfiguration( any( Page.class ) ) ).thenReturn( pageConfiguration ); when( pageConfiguration.getId() ).thenReturn( "foo" ); captor.getValue().after( ui, mock( Page.class ), mock( Page.class ) ); } @Test public void testDispatchesActionExecution() { EventDispatcher dispatcher = mock( EventDispatcher.class ); Tracking tracking = new Tracking( dispatcher, new ArrayList<Tracker>() ); ActionConfiguration actionConfiguration = mock( ActionConfiguration.class ); when( actionConfiguration.getId() ).thenReturn( "bar" ); UIConfiguration configuration = mock( UIConfiguration.class ); tracking.attach( configuration ); fakeActionExecution( configuration, actionConfiguration ); ArgumentCaptor<DispatchTask> captor = ArgumentCaptor.forClass( DispatchTask.class ); verify( dispatcher ).dispatch( captor.capture() ); assertSame( EventType.ACTION, captor.getValue().getEvent().getType() ); assertNotNull( captor.getValue().getEvent().getInfo() ); assertSame( "bar", captor.getValue().getEvent().getDetail() ); assertSame( tracking.getTrackers(), captor.getValue().getTrackers() ); } @Test public void testDispatchesEventExecution() { EventDispatcher dispatcher = mock( EventDispatcher.class ); Tracking tracking = new Tracking( dispatcher, new ArrayList<Tracker>() ); tracking.submitEvent( display, "foo" ); ArgumentCaptor<DispatchTask> captor = ArgumentCaptor.forClass( DispatchTask.class ); verify( dispatcher ).dispatch( captor.capture() ); assertSame( EventType.EVENT, captor.getValue().getEvent().getType() ); assertNotNull( captor.getValue().getEvent().getInfo() ); assertSame( "foo", captor.getValue().getEvent().getDetail() ); assertSame( tracking.getTrackers(), captor.getValue().getTrackers() ); } @Test( expected = IllegalArgumentException.class ) public void testDispatchesEventFailsWithNullDisplay() { Tracking tracking = new Tracking( mock( EventDispatcher.class ), new ArrayList<Tracker>() ); tracking.submitEvent( null, "foo" ); } @Test( expected = IllegalArgumentException.class ) public void testDispatchesEventFailsWithNullId() { Tracking tracking = new Tracking( mock( EventDispatcher.class ), new ArrayList<Tracker>() ); tracking.submitEvent( display, null ); } @Test( expected = IllegalArgumentException.class ) public void testDispatchesEventFailsWithEmptyId() { Tracking tracking = new Tracking( mock( EventDispatcher.class ), new ArrayList<Tracker>() ); tracking.submitEvent( display, "" ); } @Test public void testDispatchesOrder() { EventDispatcher dispatcher = mock( EventDispatcher.class ); Tracking tracking = new Tracking( dispatcher, new ArrayList<Tracker>() ); Order order = new Order( "foo", BigDecimal.ONE ); tracking.submitOrder( display, order ); ArgumentCaptor<DispatchTask> captor = ArgumentCaptor.forClass( DispatchTask.class ); verify( dispatcher ).dispatch( captor.capture() ); assertSame( EventType.ORDER, captor.getValue().getEvent().getType() ); assertNotNull( captor.getValue().getEvent().getInfo() ); assertEquals( order, captor.getValue().getEvent().getDetail() ); assertSame( tracking.getTrackers(), captor.getValue().getTrackers() ); } @Test( expected = IllegalArgumentException.class ) public void testSubmitOrderFailsWithNullDisplay() { Tracking tracking = new Tracking( mock( EventDispatcher.class ), new ArrayList<Tracker>() ); tracking.submitOrder( null, new Order( "foo", BigDecimal.ONE ) ); } @Test( expected = IllegalArgumentException.class ) public void testSubmitOrderFailsWithNullOrder() { Tracking tracking = new Tracking( mock( EventDispatcher.class ), new ArrayList<Tracker>() ); tracking.submitOrder( display, null ); } private void fakeActionExecution( UIConfiguration configuration, ActionConfiguration actionConfiguration ) { ArgumentCaptor<ActionListener> captor = ArgumentCaptor.forClass( ActionListener.class ); verify( configuration ).addActionListener( captor.capture() ); UI ui = mock( UI.class ); when( ui.getDisplay() ).thenReturn( display ); when( ui.getActionConfiguration( any( Action.class ) ) ).thenReturn( actionConfiguration ); captor.getValue().executed( ui, mock( Action.class ) ); } @Test public void testDispatchesSearch() { EventDispatcher dispatcher = mock( EventDispatcher.class ); Tracking tracking = new Tracking( dispatcher, new ArrayList<Tracker>() ); ActionConfiguration actionConfiguration = mock( ActionConfiguration.class ); when( actionConfiguration.getId() ).thenReturn( "bar" ); UIConfiguration configuration = mock( UIConfiguration.class ); tracking.attach( configuration ); fakeSearch( configuration, actionConfiguration, "foo" ); ArgumentCaptor<DispatchTask> captor = ArgumentCaptor.forClass( DispatchTask.class ); verify( dispatcher ).dispatch( captor.capture() ); assertSame( EventType.SEARCH, captor.getValue().getEvent().getType() ); assertNotNull( captor.getValue().getEvent().getInfo() ); assertEquals( "foo", captor.getValue().getEvent().getInfo().getSearchQuery() ); assertSame( "bar", captor.getValue().getEvent().getDetail() ); assertSame( tracking.getTrackers(), captor.getValue().getTrackers() ); } private void fakeSearch( UIConfiguration configuration, ActionConfiguration actionConfiguration, String query ) { ArgumentCaptor<SearchActionListener> captor = ArgumentCaptor.forClass( SearchActionListener.class ); verify( configuration ).addActionListener( captor.capture() ); UI ui = mock( UI.class ); when( ui.getDisplay() ).thenReturn( display ); when( ui.getActionConfiguration( any( Action.class ) ) ).thenReturn( actionConfiguration ); captor.getValue().searched( ui, mock( Action.class ), query ); } }