/*
* Copyright 2016 Kejun Xia
*
* 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 com.shipdream.lib.android.mvc;
import com.shipdream.lib.android.mvc.inject.testNameMapping.controller.TimerController;
import com.shipdream.lib.android.mvc.manager.internal.BaseNavigationManagerTest;
import com.shipdream.lib.poke.Consumer;
import com.shipdream.lib.poke.Provides;
import com.shipdream.lib.poke.exception.ProvideException;
import com.shipdream.lib.poke.exception.ProviderConflictException;
import com.shipdream.lib.poke.exception.ProviderMissingException;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.slf4j.Logger;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import javax.inject.Inject;
import javax.inject.Qualifier;
import javax.inject.Singleton;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class TestNavigationManager extends BaseNavigationManagerTest {
//Define a subscriber class
class ForwardListener {
public void onEvent(NavigationManager.Event.OnLocationForward event) {
}
}
class BackListener {
public void onEvent(NavigationManager.Event.OnLocationBack event) {
}
}
abstract class Controller1 extends Controller {
}
abstract class Controller2 extends Controller {
}
abstract class Controller3 extends Controller {
}
abstract class Controller4 extends Controller {
}
abstract class Controller5 extends Controller {
}
private Class<? extends Controller> locId1 = Controller1.class;
private Class<? extends Controller> locId2 = Controller2.class;
private Class<? extends Controller> locId3 = Controller3.class;
private Class<? extends Controller> locId4 = Controller4.class;
private Class<? extends Controller> locId5 = Controller5.class;
protected void navigateBackByFragment() {
navigationManager.navigate(this).back();
}
@Test
public void should_not_fail_when_logger_is_set_trace() {
navigationManager.logger = mock(Logger.class);
when(navigationManager.logger.isTraceEnabled()).thenReturn(true);
prepareLocationHistory();
navigationManager.navigate(this).back();
}
interface X{
}
@Test(expected = MvcGraphException.class)
public void should_throw_MvcGraphException_when_mvcGraph_with_method_encounters_PokeException() {
navigationManager.navigate(this).with(X.class);
}
class X_1 implements X {
}
@Test
public void should_throw_MvcGraphException_when_mvcGraph_destroy_method_encounters_PokeException() throws ProvideException, ProviderConflictException, ProviderMissingException {
navigationManager.logger = mock(Logger.class);
Navigator navigator = navigationManager.navigate(this);
Mvc.graph().getRootComponent().register(new Object(){
@Provides
public X x() {
return new X_1();
}
});
navigator.with(X.class);
Mvc.graph().getRootComponent().unregister(X.class, null);
navigator.destroy();
verify(navigationManager.logger).warn(anyString(), anyString());
}
@Test
public void shouldClearNavigationHistoryUpToSpecified() throws Exception {
ForwardListener forwardListener = prepareLocationHistory();
//loc1 -> loc2 -> loc3 -> loc4
navigationManager.navigate(this).to(locId2);
navigationManager.navigate(this).to(locId4);
navigationManager.navigate(this).to(locId1);
//loc1 -> loc2 -> loc3 -> loc4 -> loc2 -> loc4 -> loc1
reset(forwardListener);
navigationManager.navigate(this).to(locId5, new Forwarder().clearTo(locId3));
//loc1 -> loc2 -> loc3 -> loc5
ArgumentCaptor<NavigationManager.Event.OnLocationForward> event
= ArgumentCaptor.forClass(NavigationManager.Event.OnLocationForward.class);
verify(forwardListener).onEvent(event.capture());
assertEquals(event.getValue().getLastValue().getLocationId(), locId1.getName());
assertEquals(event.getValue().getCurrentValue().getLocationId(), locId5.getName());
assertEquals(event.getValue().getLocationWhereHistoryClearedUpTo().getLocationId(), locId3.getName());
assertEquals(event.getValue().isClearHistory(), true);
NavigationManager.Model model = navigationManager.getModel();
NavLocation curLoc = model.getCurrentLocation();
assertEquals(curLoc.getLocationId(), locId5.getName());
curLoc = curLoc.getPreviousLocation();
assertEquals(curLoc.getLocationId(), locId3.getName());
curLoc = curLoc.getPreviousLocation();
assertEquals(curLoc.getLocationId(), locId2.getName());
curLoc = curLoc.getPreviousLocation();
assertEquals(curLoc.getLocationId(), locId1.getName());
curLoc = curLoc.getPreviousLocation();
assertEquals(curLoc, null);
//loc1 -> loc2 -> loc3 -> loc5
NavLocation currentLoc = navigationManager.getModel().getCurrentLocation();
assertEquals(currentLoc.getLocationId(), locId5.getName());
assertEquals(currentLoc.getPreviousLocation().getLocationId(), locId3.getName());
assertEquals(currentLoc.getPreviousLocation().getPreviousLocation().getLocationId(), locId2.getName());
assertEquals(currentLoc.getPreviousLocation().getPreviousLocation().getPreviousLocation().getLocationId(), locId1.getName());
assertEquals(currentLoc.getPreviousLocation().getPreviousLocation().getPreviousLocation().getPreviousLocation(), null);
}
@Test
public void shouldClearAllNavigationHistory() throws Exception {
ForwardListener forwardListener = prepareLocationHistory();
reset(forwardListener);
navigationManager.navigate(this).to(locId5, new Forwarder().clearAll());
ArgumentCaptor<NavigationManager.Event.OnLocationForward> event
= ArgumentCaptor.forClass(NavigationManager.Event.OnLocationForward.class);
verify(forwardListener).onEvent(event.capture());
assertEquals(event.getValue().getLastValue().getLocationId(), locId4.getName());
assertEquals(event.getValue().getCurrentValue().getLocationId(), locId5.getName());
assertEquals(event.getValue().getLocationWhereHistoryClearedUpTo(), null);
assertEquals(event.getValue().isClearHistory(), true);
//Now the history should be loc1->loc2->loc5
NavLocation currentLoc = navigationManager.getModel().getCurrentLocation();
assertEquals(currentLoc.getLocationId(), locId5.getName());
assertEquals(currentLoc.getPreviousLocation(), null);
}
@Test
public void shouldBeAbleToNavigateBackOneByOne() throws Exception {
//mock the subscriber
BackListener backListener = mock(BackListener.class);
eventBusC.register(backListener);
prepareLocationHistory();
reset(backListener);
navigateBackByFragment();
ArgumentCaptor<NavigationManager.Event.OnLocationBack> event
= ArgumentCaptor.forClass(NavigationManager.Event.OnLocationBack.class);
verify(backListener).onEvent(event.capture());
assertEquals(event.getValue().getLastValue().getLocationId(), locId4.getName());
assertEquals(event.getValue().getCurrentValue().getLocationId(), locId3.getName());
NavLocation currentLoc = navigationManager.getModel().getCurrentLocation();
assertEquals(currentLoc.getLocationId(), locId3.getName());
assertEquals(currentLoc.getPreviousLocation().getLocationId(), locId2.getName());
assertEquals(currentLoc.getPreviousLocation().getPreviousLocation().getLocationId(), locId1.getName());
assertEquals(currentLoc.getPreviousLocation().getPreviousLocation().getPreviousLocation(), null);
Assert.assertFalse(event.getValue().isFastRewind());
reset(backListener);
navigateBackByFragment();
event = ArgumentCaptor.forClass(NavigationManager.Event.OnLocationBack.class);
verify(backListener).onEvent(event.capture());
assertEquals(event.getValue().getLastValue().getLocationId(), locId3.getName());
assertEquals(event.getValue().getCurrentValue().getLocationId(), locId2.getName());
currentLoc = navigationManager.getModel().getCurrentLocation();
assertEquals(currentLoc.getLocationId(), locId2.getName());
assertEquals(currentLoc.getPreviousLocation().getLocationId(), locId1.getName());
assertEquals(currentLoc.getPreviousLocation().getPreviousLocation(), null);
Assert.assertFalse(event.getValue().isFastRewind());
reset(backListener);
navigateBackByFragment();
event = ArgumentCaptor.forClass(NavigationManager.Event.OnLocationBack.class);
verify(backListener).onEvent(event.capture());
assertEquals(event.getValue().getLastValue().getLocationId(), locId2.getName());
assertEquals(event.getValue().getCurrentValue().getLocationId(), locId1.getName());
currentLoc = navigationManager.getModel().getCurrentLocation();
assertEquals(currentLoc.getLocationId(), locId1.getName());
assertEquals(currentLoc.getPreviousLocation(), null);
Assert.assertFalse(event.getValue().isFastRewind());
reset(backListener);
navigateBackByFragment();
event = ArgumentCaptor.forClass(NavigationManager.Event.OnLocationBack.class);
verify(backListener).onEvent(event.capture());
assertEquals(event.getValue().getLastValue().getLocationId(), locId1.getName());
assertEquals(event.getValue().getCurrentValue(), null);
currentLoc = navigationManager.getModel().getCurrentLocation();
assertEquals(currentLoc, null);
Assert.assertFalse(event.getValue().isFastRewind());
//has already reached the start of the navigation, should not be able to navigate back any more
reset(backListener);
navigateBackByFragment();
event = ArgumentCaptor.forClass(NavigationManager.Event.OnLocationBack.class);
verify(backListener, times(0)).onEvent(event.capture());
}
@Test
public void shouldBeAbleToNavigateBackToGivenLocation() throws Exception {
//mock the subscriber
BackListener backListener = mock(BackListener.class);
eventBusC.register(backListener);
prepareLocationHistory();
reset(backListener);
navigationManager.navigate(this).back(locId2);
ArgumentCaptor<NavigationManager.Event.OnLocationBack> event
= ArgumentCaptor.forClass(NavigationManager.Event.OnLocationBack.class);
verify(backListener).onEvent(event.capture());
assertEquals(event.getValue().getLastValue().getLocationId(), locId4.getName());
assertEquals(event.getValue().getCurrentValue().getLocationId(), locId2.getName());
NavLocation currentLoc = navigationManager.getModel().getCurrentLocation();
assertEquals(currentLoc.getLocationId(), locId2.getName());
assertEquals(currentLoc.getPreviousLocation().getLocationId(), locId1.getName());
assertEquals(currentLoc.getPreviousLocation().getPreviousLocation(), null);
Assert.assertTrue(event.getValue().isFastRewind());
}
@Test
public void shouldBeAbleToNavigateBackToFirstLocation() throws Exception {
//mock the subscriber
BackListener backListener = mock(BackListener.class);
eventBusC.register(backListener);
prepareLocationHistory();
reset(backListener);
Navigator navigator = navigationManager.navigate(this);
navigator.back(null);
ArgumentCaptor<NavigationManager.Event.OnLocationBack> event
= ArgumentCaptor.forClass(NavigationManager.Event.OnLocationBack.class);
verify(backListener).onEvent(event.capture());
Assert.assertTrue(this == event.getValue().getSender());
Assert.assertTrue(navigator == event.getValue().getNavigator());
assertEquals(event.getValue().getLastValue().getLocationId(), locId4.getName());
assertEquals(event.getValue().getCurrentValue().getLocationId(), locId1.getName());
NavLocation currentLoc = navigationManager.getModel().getCurrentLocation();
assertEquals(currentLoc.getLocationId(), locId1.getName());
assertEquals(currentLoc.getPreviousLocation(), null);
Assert.assertTrue(event.getValue().isFastRewind());
}
@Test
public void should_skip_interim_location_on_back_navigation() throws Exception {
//mock the subscriber
BackListener backListener = mock(BackListener.class);
eventBusC.register(backListener);
prepareLocationHistory();
reset(backListener);
navigationManager.navigate(this).to(locId1, new Forwarder().setInterim(true));
navigationManager.navigate(this).to(locId2, new Forwarder().setInterim(true));
navigationManager.navigate(this).back();
ArgumentCaptor<NavigationManager.Event.OnLocationBack> event
= ArgumentCaptor.forClass(NavigationManager.Event.OnLocationBack.class);
verify(backListener).onEvent(event.capture());
assertEquals(event.getValue().getLastValue().getLocationId(), locId2.getName());
assertEquals(event.getValue().getCurrentValue().getLocationId(), locId4.getName());
NavLocation currentLoc = navigationManager.getModel().getCurrentLocation();
assertEquals(currentLoc.getLocationId(), locId4.getName());
Assert.assertTrue(event.getValue().isFastRewind());
}
@Test
public void should_post_app_exit_event_on_the_last_back_of_linear_back_navigation() {
//mock the subscriber
class AppExitListener {
public void onEvent(NavigationManager.Event.OnAppExit event) {
}
}
ArgumentCaptor<NavigationManager.Event.OnAppExit> event
= ArgumentCaptor.forClass(NavigationManager.Event.OnAppExit.class);
AppExitListener exitListener = mock(AppExitListener.class);
eventBusC.register(exitListener);
prepareLocationHistory();
reset(exitListener);
navigateBackByFragment();
verify(exitListener, times(0)).onEvent(event.capture());
navigateBackByFragment();
verify(exitListener, times(0)).onEvent(event.capture());
navigateBackByFragment();
verify(exitListener, times(0)).onEvent(event.capture());
navigateBackByFragment();
verify(exitListener, times(1)).onEvent(event.capture());
}
@Test
public void should_post_app_exit_event_on_the_last_back_of_fast_back_navigation() {
//mock the subscriber
class AppExitListener {
public void onEvent(NavigationManager.Event.OnAppExit event) {
}
}
ArgumentCaptor<NavigationManager.Event.OnAppExit> event
= ArgumentCaptor.forClass(NavigationManager.Event.OnAppExit.class);
AppExitListener exitListener = mock(AppExitListener.class);
eventBusC.register(exitListener);
prepareLocationHistory();
reset(exitListener);
navigationManager.navigate(this).back(null);
verify(exitListener, times(0)).onEvent(event.capture());
navigateBackByFragment();
verify(exitListener, times(1)).onEvent(event.capture());
Assert.assertTrue(this == event.getValue().getSender());
}
@Test
public void should_not_raise_navigate_back_event_when_navigate_to_first_location_from_the_first_location() throws Exception {
// Arrange
BackListener backListener = mock(BackListener.class);
eventBusC.register(backListener);
navigationManager.navigate(this).to(locId1);
// Arrange
Navigator navigator = navigationManager.navigate(this);
navigator.back(null);
// Verify
ArgumentCaptor<NavigationManager.Event.OnLocationBack> event
= ArgumentCaptor.forClass(NavigationManager.Event.OnLocationBack.class);
verify(backListener, times(0)).onEvent(event.capture());
}
@Test
public void should_not_raise_navigate_back_event_when_navigate_to_unknown_location() throws Exception {
// Arrange
BackListener backListener = mock(BackListener.class);
eventBusC.register(backListener);
prepareLocationHistory();
// Arrange
navigationManager.navigate(this).back(Controller.class);
// Verify
ArgumentCaptor<NavigationManager.Event.OnLocationBack> event
= ArgumentCaptor.forClass(NavigationManager.Event.OnLocationBack.class);
verify(backListener, times(0)).onEvent(event.capture());
}
@Test
public void should_not_raise_navigate_back_event_when_fast_back_navigate_from_null_location() throws Exception {
// Arrange
BackListener backListener = mock(BackListener.class);
eventBusC.register(backListener);
// Arrange
navigationManager.navigate(this).back(Controller1.class);
// Verify
ArgumentCaptor<NavigationManager.Event.OnLocationBack> event
= ArgumentCaptor.forClass(NavigationManager.Event.OnLocationBack.class);
verify(backListener, times(0)).onEvent(event.capture());
}
@Test
public void should_be_able_to_log_navigation_history_with_trace_enabled() throws Exception {
// Arrange
Logger logger = mock(Logger.class);
when(logger.isTraceEnabled()).thenReturn(true);
navigationManager.dumpHistoryOnLocationChange = true;
navigationManager.logger = logger;
// Act
navigationManager.navigate(this).to(Controller1.class, new Forwarder().clearTo(Controller.class));
// Verify
verify(logger, atLeast(1)).trace(anyString());
// Arrange
reset(logger);
// Act
navigationManager.navigate(this).to(Controller1.class);
// Verify
verify(logger, atLeast(1)).trace(anyString());
// Arrange
reset(logger);
// Act
navigateBackByFragment();
// Verify
verify(logger, atLeast(1)).trace(anyString());
// Arrange
reset(logger);
navigationManager.navigate(this).to(Controller1.class);
// Act
navigationManager.navigate(this).back(null);
// Verify
verify(logger, atLeast(1)).trace(anyString());
}
@Test
public void should_not_log_navigation_history_without_trace_eanbled() throws Exception {
// Arrange
Logger logger = mock(Logger.class);
when(logger.isTraceEnabled()).thenReturn(false);
navigationManager.dumpHistoryOnLocationChange = true;
navigationManager.logger = logger;
// Act
navigationManager.navigate(this).to(Controller1.class, new Forwarder().clearTo(Controller.class));
// Verify
verify(logger, atLeast(0)).trace(anyString());
// Arrange
reset(logger);
// Act
navigationManager.navigate(this).to(Controller1.class);
// Verify
verify(logger, atLeast(0)).trace(anyString());
// Arrange
reset(logger);
// Act
navigateBackByFragment();
// Verify
verify(logger, atLeast(0)).trace(anyString());
// Arrange
reset(logger);
navigationManager.navigate(this).to(Controller1.class);
// Act
navigationManager.navigate(this).back(null);
// Verify
verify(logger, atLeast(0)).trace(anyString());
}
private static class TimerFragmentX2 {
@Inject
@Slower2
private TimerController timerController;
}
private static class TimerFragmentX3 {
@Inject
@Slower3
private TimerController timerController;
}
@Qualifier
@Retention(RUNTIME)
@interface Slower2 {
}
@Qualifier
@Retention(RUNTIME)
@interface Slower3 {
}
@Slower2
@Slower3
static class SlowXHolder {
}
@Test(expected = MvcGraphException.class)
public void should_catch_invocation_exception_when_NPE_detected_on_injection() throws Exception {
Object com = new Object() {
@Provides
@Singleton
@Slower2
TimerController timerSlowerX2() {
return new TimerController() {
{
onCreated();
}
@Override
public void setInitialValue(long value) {
super.setInitialValue(value * 2);
}
};
}
};
graph.getRootComponent().register(com);
Annotation slower2Qualifier = SlowXHolder.class.getAnnotation(Slower2.class);
graph.use(TimerController.class, slower2Qualifier, new Consumer<TimerController>() {
@Override
public void consume(TimerController instance) {
//Controller should have now been released
Assert.assertEquals(0, instance.getInitialValue());
}
});
graph.getRootComponent().unregister(com);
}
@Test
public void should_retain_prepared_instance_until_navigation_settled() throws Exception {
// Arrange
final long fiveMinutes = 60 * 5;
Object module = new Object() {
@Provides
@Slower2
TimerController timerSlowerX2() {
return new TimerController() {
{
try {
onCreated();
} catch (Exception e) {
}
}
@Override
public void setInitialValue(long value) {
super.setInitialValue(value * 2);
}
};
}
@Provides
@Slower3
TimerController timerSlowerX3() {
return new TimerController() {
{
try {
onCreated();
} catch (Exception e) {
}
}
@Override
public void setInitialValue(long value) {
super.setInitialValue(value * 3);
}
};
}
};
Mvc.graph().getRootComponent().register(module);
Annotation slower2Qualifier = SlowXHolder.class.getAnnotation(Slower2.class);
Annotation slower3Qualifier = SlowXHolder.class.getAnnotation(Slower3.class);
Mvc.graph().use(TimerController.class, slower2Qualifier, new Consumer<TimerController>() {
@Override
public void consume(TimerController instance) {
//Controller should have now been released
Assert.assertEquals(0, instance.getInitialValue());
}
});
// Act
Navigator navigator = navigationManager.navigate(this).with(TimerController.class, slower2Qualifier, new Preparer<TimerController>() {
@Override
public void prepare(TimerController instance) {
instance.setInitialValue(fiveMinutes);
}
});
navigator.to(TimerController.class);
Mvc.graph().use(TimerController.class, slower2Qualifier, new Consumer<TimerController>() {
@Override
public void consume(TimerController instance) {
//Controller should not have been released yet
Assert.assertEquals(fiveMinutes * 2, instance.getInitialValue());
}
});
//destroy the navigator
navigator.destroy();
Mvc.graph().use(TimerController.class, slower2Qualifier, new Consumer<TimerController>() {
@Override
public void consume(TimerController instance) {
//Controller should have now been released
Assert.assertEquals(0, instance.getInitialValue());
}
});
//Test fragment 3
Mvc.graph().use(TimerController.class, slower3Qualifier, new Consumer<TimerController>() {
@Override
public void consume(TimerController instance) {
//Controller should have now been released
Assert.assertEquals(0, instance.getInitialValue());
}
});
navigator = navigationManager.navigate(this).with(TimerController.class, slower3Qualifier, new Preparer<TimerController>() {
@Override
public void prepare(TimerController instance) {
instance.setInitialValue(fiveMinutes);
}
});
navigator.to(TimerController.class);
Mvc.graph().use(TimerController.class, slower3Qualifier, new Consumer<TimerController>() {
@Override
public void consume(TimerController instance) {
//Controller should not have been released yet
Assert.assertEquals(fiveMinutes * 3, instance.getInitialValue());
}
});
//destroy the navigator
navigator.destroy();
Mvc.graph().use(TimerController.class, slower3Qualifier, new Consumer<TimerController>() {
@Override
public void consume(TimerController instance) {
//Controller should have now been released
Assert.assertEquals(0, instance.getInitialValue());
}
});
Mvc.graph().getRootComponent().unregister(module);
}
private static class TimerFragment {
@Inject
private TimerController timerController;
}
@Test
public void should_retain_prepared_instance_until_navigation_settled_without_qualifier() throws Exception {
// Arrange
final long fiveMinutes = 60 * 5;
// Act
Navigator navigator = navigationManager.navigate(this).with(TimerController.class, new Preparer<TimerController>() {
@Override
public void prepare(TimerController instance) {
instance.setInitialValue(fiveMinutes);
}
});
navigator.to(TimerController.class);
Mvc.graph().use(TimerController.class, null, new Consumer<TimerController>() {
@Override
public void consume(TimerController instance) {
//Controller should not have been released yet
Assert.assertEquals(fiveMinutes, instance.getInitialValue());
}
});
//destroy the navigator
navigator.destroy();
Mvc.graph().use(TimerController.class, new Consumer<TimerController>() {
@Override
public void consume(TimerController instance) {
//Controller should have now been released
Assert.assertEquals(0, instance.getInitialValue());
}
});
}
@Test
public void should_invoke_singular_argument_with_method_of_navigator_correct() throws Exception {
Navigator navigator = navigationManager.navigate(this);
Navigator spiedNavigator = spy(navigator);
verify(spiedNavigator, times(0)).with(eq(NavigationManager.class), isNull(Annotation.class), isNull(Preparer.class));
spiedNavigator.with(NavigationManager.class);
verify(spiedNavigator).with(eq(NavigationManager.class), isNull(Annotation.class), isNull(Preparer.class));
}
@Test
public void should_return_correct_sender_by_navigator() throws Exception {
// Act
Navigator navigator = navigationManager.navigate(this);
Assert.assertTrue(this == navigator.getSender());
}
@Test
public void should_invoke_on_settled_when_navigation_is_done() throws Exception {
// Arrange
Navigator.OnSettled onSettled = mock(Navigator.OnSettled.class);
// Act
Navigator navigator = navigationManager.navigate(this).with(TimerController.class)
.onSettled(onSettled);
navigator.to(TimerController.class);
verify(onSettled, times(0)).run();
//destroy the navigator
navigator.destroy();
verify(onSettled, times(1)).run();
}
@Test
public void interim_forwarder_should_instruct_navigation_not_push_location_to_back_stack(){
ForwardListener forwardListener = mock(ForwardListener.class);
eventBusC.register(forwardListener);
// Act
Navigator navigator = navigationManager.navigate(this);
Forwarder forwarder = new Forwarder();
Assert.assertFalse(forwarder.isInterim());
forwarder.setInterim(true);
Assert.assertTrue(forwarder.isInterim());
navigator.to(TimerController.class, forwarder);
ArgumentCaptor<NavigationManager.Event.OnLocationForward> event
= ArgumentCaptor.forClass(NavigationManager.Event.OnLocationForward.class);
verify(forwardListener).onEvent(event.capture());
assertEquals(event.getValue().getCurrentValue().getLocationId(), TimerController.class.getName());
assertTrue(event.getValue().getCurrentValue().isInterim());
Assert.assertTrue(this == event.getValue().getSender());
Assert.assertTrue(navigator == event.getValue().getNavigator());
}
/**
* Prepare 4 locations in the history
*/
private ForwardListener prepareLocationHistory() {
//mock the subscriber
ForwardListener forwardListener = mock(ForwardListener.class);
eventBusC.register(forwardListener);
navigationManager.navigate(this).to(locId1);
ArgumentCaptor<NavigationManager.Event.OnLocationForward> event =
ArgumentCaptor.forClass(NavigationManager.Event.OnLocationForward.class);
verify(forwardListener).onEvent(event.capture());
assertEquals(event.getValue().getLastValue(), null);
assertEquals(event.getValue().getCurrentValue().getLocationId(), locId1.getName());
assertEquals(event.getValue().getLocationWhereHistoryClearedUpTo(), null);
assertEquals(event.getValue().isClearHistory(), false);
reset(forwardListener);
navigationManager.navigate(this).to(locId2);
event = ArgumentCaptor.forClass(NavigationManager.Event.OnLocationForward.class);
verify(forwardListener).onEvent(event.capture());
assertEquals(event.getValue().getLastValue().getLocationId(), locId1.getName());
assertEquals(event.getValue().getCurrentValue().getLocationId(), locId2.getName());
assertEquals(event.getValue().getLocationWhereHistoryClearedUpTo(), null);
assertEquals(event.getValue().isClearHistory(), false);
reset(forwardListener);
navigationManager.navigate(this).to(locId3);
event = ArgumentCaptor.forClass(NavigationManager.Event.OnLocationForward.class);
verify(forwardListener).onEvent(event.capture());
assertEquals(event.getValue().getLastValue().getLocationId(), locId2.getName());
assertEquals(event.getValue().getCurrentValue().getLocationId(), locId3.getName());
assertEquals(event.getValue().getLocationWhereHistoryClearedUpTo(), null);
assertEquals(event.getValue().isClearHistory(), false);
reset(forwardListener);
navigationManager.navigate(this).to(locId4);
event = ArgumentCaptor.forClass(NavigationManager.Event.OnLocationForward.class);
verify(forwardListener).onEvent(event.capture());
assertEquals(event.getValue().getLastValue().getLocationId(), locId3.getName());
assertEquals(event.getValue().getCurrentValue().getLocationId(), locId4.getName());
assertEquals(event.getValue().getLocationWhereHistoryClearedUpTo(), null);
assertEquals(event.getValue().isClearHistory(), false);
return forwardListener;
}
}