Skip to content

Commit aa76587

Browse files
a7medevHeshamMegid
authored andcommitted
[MOB-10585] Add More Native Android Tests (#302)
* Test native Android APM * Test native Android Instabug * Test native Android bug reporting * Fix order of Android assert(expected, actual) * Test APM networkLogAndroid * Remove unused imports in tests * Test native Android crash reporting * Test native Android FeatureRequests * Close `JSONObject` mock after test * Test native Android InstabugLog * Test native Android Replies * Test native Android Surveys * Fix failing tests * Improve Android test code quality * Test native Android `setValueForStringWithKey` branches
1 parent bf61b60 commit aa76587

13 files changed

+1663
-9
lines changed

android/src/main/java/com/instabug/flutter/modules/InstabugApi.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import androidx.annotation.NonNull;
1111
import androidx.annotation.Nullable;
12+
import androidx.annotation.VisibleForTesting;
1213

1314
import com.instabug.flutter.util.ArgsRegistry;
1415
import com.instabug.flutter.generated.InstabugPigeon;
@@ -57,7 +58,8 @@ public InstabugApi(Context context, Callable<Bitmap> screenshotProvider) {
5758
this.screenshotProvider = screenshotProvider;
5859
}
5960

60-
private void setCurrentPlatform() {
61+
@VisibleForTesting
62+
public void setCurrentPlatform() {
6163
try {
6264
Method method = Reflection.getMethod(Class.forName("com.instabug.library.Instabug"), "setCurrentPlatform", int.class);
6365
if (method != null) {
@@ -278,7 +280,8 @@ public void reportScreenChange(@NonNull String screenName) {
278280
}
279281
}
280282

281-
private Bitmap getBitmapForAsset(String assetName) {
283+
@VisibleForTesting
284+
public Bitmap getBitmapForAsset(String assetName) {
282285
try {
283286
FlutterLoader loader = FlutterInjector.instance().flutterLoader();
284287
String key = loader.getLookupKeyForAsset(assetName);
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
package com.instabug.flutter;
2+
3+
import static com.instabug.flutter.util.GlobalMocks.reflected;
4+
import static com.instabug.flutter.util.MockResult.makeResult;
5+
import static org.junit.Assert.assertEquals;
6+
import static org.mockito.ArgumentMatchers.any;
7+
import static org.mockito.ArgumentMatchers.anyInt;
8+
import static org.mockito.ArgumentMatchers.eq;
9+
import static org.mockito.Mockito.mock;
10+
import static org.mockito.Mockito.mockConstruction;
11+
import static org.mockito.Mockito.mockStatic;
12+
import static org.mockito.Mockito.verify;
13+
import static org.mockito.Mockito.when;
14+
15+
import com.instabug.apm.APM;
16+
import com.instabug.apm.model.ExecutionTrace;
17+
import com.instabug.flutter.generated.ApmPigeon;
18+
import com.instabug.flutter.modules.ApmApi;
19+
import com.instabug.flutter.util.GlobalMocks;
20+
import com.instabug.flutter.util.MockReflected;
21+
import com.instabug.library.LogLevel;
22+
23+
import org.json.JSONObject;
24+
import org.junit.After;
25+
import org.junit.Assert;
26+
import org.junit.Before;
27+
import org.junit.Test;
28+
import org.mockito.MockedConstruction;
29+
import org.mockito.MockedStatic;
30+
31+
import java.util.HashMap;
32+
import java.util.Map;
33+
34+
import io.flutter.plugin.common.BinaryMessenger;
35+
36+
37+
public class ApmApiTest {
38+
private final ApmApi api = new ApmApi();
39+
private MockedStatic<APM> mAPM;
40+
private MockedStatic<ApmPigeon.ApmHostApi> mHostApi;
41+
42+
@Before
43+
public void setUp() throws NoSuchMethodException {
44+
mAPM = mockStatic(APM.class);
45+
mHostApi = mockStatic(ApmPigeon.ApmHostApi.class);
46+
GlobalMocks.setUp();
47+
}
48+
49+
@After
50+
public void cleanUp() {
51+
mAPM.close();
52+
mHostApi.close();
53+
GlobalMocks.close();
54+
}
55+
56+
private ExecutionTrace mockTrace(String id) {
57+
String name = "trace-name";
58+
ExecutionTrace mTrace = mock(ExecutionTrace.class);
59+
60+
mAPM.when(() -> APM.startExecutionTrace(name)).thenReturn(mTrace);
61+
62+
api.startExecutionTrace(id, name, makeResult());
63+
64+
return mTrace;
65+
}
66+
67+
@Test
68+
public void testInit() {
69+
BinaryMessenger messenger = mock(BinaryMessenger.class);
70+
71+
ApmApi.init(messenger);
72+
73+
mHostApi.verify(() -> ApmPigeon.ApmHostApi.setup(eq(messenger), any(ApmApi.class)));
74+
}
75+
76+
@Test
77+
public void testSetEnabled() {
78+
boolean isEnabled = false;
79+
80+
api.setEnabled(isEnabled);
81+
82+
mAPM.verify(() -> APM.setEnabled(isEnabled));
83+
}
84+
85+
@SuppressWarnings("deprecation")
86+
@Test
87+
public void testSetColdAppLaunchEnabled() {
88+
boolean isEnabled = false;
89+
90+
api.setColdAppLaunchEnabled(isEnabled);
91+
92+
mAPM.verify(() -> APM.setAppLaunchEnabled(isEnabled));
93+
}
94+
95+
@Test
96+
public void testSetAutoUITraceEnabled() {
97+
boolean isEnabled = false;
98+
99+
api.setAutoUITraceEnabled(isEnabled);
100+
101+
mAPM.verify(() -> APM.setAutoUITraceEnabled(isEnabled));
102+
}
103+
104+
@SuppressWarnings("deprecation")
105+
@Test
106+
public void testSetLogLevel() {
107+
String logLevel = "LogLevel.none";
108+
109+
api.setLogLevel(logLevel);
110+
111+
mAPM.verify(() -> APM.setLogLevel(LogLevel.NONE));
112+
}
113+
114+
@Test
115+
public void testStartExecutionTraceWhenTraceNotNull() {
116+
String expectedId = "trace-id";
117+
String name = "trace-name";
118+
ApmPigeon.Result<String> result = makeResult((String actualId) -> assertEquals(expectedId, actualId));
119+
120+
mAPM.when(() -> APM.startExecutionTrace(name)).thenReturn(new ExecutionTrace(name));
121+
122+
api.startExecutionTrace(expectedId, name, result);
123+
124+
mAPM.verify(() -> APM.startExecutionTrace(name));
125+
}
126+
127+
@Test
128+
public void testStartExecutionTraceWhenTraceIsNull() {
129+
String id = "trace-id";
130+
String name = "trace-name";
131+
ApmPigeon.Result<String> result = makeResult(Assert::assertNull);
132+
133+
mAPM.when(() -> APM.startExecutionTrace(name)).thenReturn(null);
134+
135+
api.startExecutionTrace(id, name, result);
136+
137+
mAPM.verify(() -> APM.startExecutionTrace(name));
138+
}
139+
140+
@Test
141+
public void testSetExecutionTraceAttribute() {
142+
String id = "trace-id";
143+
String key = "is_premium";
144+
String value = "true";
145+
ExecutionTrace mTrace = mockTrace(id);
146+
147+
api.setExecutionTraceAttribute(id, key, value);
148+
149+
verify(mTrace).setAttribute(key, value);
150+
}
151+
152+
@Test
153+
public void testEndExecutionTrace() {
154+
String id = "trace-id";
155+
ExecutionTrace mTrace = mockTrace(id);
156+
157+
api.endExecutionTrace(id);
158+
159+
verify(mTrace).end();
160+
}
161+
162+
@Test
163+
public void testStartUITrace() {
164+
String name = "login";
165+
166+
api.startUITrace(name);
167+
168+
mAPM.verify(() -> APM.startUITrace(name));
169+
}
170+
171+
@Test
172+
public void testEndUITrace() {
173+
api.endUITrace();
174+
175+
mAPM.verify(APM::endUITrace);
176+
}
177+
178+
@Test
179+
public void testEndAppLaunch() {
180+
api.endAppLaunch();
181+
182+
mAPM.verify(APM::endAppLaunch);
183+
}
184+
185+
@Test
186+
public void testNetworkLogAndroid() {
187+
Map<String, Object> data = new HashMap<>();
188+
String requestUrl = "https://example.com";
189+
String requestBody = "hi";
190+
String responseBody = "{\"hello\":\"world\"}";
191+
String requestMethod = "POST";
192+
String requestContentType = "text/plain";
193+
String responseContentType = "application/json";
194+
long requestBodySize = 20;
195+
long responseBodySize = 50;
196+
int responseCode = 401;
197+
long requestDuration = 23000;
198+
long requestStartTime = System.currentTimeMillis() / 1000;
199+
HashMap<String, String> requestHeaders = new HashMap<>();
200+
HashMap<String, String> responseHeaders = new HashMap<>();
201+
String errorDomain = "ERROR_DOMAIN";
202+
String serverErrorMessage = "SERVER_ERROR_MESSAGE";
203+
data.put("url", requestUrl);
204+
data.put("requestBody", requestBody);
205+
data.put("responseBody", responseBody);
206+
data.put("method", requestMethod);
207+
data.put("requestContentType", requestContentType);
208+
data.put("responseContentType", responseContentType);
209+
data.put("requestBodySize", requestBodySize);
210+
data.put("responseBodySize", responseBodySize);
211+
data.put("errorDomain", errorDomain);
212+
data.put("responseCode", responseCode);
213+
data.put("requestDuration", requestDuration);
214+
data.put("startTime", requestStartTime);
215+
data.put("requestHeaders", requestHeaders);
216+
data.put("responseHeaders", responseHeaders);
217+
data.put("duration", requestDuration);
218+
data.put("serverErrorMessage", serverErrorMessage);
219+
220+
MockedConstruction<JSONObject> mJSONObject = mockConstruction(JSONObject.class, (mock, context) -> when(mock.toString(anyInt())).thenReturn("{}"));
221+
222+
api.networkLogAndroid(data);
223+
224+
reflected.verify(() -> MockReflected.apmNetworkLog(
225+
requestStartTime * 1000,
226+
requestDuration / 1000,
227+
"{}",
228+
requestBody,
229+
requestBodySize,
230+
requestMethod,
231+
requestUrl,
232+
requestContentType,
233+
"{}",
234+
responseBody,
235+
responseBodySize,
236+
responseCode,
237+
responseContentType,
238+
errorDomain,
239+
null,
240+
serverErrorMessage
241+
));
242+
243+
mJSONObject.close();
244+
}
245+
}

0 commit comments

Comments
 (0)