package io.nlopez.smartlocation.location.providers; import android.content.Context; import android.location.Location; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.annotation.Config; import java.util.Collection; import java.util.Iterator; import io.nlopez.smartlocation.CustomTestRunner; import io.nlopez.smartlocation.OnLocationUpdatedListener; import io.nlopez.smartlocation.location.LocationProvider; import io.nlopez.smartlocation.location.config.LocationParams; import io.nlopez.smartlocation.utils.Logger; import io.nlopez.smartlocation.utils.ServiceConnectionListener; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.mockito.Mockito.verify; /** * Unit tests for the {@link MultiFallbackProvider} * * @author abkaplan07 */ @RunWith(CustomTestRunner.class) @Config(manifest=Config.NONE) public class MultiFallbackProviderTest { @Test public void testDefaultBuilder() { MultiFallbackProvider subject = new MultiFallbackProvider.Builder().build(); checkExpectedProviders(subject, LocationManagerProvider.class); } @Test public void testGoogleBuilder() { MultiFallbackProvider subject = new MultiFallbackProvider.Builder() .withGooglePlayServicesProvider().build(); checkExpectedProviders(subject, LocationGooglePlayServicesProvider.class); } @Test public void testMultiProviderBuilder() { MultiFallbackProvider subject = new MultiFallbackProvider.Builder() .withGooglePlayServicesProvider().withDefaultProvider().build(); checkExpectedProviders(subject, LocationGooglePlayServicesProvider.class, LocationManagerProvider.class); } @Test public void testMultiProviderRun() { TestServiceProvider testServiceProvider = new TestServiceProvider(); ServiceConnectionListener mockListener = mock(ServiceConnectionListener.class); testServiceProvider.setServiceListener(mockListener); LocationProvider backupProvider = mock(LocationProvider.class); MultiFallbackProvider subject = new MultiFallbackProvider.Builder().withServiceProvider (testServiceProvider).withProvider(backupProvider).build(); // Test initialization passes through to first provider subject.init(mock(Context.class), mock(Logger.class)); assertEquals(1, testServiceProvider.getInitCount()); // Test starting location updates passes through to first provider OnLocationUpdatedListener listenerMock = mock(OnLocationUpdatedListener.class); LocationParams paramsMock = mock(LocationParams.class); subject.start(listenerMock, paramsMock, false); assertEquals(1, testServiceProvider.getStartCount()); // Test that falling back initializes and starts the backup provider testServiceProvider.simulateFailure(); // Ensure that our 1st listener from the test service provider was invoked. verify(mockListener).onConnectionFailed(); assertEquals(1, testServiceProvider.getStopCount()); // Verify that the backup provider is initialized and started. verify(backupProvider).init(any(Context.class), any(Logger.class)); verify(backupProvider).start(listenerMock, paramsMock, false); // Test that we're now using the fallback provider to stop. subject.stop(); verify(backupProvider).stop(); assertEquals(1, testServiceProvider.getStopCount()); // Test that we're now using the fallback provider to get the last location Location mockLocation = mock(Location.class); when(backupProvider.getLastLocation()).thenReturn(mockLocation); assertEquals(mockLocation, subject.getLastLocation()); assertEquals(0, testServiceProvider.getLastLocCount()); } @SafeVarargs private final void checkExpectedProviders(MultiFallbackProvider subject, Class<? extends LocationProvider>... expectedProviders) { Collection<LocationProvider> providers = subject.getProviders(); assertEquals(expectedProviders.length, providers.size()); Iterator<LocationProvider> providerIt = providers.iterator(); for (int i = 0; i < expectedProviders.length; i++) { Class<? extends LocationProvider> expected = expectedProviders[i]; if (!providerIt.hasNext()) { fail("providers list did not have expected value " + expected.getName()); } LocationProvider actual = providerIt.next(); assertTrue("provider instance class " + actual.getClass().getName() + " does not " + "match expected value " + expected.getName(), actual.getClass() .isAssignableFrom(expected)); } } }