Skip to content

Commit 66889cc

Browse files
committed
Merge pull request #320 from Iterable/chore/MOB-2344-remove-powermock
[MOB-2344] Remove PowerMock
1 parent f8bb6cf commit 66889cc

File tree

4 files changed

+92
-119
lines changed

4 files changed

+92
-119
lines changed

iterableapi/build.gradle

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,6 @@ dependencies {
4747
testImplementation 'org.robolectric:robolectric:4.4'
4848
testImplementation 'org.robolectric:shadows-playservices:4.4'
4949
testImplementation 'org.khronos:opengl-api:gl1.1-android-2.1_r1'
50-
testImplementation "org.powermock:powermock-module-junit4:2.0.9"
51-
testImplementation "org.powermock:powermock-module-junit4-rule:2.0.9"
52-
testImplementation "org.powermock:powermock-api-mockito2:2.0.9"
53-
testImplementation "org.powermock:powermock-classloading-xstream:2.0.9"
5450
testImplementation 'com.squareup.okhttp3:mockwebserver:4.2.2'
5551
testImplementation 'org.skyscreamer:jsonassert:1.5.0'
5652
androidTestImplementation 'androidx.test:runner:1.3.0'

iterableapi/src/main/java/com/iterable/iterableapi/IterableActionRunner.java

Lines changed: 80 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -4,92 +4,108 @@
44
import android.content.Intent;
55
import android.content.pm.ResolveInfo;
66
import android.net.Uri;
7+
78
import androidx.annotation.NonNull;
89
import androidx.annotation.Nullable;
10+
import androidx.annotation.VisibleForTesting;
11+
912
import android.util.Log;
1013

1114
import java.util.List;
1215

1316
class IterableActionRunner {
14-
private static final String TAG = "IterableActionRunner";
15-
16-
/**
17-
* Execute an {@link IterableAction} as a response to push action
18-
* @param context Context
19-
* @param action The original action object
20-
* @return `true` if the action was handled, `false` if it was not
21-
*/
22-
static boolean executeAction(@NonNull Context context, @Nullable IterableAction action, @NonNull IterableActionSource source) {
23-
if (action == null) {
24-
return false;
25-
}
2617

27-
IterableActionContext actionContext = new IterableActionContext(action, source);
18+
@VisibleForTesting
19+
static IterableActionRunnerImpl instance = new IterableActionRunnerImpl();
2820

29-
if (action.isOfType(IterableAction.ACTION_TYPE_OPEN_URL)) {
30-
return openUri(context, Uri.parse(action.getData()), actionContext);
31-
} else {
32-
return callCustomActionIfSpecified(action, actionContext);
33-
}
21+
static boolean executeAction(@NonNull Context context, @Nullable IterableAction action, @NonNull IterableActionSource source) {
22+
return instance.executeAction(context, action, source);
3423
}
3524

36-
/**
37-
* Handle {@link IterableAction#ACTION_TYPE_OPEN_URL} action type
38-
* Calls {@link IterableUrlHandler} for custom handling by the app. If the handle does not exist
39-
* or returns `false`, the SDK tries to find an activity that can open this URL.
40-
* @param context Context
41-
* @param uri The URL to open
42-
* @param actionContext The original action object
43-
* @return `true` if the action was handled, or an activity was found for this URL
44-
* `false` if the handler did not handle this URL and no activity was found to open it with
45-
*/
46-
private static boolean openUri(@NonNull Context context, @NonNull Uri uri, @NonNull IterableActionContext actionContext) {
47-
if (IterableApi.sharedInstance.config.urlHandler != null) {
48-
if (IterableApi.sharedInstance.config.urlHandler.handleIterableURL(uri, actionContext)) {
49-
return true;
25+
static class IterableActionRunnerImpl {
26+
private static final String TAG = "IterableActionRunner";
27+
28+
/**
29+
* Execute an {@link IterableAction} as a response to push action
30+
*
31+
* @param context Context
32+
* @param action The original action object
33+
* @return `true` if the action was handled, `false` if it was not
34+
*/
35+
boolean executeAction(@NonNull Context context, @Nullable IterableAction action, @NonNull IterableActionSource source) {
36+
if (action == null) {
37+
return false;
38+
}
39+
40+
IterableActionContext actionContext = new IterableActionContext(action, source);
41+
42+
if (action.isOfType(IterableAction.ACTION_TYPE_OPEN_URL)) {
43+
return openUri(context, Uri.parse(action.getData()), actionContext);
44+
} else {
45+
return callCustomActionIfSpecified(action, actionContext);
5046
}
5147
}
5248

53-
// Handle URL: check for deep links within the app
54-
Intent intent = new Intent(Intent.ACTION_VIEW);
55-
intent.setData(uri);
56-
57-
List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentActivities(intent, 0);
58-
if (resolveInfos.size() > 1) {
59-
for (ResolveInfo resolveInfo : resolveInfos) {
60-
if (resolveInfo.activityInfo.packageName.equals(context.getPackageName())) {
61-
Log.d(TAG, "The deep link will be handled by the app: " + resolveInfo.activityInfo.packageName);
62-
intent.setPackage(resolveInfo.activityInfo.packageName);
63-
break;
49+
/**
50+
* Handle {@link IterableAction#ACTION_TYPE_OPEN_URL} action type
51+
* Calls {@link IterableUrlHandler} for custom handling by the app. If the handle does not exist
52+
* or returns `false`, the SDK tries to find an activity that can open this URL.
53+
*
54+
* @param context Context
55+
* @param uri The URL to open
56+
* @param actionContext The original action object
57+
* @return `true` if the action was handled, or an activity was found for this URL
58+
* `false` if the handler did not handle this URL and no activity was found to open it with
59+
*/
60+
private boolean openUri(@NonNull Context context, @NonNull Uri uri, @NonNull IterableActionContext actionContext) {
61+
if (IterableApi.sharedInstance.config.urlHandler != null) {
62+
if (IterableApi.sharedInstance.config.urlHandler.handleIterableURL(uri, actionContext)) {
63+
return true;
6464
}
6565
}
66-
}
6766

68-
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
67+
// Handle URL: check for deep links within the app
68+
Intent intent = new Intent(Intent.ACTION_VIEW);
69+
intent.setData(uri);
6970

70-
if (intent.resolveActivity(context.getPackageManager()) != null) {
71-
context.startActivity(intent);
72-
return true;
73-
} else {
74-
IterableLogger.e(TAG, "Could not find activities to handle deep link:" + uri);
75-
return false;
71+
List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentActivities(intent, 0);
72+
if (resolveInfos.size() > 1) {
73+
for (ResolveInfo resolveInfo : resolveInfos) {
74+
if (resolveInfo.activityInfo.packageName.equals(context.getPackageName())) {
75+
Log.d(TAG, "The deep link will be handled by the app: " + resolveInfo.activityInfo.packageName);
76+
intent.setPackage(resolveInfo.activityInfo.packageName);
77+
break;
78+
}
79+
}
80+
}
81+
82+
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
83+
84+
if (intent.resolveActivity(context.getPackageManager()) != null) {
85+
context.startActivity(intent);
86+
return true;
87+
} else {
88+
IterableLogger.e(TAG, "Could not find activities to handle deep link:" + uri);
89+
return false;
90+
}
7691
}
77-
}
7892

79-
/**
80-
* Handle custom actions passed from push notifications
81-
* @param action {@link IterableAction} object that contains action payload
82-
* @return `true` if the action is valid and was handled by the handler
83-
* `false` if the action is invalid or the handler returned `false`
84-
*/
85-
private static boolean callCustomActionIfSpecified(@NonNull IterableAction action, @NonNull IterableActionContext actionContext) {
86-
if (action.getType() != null && !action.getType().isEmpty()) {
87-
// Call custom action handler
88-
if (IterableApi.sharedInstance.config.customActionHandler != null) {
89-
return IterableApi.sharedInstance.config.customActionHandler.handleIterableCustomAction(action, actionContext);
93+
/**
94+
* Handle custom actions passed from push notifications
95+
*
96+
* @param action {@link IterableAction} object that contains action payload
97+
* @return `true` if the action is valid and was handled by the handler
98+
* `false` if the action is invalid or the handler returned `false`
99+
*/
100+
private boolean callCustomActionIfSpecified(@NonNull IterableAction action, @NonNull IterableActionContext actionContext) {
101+
if (action.getType() != null && !action.getType().isEmpty()) {
102+
// Call custom action handler
103+
if (IterableApi.sharedInstance.config.customActionHandler != null) {
104+
return IterableApi.sharedInstance.config.customActionHandler.handleIterableCustomAction(action, actionContext);
105+
}
90106
}
107+
return false;
91108
}
92-
return false;
93109
}
94110

95111
}

iterableapi/src/test/java/com/iterable/iterableapi/BasePowerMockTest.java

Lines changed: 0 additions & 37 deletions
This file was deleted.

iterableapi/src/test/java/com/iterable/iterableapi/IterablePushActionReceiverTest.java

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
import org.junit.Before;
1212
import org.junit.Test;
1313
import org.mockito.ArgumentCaptor;
14-
import org.powermock.api.mockito.PowerMockito;
15-
import org.powermock.core.classloader.annotations.PrepareForTest;
1614
import org.robolectric.RuntimeEnvironment;
1715

1816
import java.util.concurrent.TimeUnit;
@@ -27,23 +25,30 @@
2725
import static junit.framework.Assert.assertNull;
2826
import static org.mockito.ArgumentMatchers.any;
2927
import static org.mockito.ArgumentMatchers.eq;
28+
import static org.mockito.Mockito.mock;
29+
import static org.mockito.Mockito.verify;
3030
import static org.robolectric.Shadows.shadowOf;
3131

32-
@PrepareForTest(IterableActionRunner.class)
33-
public class IterablePushActionReceiverTest extends BasePowerMockTest {
32+
public class IterablePushActionReceiverTest extends BaseTest {
3433

3534
private MockWebServer server;
35+
private IterableActionRunner.IterableActionRunnerImpl actionRunnerMock;
3636

3737
@Before
3838
public void setUp() throws Exception {
3939
IterableApi.sharedInstance = new IterableApi();
4040
IterableTestUtils.createIterableApi();
4141
server = new MockWebServer();
4242
IterableApi.overrideURLEndpointPath(server.url("").toString());
43+
44+
actionRunnerMock = mock(IterableActionRunner.IterableActionRunnerImpl.class);
45+
IterableActionRunner.instance = actionRunnerMock;
4346
}
4447

4548
@After
4649
public void tearDown() throws Exception {
50+
IterableActionRunner.instance = new IterableActionRunner.IterableActionRunnerImpl();
51+
4752
server.shutdown();
4853
server = null;
4954
}
@@ -70,14 +75,12 @@ public void testTrackPushOpenWithCustomAction() throws Exception {
7075
Intent intent = new Intent(IterableConstants.ACTION_PUSH_ACTION);
7176
intent.putExtra(IterableConstants.ITERABLE_DATA_ACTION_IDENTIFIER, IterableConstants.ITERABLE_ACTION_DEFAULT);
7277
intent.putExtra(IterableConstants.ITERABLE_DATA_KEY, IterableTestUtils.getResourceString("push_payload_custom_action.json"));
73-
PowerMockito.mockStatic(IterableActionRunner.class);
7478

7579
iterablePushActionReceiver.onReceive(RuntimeEnvironment.application, intent);
7680

7781
// Verify that IterableActionRunner was called with the proper action
78-
PowerMockito.verifyStatic(IterableActionRunner.class);
7982
ArgumentCaptor<IterableAction> capturedAction = ArgumentCaptor.forClass(IterableAction.class);
80-
IterableActionRunner.executeAction(any(Context.class), capturedAction.capture(), eq(IterableActionSource.PUSH));
83+
verify(actionRunnerMock).executeAction(any(Context.class), capturedAction.capture(), eq(IterableActionSource.PUSH));
8184
assertEquals("customAction", capturedAction.getValue().getType());
8285

8386
// Verify that the main app activity was launched
@@ -126,14 +129,11 @@ public void testPushActionWithTextInput() throws Exception {
126129
clipDataIntent.putExtra(RemoteInput.EXTRA_RESULTS_DATA, resultsBundle);
127130
intent.setClipData(ClipData.newIntent(RESULTS_CLIP_LABEL, clipDataIntent));
128131

129-
PowerMockito.mockStatic(IterableActionRunner.class);
130-
131132
iterablePushActionReceiver.onReceive(RuntimeEnvironment.application, intent);
132133

133134
// Verify that IterableActionRunner was called with the proper action
134-
PowerMockito.verifyStatic(IterableActionRunner.class);
135135
ArgumentCaptor<IterableAction> actionCaptor = ArgumentCaptor.forClass(IterableAction.class);
136-
IterableActionRunner.executeAction(any(Context.class), actionCaptor.capture(), eq(IterableActionSource.PUSH));
136+
verify(actionRunnerMock).executeAction(any(Context.class), actionCaptor.capture(), eq(IterableActionSource.PUSH));
137137
IterableAction capturedAction = actionCaptor.getValue();
138138
assertEquals("handleTextInput", capturedAction.getType());
139139
assertEquals("input text", capturedAction.userInput);
@@ -146,14 +146,12 @@ public void testLegacyDeepLinkPayload() throws Exception {
146146
Intent intent = new Intent(IterableConstants.ACTION_PUSH_ACTION);
147147
intent.putExtras(IterableTestUtils.getBundleFromJsonResource("push_payload_legacy_deep_link.json"));
148148
intent.putExtra(IterableConstants.ITERABLE_DATA_ACTION_IDENTIFIER, IterableConstants.ITERABLE_ACTION_DEFAULT);
149-
PowerMockito.mockStatic(IterableActionRunner.class);
150149

151150
iterablePushActionReceiver.onReceive(RuntimeEnvironment.application, intent);
152151

153152
// Verify that IterableActionRunner was called with openUrl action
154-
PowerMockito.verifyStatic(IterableActionRunner.class);
155153
ArgumentCaptor<IterableAction> capturedAction = ArgumentCaptor.forClass(IterableAction.class);
156-
IterableActionRunner.executeAction(any(Context.class), capturedAction.capture(), eq(IterableActionSource.PUSH));
154+
verify(actionRunnerMock).executeAction(any(Context.class), capturedAction.capture(), eq(IterableActionSource.PUSH));
157155
assertEquals("openUrl", capturedAction.getValue().getType());
158156
assertEquals("https://example.com", capturedAction.getValue().getData());
159157
}

0 commit comments

Comments
 (0)