Commit ca6220fe authored by d4vidi's avatar d4vidi

Add more Android UT + refactoring

parent 6b12adb8
......@@ -26,5 +26,5 @@ dependencies {
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:2.+'
testCompile "org.robolectric:robolectric:3.1.4"
testCompile 'org.robolectric:robolectric:3.1.4'
}
......@@ -39,7 +39,7 @@ public class AppLaunchHelper {
return activityName.equals(launchIntentActivityName);
}
public boolean isLaunchIntent(Intent intent) {
public boolean isLaunchIntentOfNotification(Intent intent) {
return intent.getBooleanExtra(LAUNCH_FLAG_KEY_NAME, false);
}
}
......@@ -5,18 +5,35 @@ import android.support.annotation.Nullable;
import com.wix.reactnativenotifications.core.notification.PushNotificationProps;
public class InitialNotification {
private static PushNotificationProps sNotification;
public static void set(PushNotificationProps pushNotificationProps) {
sNotification = pushNotificationProps;
private static InitialNotification sInstance;
private PushNotificationProps mNotification;
public static void setInstance(InitialNotification instance) {
sInstance = instance;
}
/*package*/ InitialNotification() {
}
public static InitialNotification getInstance() {
if (sInstance == null) {
sInstance = new InitialNotification();
}
return sInstance;
}
public void set(PushNotificationProps pushNotificationProps) {
mNotification = pushNotificationProps;
}
public static void clear() {
sNotification = null;
public void clear() {
mNotification = null;
}
@Nullable
public static PushNotificationProps get() {
return sNotification;
public PushNotificationProps get() {
return mNotification;
}
}
......@@ -7,8 +7,6 @@ import android.util.Log;
import com.wix.reactnativenotifications.core.notification.IPushNotification;
import com.wix.reactnativenotifications.core.notification.PushNotification;
import com.wix.reactnativenotifications.core.notificationdrawer.IPushNotificationsDrawer;
import com.wix.reactnativenotifications.core.notificationdrawer.PushNotificationsDrawer;
public class ProxyService extends IntentService {
......@@ -26,8 +24,5 @@ public class ProxyService extends IntentService {
if (pushNotification != null) {
pushNotification.onOpened();
}
final IPushNotificationsDrawer pushNotificationDrawer = PushNotificationsDrawer.get(this);
pushNotificationDrawer.onNotificationOpened();
}
}
......@@ -58,7 +58,7 @@ public class RNNotificationsModule extends ReactContextBaseJavaModule implements
Object result = null;
try {
final PushNotificationProps notification = InitialNotification.get();
final PushNotificationProps notification = InitialNotification.getInstance().get();
if (notification == null) {
return;
}
......
......@@ -67,6 +67,7 @@ public class PushNotification implements IPushNotification {
@Override
public void onOpened() {
digestNotification();
clearAllNotifications();
}
@Override
......@@ -109,7 +110,7 @@ public class PushNotification implements IPushNotification {
}
protected void setAsInitialNotification() {
InitialNotification.set(mNotificationProps);
InitialNotification.getInstance().set(mNotificationProps);
}
protected void dispatchImmediately() {
......@@ -158,6 +159,11 @@ public class PushNotification implements IPushNotification {
notificationManager.notify(id, notification);
}
protected void clearAllNotifications() {
final NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
}
protected int createNotificationId(Notification notification) {
return (int) System.nanoTime();
}
......
......@@ -2,6 +2,8 @@ package com.wix.reactnativenotifications.core.notificationdrawer;
import android.content.Context;
import com.wix.reactnativenotifications.core.AppLaunchHelper;
public interface INotificationsDrawerApplication {
IPushNotificationsDrawer getPushNotificationsDrawer(Context context);
IPushNotificationsDrawer getPushNotificationsDrawer(Context context, AppLaunchHelper defaultAppLaunchHelper);
}
......@@ -19,7 +19,7 @@ public class PushNotificationsDrawer implements IPushNotificationsDrawer {
public static IPushNotificationsDrawer get(Context context, AppLaunchHelper appLaunchHelper) {
final Context appContext = context.getApplicationContext();
if (appContext instanceof INotificationsDrawerApplication) {
return ((INotificationsDrawerApplication) appContext).getPushNotificationsDrawer(context);
return ((INotificationsDrawerApplication) appContext).getPushNotificationsDrawer(context, appLaunchHelper);
}
return new PushNotificationsDrawer(context, appLaunchHelper);
......@@ -42,9 +42,10 @@ public class PushNotificationsDrawer implements IPushNotificationsDrawer {
@Override
public void onNewActivity(Activity activity) {
if (mAppLaunchHelper.isLaunchIntentsActivity(activity) &&
!mAppLaunchHelper.isLaunchIntent(activity.getIntent())) {
InitialNotification.clear();
boolean launchIntentsActivity = mAppLaunchHelper.isLaunchIntentsActivity(activity);
boolean launchIntentOfNotification = mAppLaunchHelper.isLaunchIntentOfNotification(activity.getIntent());
if (launchIntentsActivity && !launchIntentOfNotification) {
InitialNotification.getInstance().clear();
}
}
......
package com.wix.reactnativenotifications.core;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
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 static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(RobolectricTestRunner.class)
public class AppLaunchHelperTest {
private static final String LAUNCHED_FROM_NOTIF_BOOLEAN_EXTRA_NAME = "launchedFromNotification";
static class ActivityMock extends Activity {
}
private final String APP_PACKAGE_NAME = "the.package";
private final String APP_MAIN_ACTIVITY_NAME = ActivityMock.class.getName();
@Mock private Context mContext;
@Mock private PackageManager mPackageManager;
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
when(mContext.getApplicationContext()).thenReturn(mContext);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mContext.getPackageName()).thenReturn(APP_PACKAGE_NAME);
// Set-up the intent (mock) returned by the SDK for getLaunchIntentForPackage()
Intent intent = mock(Intent.class);
when(intent.getComponent()).thenReturn(new ComponentName(APP_PACKAGE_NAME, APP_MAIN_ACTIVITY_NAME));
when(mPackageManager.getLaunchIntentForPackage(eq(APP_PACKAGE_NAME))).thenReturn(intent);
}
@Test
public void getLaunchIntent__returnsCustomIntentWithNotifFlagExtra() throws Exception {
final AppLaunchHelper uut = getUUT();
Intent intent = uut.getLaunchIntent(mContext);
assertNotNull(intent);
assertEquals(APP_PACKAGE_NAME, intent.getComponent().getPackageName());
assertEquals(APP_MAIN_ACTIVITY_NAME, intent.getComponent().getClassName());
assertEquals(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED, intent.getFlags());
assertTrue(intent.getBooleanExtra(LAUNCHED_FROM_NOTIF_BOOLEAN_EXTRA_NAME, false));
}
@Test
public void isLaunchIntentsActivity_activityIsMainLauncherActivity_returnTrue() throws Exception {
Activity activity = getActivityMock(APP_MAIN_ACTIVITY_NAME);
final AppLaunchHelper uut = getUUT();
boolean result = uut.isLaunchIntentsActivity(activity);
assertTrue(result);
}
@Test
public void isLaunchIntentsActivity_activityIsNotMainActivity_returnFalse() throws Exception {
Activity activity = getActivityMock("other.activity");
final AppLaunchHelper uut = getUUT();
boolean result = uut.isLaunchIntentsActivity(activity);
assertFalse(result);
}
@Test
public void isLaunchIntentOfNotification_hasFlagInBundle_returnTrue() throws Exception {
Intent intent = mock(Intent.class);
when(intent.getBooleanExtra(eq(LAUNCHED_FROM_NOTIF_BOOLEAN_EXTRA_NAME), eq(false))).thenReturn(true);
final AppLaunchHelper uut = getUUT();
boolean result = uut.isLaunchIntentOfNotification(intent);
assertTrue(result);
}
@Test
public void isLaunchIntentOfNotification_noFlagInBundle_returnFalse() throws Exception {
Intent intent = mock(Intent.class);
final AppLaunchHelper uut = getUUT();
boolean result = uut.isLaunchIntentOfNotification(intent);
assertFalse(result);
}
protected Activity getActivityMock(String activityClassName) {
Activity activity = mock(Activity.class);
when(activity.getPackageManager()).thenReturn(mPackageManager);
when(activity.getPackageName()).thenReturn(APP_PACKAGE_NAME);
when(activity.getComponentName()).thenReturn(new ComponentName(APP_PACKAGE_NAME, activityClassName));
when(activity.getLocalClassName()).thenReturn(activityClassName);
return activity;
}
private AppLaunchHelper getUUT() {
return new AppLaunchHelper();
}
}
\ No newline at end of file
package com.wix.reactnativenotifications.core;
import com.wix.reactnativenotifications.core.notification.PushNotificationProps;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
@RunWith(MockitoJUnitRunner.class)
public class InitialNotificationTest {
@Test
public void initialState() throws Exception {
final InitialNotification uut = createUUT();
assertNull(uut.get());
}
@Test
public void setsInitialNotification() throws Exception {
PushNotificationProps props = mock(PushNotificationProps.class);
final InitialNotification uut = createUUT();
uut.set(props);
assertEquals(props, uut.get());
}
@Test
public void clearsInitialNotification() throws Exception {
PushNotificationProps props = mock(PushNotificationProps.class);
final InitialNotification uut = createUUT();
uut.set(props);
uut.clear();
assertNull(uut.get());
}
@Test
public void replacesInitialNotification() throws Exception {
PushNotificationProps props1 = mock(PushNotificationProps.class);
PushNotificationProps props2 = mock(PushNotificationProps.class);
final InitialNotification uut = createUUT();
uut.set(props1);
uut.set(props2);
assertNotEquals(props1, props2);
assertEquals(props2, uut.get());
}
@Test
public void isALazySingleton() throws Exception {
final InitialNotification instance = InitialNotification.getInstance();
assertNotNull(instance);
assertEquals(instance, InitialNotification.getInstance());
}
private InitialNotification createUUT() {
return new InitialNotification();
}
}
\ No newline at end of file
package com.wix.reactnativenotifications.core;
import android.os.Bundle;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class JsIOHelperTest {
@Mock DeviceEventManagerModule.RCTDeviceEventEmitter mRCTDeviceEventEmitter;
@Mock ReactContext mReactContext;
@Before
public void setup() throws Exception {
when(mReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)).thenReturn(mRCTDeviceEventEmitter);
}
@Test
public void sendEventToJS_hasReactContext_emitsEventToJs() throws Exception {
WritableMap data = mock(WritableMap.class);
final JsIOHelper uut = createUUT();
boolean result = uut.sendEventToJS("my-event", data, mReactContext);
assertTrue(result);
verify(mRCTDeviceEventEmitter).emit("my-event", data);
}
@Test
public void sendEventToJS_noReactContext_returnsFalse() throws Exception {
WritableMap data = mock(WritableMap.class);
final JsIOHelper uut = createUUT();
boolean result = uut.sendEventToJS("my-event", data, null);
assertFalse(result);
verify(mRCTDeviceEventEmitter, never()).emit(anyString(), any(WritableMap.class));
}
private JsIOHelper createUUT() {
return new JsIOHelper();
}
}
package com.wix.reactnativenotifications.core.notification;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
......@@ -11,6 +12,7 @@ import com.facebook.react.bridge.ReactContext;
import com.wix.reactnativenotifications.core.AppLaunchHelper;
import com.wix.reactnativenotifications.core.AppLifecycleFacade;
import com.wix.reactnativenotifications.core.AppLifecycleFacade.AppVisibilityListener;
import com.wix.reactnativenotifications.core.InitialNotification;
import com.wix.reactnativenotifications.core.JsIOHelper;
import org.junit.Before;
......@@ -56,6 +58,7 @@ public class PushNotificationTest {
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
InitialNotification.setInstance(mock(InitialNotification.class));
when(mDefaultBundle.getString(eq("title"))).thenReturn(DEFAULT_NOTIFICATION_TITLE);
when(mDefaultBundle.getString(eq("body"))).thenReturn(DEFAULT_NOTIFICATION_BODY);
......@@ -84,6 +87,18 @@ public class PushNotificationTest {
verify(mAppLifecycleFacade, never()).addVisibilityListener(any(AppVisibilityListener.class));
}
@Test
public void onOpened_noReactContext_setAsInitialNotification() throws Exception {
when(mAppLifecycleFacade.isReactInitialized()).thenReturn(false);
Activity currentActivity = mock(Activity.class);
when(mReactContext.getCurrentActivity()).thenReturn(currentActivity);
final PushNotification uut = createUUT();
uut.onOpened();
verify(InitialNotification.getInstance()).set(any(PushNotificationProps.class));
}
@Test
public void onOpened_appInvisible_resumeAppWaitForVisibility() throws Exception {
setUpBackgroundApp();
......@@ -95,6 +110,18 @@ public class PushNotificationTest {
verify(mAppLifecycleFacade).addVisibilityListener(any(AppVisibilityListener.class));
}
@Test
public void onOpened_appInvisible_dontSetInitialNotification() throws Exception {
setUpBackgroundApp();
Activity currentActivity = mock(Activity.class);
when(mReactContext.getCurrentActivity()).thenReturn(currentActivity);
final PushNotification uut = createUUT();
uut.onOpened();
verify(InitialNotification.getInstance(), never()).set(any(PushNotificationProps.class));
}
@Test
public void onOpened_appGoesVisible_resumeAppAndNotifyJs() throws Exception {
......@@ -129,6 +156,40 @@ public class PushNotificationTest {
verify(mJsIOHelper).sendEventToJS(eq(NOTIFICATION_OPENED_EVENT_NAME), eq(mDefaultBundle), eq(mReactContext));
}
@Test
public void onOpened_appVisible_clearNotificationsDrawer() throws Exception {
verify(mNotificationManager, never()).cancelAll();
setUpForegroundApp();
final PushNotification uut = createUUT();
uut.onOpened();
verify(mNotificationManager).cancelAll();
}
@Test
public void onOpened_appVisible_dontSetInitialNotification() throws Exception {
setUpForegroundApp();
Activity currentActivity = mock(Activity.class);
when(mReactContext.getCurrentActivity()).thenReturn(currentActivity);
final PushNotification uut = createUUT();
uut.onOpened();
verify(InitialNotification.getInstance(), never()).set(any(PushNotificationProps.class));
}
@Test
public void onOpened_reactInitializedWithNoActivities_setAsInitialNotification() throws Exception {
setUpBackgroundApp();
when(mReactContext.getCurrentActivity()).thenReturn(null); // Just for clarity
final PushNotification uut = createUUT();
uut.onOpened();
verify(InitialNotification.getInstance()).set(any(PushNotificationProps.class));
}
@Test
public void onReceived_validData_postNotificationAndNotifyJS() throws Exception {
// Arrange
......
package com.wix.reactnativenotifications.core.notificationdrawer;
import android.app.Activity;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import com.facebook.react.bridge.ReactContext;
import com.wix.reactnativenotifications.core.AppLaunchHelper;
import com.wix.reactnativenotifications.core.InitialNotification;
import org.junit.Before;
import org.junit.Test;
......@@ -13,7 +16,9 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
......@@ -30,6 +35,7 @@ public class PushNotificationsDrawerTest {
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
InitialNotification.setInstance(mock(InitialNotification.class));
when(mContext.getSystemService(Context.NOTIFICATION_SERVICE)).thenReturn(mNotificationManager);
}
......@@ -45,12 +51,6 @@ public class PushNotificationsDrawerTest {
verify(mNotificationManager).cancelAll();
}
@Test
public void onNotificationOpened_clearAllNotifications() throws Exception {
createUUT().onNotificationOpened();
verify(mNotificationManager).cancelAll();
}
@Test
public void onNotificationClearRequest_clearSpecificNotification() throws Exception {
createUUT().onNotificationClearRequest(666);
......@@ -58,6 +58,47 @@ public class PushNotificationsDrawerTest {
verify(mNotificationManager, never()).cancelAll();
}
@Test
public void onNewActivity_activityIsTheOneLaunchedByNotifs_clearInitialNotification() throws Exception {
verify(InitialNotification.getInstance(), never()).clear();
Activity activity = mock(Activity.class);
Intent intent = mock(Intent.class);
when(activity.getIntent()).thenReturn(intent);
when(mAppLaunchHelper.isLaunchIntentsActivity(activity)).thenReturn(true);
when(mAppLaunchHelper.isLaunchIntentOfNotification(any(Intent.class))).thenReturn(false);
createUUT().onNewActivity(activity);
verify(InitialNotification.getInstance()).clear();
}
@Test
public void onNewActivity_activityIsNotTheOneLaunchedByNotifs_dontClearInitialNotification() throws Exception {
Activity activity = mock(Activity.class);
Intent intent = mock(Intent.class);
when(activity.getIntent()).thenReturn(intent);
when(mAppLaunchHelper.isLaunchIntentsActivity(activity)).thenReturn(false);
when(mAppLaunchHelper.isLaunchIntentOfNotification(any(Intent.class))).thenReturn(false);
createUUT().onNewActivity(activity);
verify(InitialNotification.getInstance(), never()).clear();
}
@Test
public void onNewActivity_activityLaunchedFromPushNotification_dontClearInitialNotification() throws Exception {
Activity activity = mock(Activity.class);
Intent intent = mock(Intent.class);
when(activity.getIntent()).thenReturn(intent);
when(mAppLaunchHelper.isLaunchIntentsActivity(activity)).thenReturn(true);
when(mAppLaunchHelper.isLaunchIntentOfNotification(eq(intent))).thenReturn(true);
createUUT().onNewActivity(activity);
verify(InitialNotification.getInstance(), never()).clear();
}
protected PushNotificationsDrawer createUUT() {
return new PushNotificationsDrawer(mContext, mAppLaunchHelper);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment