package co.smartreceipts.android.push;
import android.os.Bundle;
import com.google.firebase.messaging.RemoteMessage;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import java.lang.reflect.Constructor;
import co.smartreceipts.android.analytics.Analytics;
import co.smartreceipts.android.identity.IdentityManager;
import co.smartreceipts.android.identity.apis.me.MeResponse;
import co.smartreceipts.android.push.apis.me.UpdatePushTokensRequest;
import co.smartreceipts.android.push.internal.FcmTokenRetriever;
import co.smartreceipts.android.push.store.PushDataStore;
import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.schedulers.Schedulers;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(RobolectricTestRunner.class)
public class PushManagerTest {
private static final String TOKEN = "token";
// Class under test
PushManager pushManager;
@Mock
IdentityManager identityManager;
@Mock
Analytics analytics;
@Mock
FcmTokenRetriever fcmTokenRetriever;
@Mock
PushDataStore pushDataStore;
@Mock
PushMessageReceiver receiver1, receiver2, receiver3;
@Mock
MeResponse meResponse;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
pushManager = new PushManager(identityManager, analytics, fcmTokenRetriever, pushDataStore, Schedulers.trampoline());
}
@Test
public void initializeWhenNotRequired() throws Exception {
when(pushDataStore.isRemoteRefreshRequiredSingle()).thenReturn(Single.just(false));
when(identityManager.isLoggedInStream()).thenReturn(Observable.just(true));
when(fcmTokenRetriever.getFcmTokenObservable()).thenReturn(Observable.just(TOKEN));
when(identityManager.updateMe(any(UpdatePushTokensRequest.class))).thenReturn(Observable.just(meResponse));
pushManager.initialize();
verify(identityManager, never()).updateMe(any(UpdatePushTokensRequest.class));
verify(pushDataStore, never()).setRemoteRefreshRequired(false);
}
@Test
public void initializeWhenNotLoggedIn() throws Exception {
when(pushDataStore.isRemoteRefreshRequiredSingle()).thenReturn(Single.just(true));
when(identityManager.isLoggedInStream()).thenReturn(Observable.just(false));
when(fcmTokenRetriever.getFcmTokenObservable()).thenReturn(Observable.just(TOKEN));
when(identityManager.updateMe(any(UpdatePushTokensRequest.class))).thenReturn(Observable.just(meResponse));
pushManager.initialize();
verify(identityManager, never()).updateMe(any(UpdatePushTokensRequest.class));
verify(pushDataStore, never()).setRemoteRefreshRequired(false);
}
@Test
public void initializeWithNetworkError() throws Exception {
when(pushDataStore.isRemoteRefreshRequiredSingle()).thenReturn(Single.just(true));
when(identityManager.isLoggedInStream()).thenReturn(Observable.<Boolean>error(new Exception("test")));
when(fcmTokenRetriever.getFcmTokenObservable()).thenReturn(Observable.just(TOKEN));
when(identityManager.updateMe(any(UpdatePushTokensRequest.class))).thenReturn(Observable.just(meResponse));
pushManager.initialize();
verify(pushDataStore, never()).setRemoteRefreshRequired(false);
}
@Test
public void initialize() throws Exception {
when(pushDataStore.isRemoteRefreshRequiredSingle()).thenReturn(Single.just(true));
when(identityManager.isLoggedInStream()).thenReturn(Observable.just(true));
when(fcmTokenRetriever.getFcmTokenObservable()).thenReturn(Observable.just(TOKEN));
when(identityManager.updateMe(any(UpdatePushTokensRequest.class))).thenReturn(Observable.just(meResponse));
pushManager.initialize();
verify(pushDataStore).setRemoteRefreshRequired(false);
verify(identityManager).updateMe(any(UpdatePushTokensRequest.class));
}
@Test
public void onTokenRefreshWhenNotLoggedIn() throws Exception {
when(pushDataStore.isRemoteRefreshRequiredSingle()).thenReturn(Single.just(true));
when(identityManager.isLoggedInStream()).thenReturn(Observable.just(false));
when(fcmTokenRetriever.getFcmTokenObservable()).thenReturn(Observable.just(TOKEN));
when(identityManager.updateMe(any(UpdatePushTokensRequest.class))).thenReturn(Observable.just(meResponse));
pushManager.onTokenRefresh();
verify(pushDataStore).setRemoteRefreshRequired(true);
verify(identityManager, never()).updateMe(any(UpdatePushTokensRequest.class));
}
@Test
public void onTokenRefresh() throws Exception {
when(pushDataStore.isRemoteRefreshRequiredSingle()).thenReturn(Single.just(true));
when(identityManager.isLoggedInStream()).thenReturn(Observable.just(true));
when(fcmTokenRetriever.getFcmTokenObservable()).thenReturn(Observable.just(TOKEN));
when(identityManager.updateMe(any(UpdatePushTokensRequest.class))).thenReturn(Observable.just(meResponse));
pushManager.onTokenRefresh();
verify(pushDataStore).setRemoteRefreshRequired(true);
verify(pushDataStore).setRemoteRefreshRequired(false);
verify(identityManager).updateMe(any(UpdatePushTokensRequest.class));
}
@Test
public void onMessageReceived() throws Exception {
pushManager.registerReceiver(receiver1);
pushManager.registerReceiver(receiver2);
pushManager.registerReceiver(receiver3);
pushManager.unregisterReceiver(receiver3);
final Constructor<RemoteMessage> constructor = RemoteMessage.class.getDeclaredConstructor(Bundle.class);
constructor.setAccessible(true);
final RemoteMessage message = constructor.newInstance(new Bundle());
pushManager.onMessageReceived(message);
verify(receiver1).onMessageReceived(message);
verify(receiver2).onMessageReceived(message);
verify(receiver3, never()).onMessageReceived(message);
}
}