Skip to content

Commit af04acf

Browse files
committed
release: SDK 1.17.1
1 parent 9fc9ab4 commit af04acf

File tree

14 files changed

+17547
-115
lines changed

14 files changed

+17547
-115
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ If you think you've discovered a bug in our SDK, our support team is available a
2525
- Describe your environment
2626
- Provide detailed reproduction steps
2727
- Provide a minimal reproduction project: this isn’t compulsory but will reduce greatly the resolution time
28-
- Include detailed logs: Please don’t try filter the logs here, it’s best to provide here the rawest logs as possible
28+
- Include detailed logs: It’s best to provide the rawest logs possible, please don’t try filter them
2929
- Includes a Stack Trace: If your issue involves a crash, this is absolutely compulsory, and should be as raw as possible
3030

3131
You can also open an issue for it, using the appropriate template and respecting the same rules. However, we do have a longer response time here than by email or the Live Chat.

Sources/sdk/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ android {
2626
minSdkVersion 15
2727
targetSdkVersion 30
2828
versionCode 1
29-
versionName "1.17.0"
29+
versionName "1.17.1"
3030
buildConfigField "String", SDK_VERSION, "\"$versionName\""
31-
buildConfigField "Integer", API_LEVEL, '34'
31+
buildConfigField "Integer", API_LEVEL, '35'
3232
buildConfigField "Integer", MESSAGING_API_LEVEL, '10'
3333
buildConfigField "String", WS_DOMAIN, '"ws.batch.com"'
3434

Sources/sdk/src/main/java/com/batch/android/actions/UserEventBuiltinActionRunnable.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public void performAction(@Nullable Context context,
5757
return;
5858
}
5959

60-
String label = json.getString("l");
60+
String label = json.reallyOptString("l", null);
6161

6262
BatchEventData data = new BatchEventData();
6363

Sources/sdk/src/main/java/com/batch/android/compat/LocalBroadcastManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ private static class BroadcastRecord
105105

106106
public LocalBroadcastManager(Context context)
107107
{
108-
mAppContext = context;
109-
mHandler = new Handler(context.getMainLooper())
108+
mAppContext = context.getApplicationContext();
109+
mHandler = new Handler(mAppContext.getMainLooper())
110110
{
111111

112112
@Override

Sources/sdk/src/main/java/com/batch/android/messaging/view/formats/WebFormatView.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,10 @@ public WebFormatView(@NonNull Context context,
124124
webSettings.setDefaultTextEncodingName("utf-8");
125125
webSettings.setSupportMultipleWindows(true);
126126
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
127-
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
127+
// Work around an issue where android could show "ERR_CACHE_MISS"
128+
// In a perfect world we would like to make use of the browser cache
129+
// but as those messages are usually one shot, it doesn't really matter.
130+
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
128131
}
129132

130133
webView.addJavascriptInterface(jsInterface, "_batchAndroidBridge");

Sources/sdk/src/main/java/com/batch/android/module/UserModule.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ public void trackPublicEvent(String event, String label, JSONObject data)
354354
if (label.length() > 200) {
355355
Logger.internal(TAG,
356356
"Event label is longer than 200 characters and has been removed from the event");
357-
} else {
357+
} else if (label.length() > 0) {
358358
params.put(PARAMETER_KEY_LABEL, label);
359359
}
360360
}

Sources/sdk/src/test/java/com/batch/android/module/ActionModuleTest.java renamed to Sources/sdk/src/test/java/com/batch/android/actions/ActionModuleTest.java

Lines changed: 3 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.batch.android.module;
1+
package com.batch.android.actions;
22

33
import android.content.ClipData;
44
import android.content.ClipboardManager;
@@ -21,6 +21,8 @@
2121
import com.batch.android.di.providers.RuntimeManagerProvider;
2222
import com.batch.android.json.JSONException;
2323
import com.batch.android.json.JSONObject;
24+
import com.batch.android.module.ActionModule;
25+
import com.batch.android.module.UserModule;
2426

2527
import org.junit.Assert;
2628
import org.junit.Before;
@@ -206,112 +208,6 @@ public void testClipboardAction() throws JSONException
206208
assertEquals("best text ever", text.getItemAt(0).getText().toString());
207209
}
208210

209-
@Test
210-
public void testTrackEventAction() throws JSONException
211-
{
212-
ActionModule actionModule = new ActionModule();
213-
UserModule userModule = DITestUtils.mockSingletonDependency(UserModule.class, null);
214-
215-
PowerMockito.doAnswer(new Answer<Object>()
216-
{
217-
@Override
218-
public Object answer(InvocationOnMock invocation) throws Throwable
219-
{
220-
String event = invocation.getArgument(0, String.class);
221-
String label = invocation.getArgument(1, String.class);
222-
JSONObject data = invocation.getArgument(2, JSONObject.class);
223-
224-
Assert.assertEquals("event_test", event);
225-
Assert.assertEquals("label_test", label);
226-
Assert.assertNotNull(data);
227-
Assert.assertNotNull(data.getJSONObject("attributes"));
228-
Assert.assertTrue(data.getJSONObject("attributes").keySet().isEmpty());
229-
Assert.assertNotNull(data.getJSONArray("tags"));
230-
Assert.assertEquals(0, data.getJSONArray("tags").length());
231-
return null;
232-
}
233-
}).when(userModule).trackPublicEvent(Mockito.anyString(),
234-
Mockito.anyString(),
235-
Mockito.any(JSONObject.class));
236-
String eventJSON = "{'e':'event_test', 'l':'label_test'}";
237-
actionModule.performAction(context, "batch.user.event", new JSONObject(eventJSON), null);
238-
}
239-
240-
@Test
241-
public void testTrackEventWithTagsAction() throws JSONException
242-
{
243-
ActionModule actionModule = new ActionModule();
244-
UserModule userModule = DITestUtils.mockSingletonDependency(UserModule.class, null);
245-
246-
PowerMockito.doAnswer(new Answer<Object>()
247-
{
248-
@Override
249-
public Object answer(InvocationOnMock invocation) throws Throwable
250-
{
251-
String event = invocation.getArgument(0, String.class);
252-
String label = invocation.getArgument(1, String.class);
253-
JSONObject data = invocation.getArgument(2, JSONObject.class);
254-
255-
Assert.assertEquals("event_test", event);
256-
Assert.assertEquals("label_test", label);
257-
Assert.assertNotNull(data);
258-
Assert.assertNotNull(data.getJSONObject("attributes"));
259-
Assert.assertTrue(data.getJSONObject("attributes").keySet().isEmpty());
260-
Assert.assertNotNull(data.getJSONArray("tags"));
261-
Assert.assertEquals(3, data.getJSONArray("tags").length());
262-
Assert.assertEquals("tag1", data.getJSONArray("tags").optString(0));
263-
Assert.assertEquals("tag2", data.getJSONArray("tags").optString(1));
264-
Assert.assertEquals("tag3", data.getJSONArray("tags").optString(2));
265-
return null;
266-
}
267-
}).when(userModule).trackPublicEvent(Mockito.anyString(),
268-
Mockito.anyString(),
269-
Mockito.any(JSONObject.class));
270-
String eventJSON = "{'e':'event_test', 'l':'label_test', 't':['tag1', 'tag2', 'tag3']}";
271-
actionModule.performAction(context, "batch.user.event", new JSONObject(eventJSON), null);
272-
}
273-
274-
@Test
275-
public void testTrackEventWithAttrAction() throws JSONException
276-
{
277-
ActionModule actionModule = new ActionModule();
278-
UserModule userModule = DITestUtils.mockSingletonDependency(UserModule.class, null);
279-
280-
PowerMockito.doAnswer(new Answer<Object>()
281-
{
282-
@Override
283-
public Object answer(InvocationOnMock invocation) throws Throwable
284-
{
285-
String event = invocation.getArgument(0, String.class);
286-
String label = invocation.getArgument(1, String.class);
287-
JSONObject data = invocation.getArgument(2, JSONObject.class);
288-
289-
Assert.assertEquals("event_test", event);
290-
Assert.assertEquals("label_test", label);
291-
Assert.assertNotNull(data);
292-
Assert.assertNotNull(data.getJSONArray("tags"));
293-
Assert.assertEquals(0, data.getJSONArray("tags").length());
294-
295-
Assert.assertNotNull(data.getJSONObject("attributes"));
296-
Assert.assertTrue(data.getJSONObject("attributes").optBoolean("bool.b"));
297-
Assert.assertEquals(64, data.getJSONObject("attributes").optInt("int.i"));
298-
Assert.assertEquals(68987.256,
299-
data.getJSONObject("attributes").optDouble("double.f"),
300-
0);
301-
Assert.assertEquals("tototo",
302-
data.getJSONObject("attributes").optString("string.s"));
303-
Assert.assertEquals(1596975143943L,
304-
data.getJSONObject("attributes").optLong("date.t"));
305-
return null;
306-
}
307-
}).when(userModule).trackPublicEvent(Mockito.anyString(),
308-
Mockito.anyString(),
309-
Mockito.any(JSONObject.class));
310-
311-
String eventJSON = "{'e':'event_test', 'l':'label_test', 'a':{'bool':true, 'int':64, 'double': 68987.256, 'string':'tototo', 'date': '2020-08-09T12:12:23.943Z'}}}";
312-
actionModule.performAction(context, "batch.user.event", new JSONObject(eventJSON), null);
313-
}
314-
315211
private JSONObject generateJSONTestAction(String action) throws JSONException
316212
{
317213
JSONObject json = new JSONObject();
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
package com.batch.android.actions;
2+
3+
import android.content.Context;
4+
5+
import androidx.test.core.app.ApplicationProvider;
6+
import androidx.test.ext.junit.runners.AndroidJUnit4;
7+
import androidx.test.filters.MediumTest;
8+
9+
import com.batch.android.Batch;
10+
import com.batch.android.Config;
11+
import com.batch.android.di.DITestUtils;
12+
import com.batch.android.di.providers.RuntimeManagerProvider;
13+
import com.batch.android.json.JSONException;
14+
import com.batch.android.json.JSONObject;
15+
import com.batch.android.module.ActionModule;
16+
import com.batch.android.module.UserModule;
17+
18+
import org.junit.Assert;
19+
import org.junit.Before;
20+
import org.junit.Rule;
21+
import org.junit.Test;
22+
import org.junit.runner.RunWith;
23+
import org.mockito.ArgumentCaptor;
24+
import org.mockito.Mock;
25+
import org.mockito.Mockito;
26+
import org.mockito.invocation.InvocationOnMock;
27+
import org.mockito.stubbing.Answer;
28+
import org.powermock.api.mockito.PowerMockito;
29+
import org.powermock.core.classloader.annotations.PowerMockIgnore;
30+
import org.powermock.core.classloader.annotations.PrepareForTest;
31+
import org.powermock.modules.junit4.rule.PowerMockRule;
32+
import org.robolectric.res.android.Asset;
33+
import org.robolectric.shadows.ShadowLog;
34+
35+
import static org.mockito.ArgumentMatchers.eq;
36+
37+
@RunWith(AndroidJUnit4.class)
38+
@MediumTest
39+
@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*", "androidx.*"})
40+
@PrepareForTest({UserModule.class})
41+
public class UserEventActionTest
42+
{
43+
44+
private Context context;
45+
46+
@Rule
47+
public PowerMockRule rule = new PowerMockRule();
48+
49+
@Before
50+
public void setUp()
51+
{
52+
ShadowLog.stream = System.out;
53+
54+
context = ApplicationProvider.getApplicationContext();
55+
56+
RuntimeManagerProvider.get().setContext(context);
57+
}
58+
59+
@Test
60+
public void testTrackEventAction() throws JSONException
61+
{
62+
ActionModule actionModule = new ActionModule();
63+
UserModule userModule = DITestUtils.mockSingletonDependency(UserModule.class, null);
64+
65+
PowerMockito.doNothing().when(userModule).trackPublicEvent(Mockito.anyString(),
66+
Mockito.anyString(),
67+
Mockito.any(JSONObject.class));
68+
69+
ArgumentCaptor<JSONObject> eventDataCaptor = ArgumentCaptor.forClass(JSONObject.class);
70+
71+
String eventJSON = "{'e':'event_test', 'l':'label_test'}";
72+
actionModule.performAction(context, "batch.user.event", new JSONObject(eventJSON), null);
73+
Mockito.verify(userModule).trackPublicEvent(eq("event_test"),
74+
eq("label_test"),
75+
eventDataCaptor.capture());
76+
77+
JSONObject eventData = eventDataCaptor.getValue();
78+
Assert.assertNotNull(eventData);
79+
Assert.assertNotNull(eventData.getJSONObject("attributes"));
80+
Assert.assertTrue(eventData.getJSONObject("attributes").keySet().isEmpty());
81+
Assert.assertNotNull(eventData.getJSONArray("tags"));
82+
Assert.assertEquals(0, eventData.getJSONArray("tags").length());
83+
}
84+
85+
@Test
86+
public void testTrackEventWithoutLabelAction() throws JSONException
87+
{
88+
ActionModule actionModule = new ActionModule();
89+
UserModule userModule = DITestUtils.mockSingletonDependency(UserModule.class, null);
90+
91+
PowerMockito.doNothing().when(userModule).trackPublicEvent(Mockito.anyString(),
92+
Mockito.anyString(),
93+
Mockito.any(JSONObject.class));
94+
95+
ArgumentCaptor<JSONObject> eventDataCaptor = ArgumentCaptor.forClass(JSONObject.class);
96+
97+
String eventJSON = "{'e':'event_test'}";
98+
actionModule.performAction(context, "batch.user.event", new JSONObject(eventJSON), null);
99+
Mockito.verify(userModule).trackPublicEvent(eq("event_test"),
100+
eq(null),
101+
eventDataCaptor.capture());
102+
103+
JSONObject eventData = eventDataCaptor.getValue();
104+
Assert.assertNotNull(eventData);
105+
Assert.assertNotNull(eventData.getJSONObject("attributes"));
106+
Assert.assertTrue(eventData.getJSONObject("attributes").keySet().isEmpty());
107+
Assert.assertNotNull(eventData.getJSONArray("tags"));
108+
Assert.assertEquals(0, eventData.getJSONArray("tags").length());
109+
}
110+
111+
@Test
112+
public void testTrackEventWithTagsAction() throws JSONException
113+
{
114+
ActionModule actionModule = new ActionModule();
115+
UserModule userModule = DITestUtils.mockSingletonDependency(UserModule.class, null);
116+
117+
PowerMockito.doNothing().when(userModule).trackPublicEvent(Mockito.anyString(),
118+
Mockito.anyString(),
119+
Mockito.any(JSONObject.class));
120+
121+
ArgumentCaptor<JSONObject> eventDataCaptor = ArgumentCaptor.forClass(JSONObject.class);
122+
123+
String eventJSON = "{'e':'event_test', 'l':'label_test', 't':['tag1', 'tag2', 'tag3']}";
124+
actionModule.performAction(context, "batch.user.event", new JSONObject(eventJSON), null);
125+
Mockito.verify(userModule).trackPublicEvent(eq("event_test"),
126+
eq("label_test"),
127+
eventDataCaptor.capture());
128+
129+
JSONObject eventData = eventDataCaptor.getValue();
130+
Assert.assertNotNull(eventData);
131+
Assert.assertNotNull(eventData.getJSONObject("attributes"));
132+
Assert.assertTrue(eventData.getJSONObject("attributes").keySet().isEmpty());
133+
Assert.assertNotNull(eventData.getJSONArray("tags"));
134+
Assert.assertEquals(3, eventData.getJSONArray("tags").length());
135+
Assert.assertEquals("tag1", eventData.getJSONArray("tags").optString(0));
136+
Assert.assertEquals("tag2", eventData.getJSONArray("tags").optString(1));
137+
Assert.assertEquals("tag3", eventData.getJSONArray("tags").optString(2));
138+
}
139+
140+
@Test
141+
public void testTrackEventWithAttrAction() throws JSONException
142+
{
143+
ActionModule actionModule = new ActionModule();
144+
UserModule userModule = DITestUtils.mockSingletonDependency(UserModule.class, null);
145+
146+
PowerMockito.doNothing().when(userModule).trackPublicEvent(Mockito.anyString(),
147+
Mockito.anyString(),
148+
Mockito.any(JSONObject.class));
149+
150+
ArgumentCaptor<JSONObject> eventDataCaptor = ArgumentCaptor.forClass(JSONObject.class);
151+
152+
String eventJSON = "{'e':'event_test', 'l':'label_test', 'a':{'bool':true, 'int':64, 'double': 68987.256, 'string':'tototo', 'date': '2020-08-09T12:12:23.943Z'}}}";
153+
actionModule.performAction(context, "batch.user.event", new JSONObject(eventJSON), null);
154+
Mockito.verify(userModule).trackPublicEvent(eq("event_test"),
155+
eq("label_test"),
156+
eventDataCaptor.capture());
157+
158+
JSONObject eventData = eventDataCaptor.getValue();
159+
Assert.assertNotNull(eventData);
160+
161+
Assert.assertNotNull(eventData.getJSONObject("attributes"));
162+
Assert.assertTrue(eventData.getJSONObject("attributes").optBoolean("bool.b"));
163+
Assert.assertEquals(64, eventData.getJSONObject("attributes").optInt("int.i"));
164+
Assert.assertEquals(68987.256,
165+
eventData.getJSONObject("attributes").optDouble("double.f"),
166+
0);
167+
Assert.assertEquals("tototo",
168+
eventData.getJSONObject("attributes").optString("string.s"));
169+
Assert.assertEquals(1596975143943L,
170+
eventData.getJSONObject("attributes").optLong("date.t"));
171+
172+
Assert.assertNotNull(eventData.getJSONArray("tags"));
173+
Assert.assertEquals(0, eventData.getJSONArray("tags").length());
174+
}
175+
}

proguard-mappings/1.16.4/checksum.md5

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
MD5 (public-sdk/Batch.aar) = 2df641af51f6a9a9c8c346c722e09c0b

proguard-mappings/1.16.4/checksum.sha

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
98afdf3a1b75b97e8b7eb9d86b680c274411b07b public-sdk/Batch.aar

0 commit comments

Comments
 (0)