Skip to content

Commit a78e808

Browse files
committed
Merge pull request #55 in MML/infobip-mobile-messaging-android from sslavin-MM-1078-updating-showcase to master
Squashed commit of the following: commit 855ba6a8c2b8e84bd1768a23e9fedcdbcc6a31e6 Author: sslavin <stanislav.slavin@infobip.com> Date: Fri Nov 11 14:37:11 2016 +0300 MM-1078 - Added removal function commit 6fe4b82f6b89a3924af073493e8865cd7af66bee Author: sslavin <stanislav.slavin@infobip.com> Date: Fri Nov 11 14:05:33 2016 +0300 MM-1078 - Updated Date parsing exception handling commit 642e1fd9e48d01ab9304b34dcdf984027f6f066f Author: sslavin <stanislav.slavin@infobip.com> Date: Thu Nov 10 08:22:36 2016 +0300 MM-1078 - Updated after showcase integration
1 parent 1ea4612 commit a78e808

7 files changed

Lines changed: 265 additions & 63 deletions

File tree

infobip-mobile-messaging-android-sdk/src/androidTest/java/org/infobip/mobile/messaging/CustomUserDataTypeTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ public void test_sync_user_data() {
105105
assertEquals(SOME_STRING_VALUE, userDataResponse.getCustomUserDataValue(KEY_FOR_STRING).stringValue());
106106
assertEquals(SOME_NUMBER_VALUE, userDataResponse.getCustomUserDataValue(KEY_FOR_NUMBER).numberValue().intValue());
107107
assertEquals(SOME_DATE_VALUE.toString(), userDataResponse.getCustomUserDataValue(KEY_FOR_DATE).dateValue().toString());
108+
assertEquals(CustomUserDataValue.Type.String, userDataResponse.getCustomUserDataValue(KEY_FOR_STRING).getType());
109+
assertEquals(CustomUserDataValue.Type.Number, userDataResponse.getCustomUserDataValue(KEY_FOR_NUMBER).getType());
110+
assertEquals(CustomUserDataValue.Type.Date, userDataResponse.getCustomUserDataValue(KEY_FOR_DATE).getType());
108111
}
109112

110113
public void test_get_custom_user_data_value_from_json_string() throws ParseException {
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package org.infobip.mobile.messaging;
2+
3+
import android.content.BroadcastReceiver;
4+
import android.content.Context;
5+
import android.content.Intent;
6+
import android.content.IntentFilter;
7+
import android.test.InstrumentationTestCase;
8+
9+
import org.infobip.mobile.messaging.tools.DebugServer;
10+
import org.infobip.mobile.messaging.util.PreferenceHelper;
11+
import org.mockito.ArgumentCaptor;
12+
import org.mockito.Mockito;
13+
import org.skyscreamer.jsonassert.JSONAssert;
14+
15+
import java.util.Date;
16+
17+
import fi.iki.elonen.NanoHTTPD;
18+
19+
/**
20+
* @author sslavin
21+
* @since 10/11/2016.
22+
*/
23+
24+
public class UserDataSyncTest extends InstrumentationTestCase {
25+
26+
DebugServer debugServer;
27+
BroadcastReceiver receiver;
28+
ArgumentCaptor<Intent> captor;
29+
MobileMessaging mobileMessaging;
30+
31+
@Override
32+
protected void setUp() throws Exception {
33+
super.setUp();
34+
35+
mobileMessaging = MobileMessaging.getInstance(getInstrumentation().getContext());
36+
37+
debugServer = new DebugServer();
38+
debugServer.start();
39+
40+
PreferenceHelper.saveString(getInstrumentation().getContext(), MobileMessagingProperty.API_URI, "http://127.0.0.1:" + debugServer.getListeningPort() + "/");
41+
PreferenceHelper.saveString(getInstrumentation().getContext(), MobileMessagingProperty.APPLICATION_CODE, "TestApplicationCode");
42+
PreferenceHelper.saveString(getInstrumentation().getContext(), MobileMessagingProperty.INFOBIP_REGISTRATION_ID, "TestDeviceInstanceId");
43+
44+
captor = ArgumentCaptor.forClass(Intent.class);
45+
receiver = Mockito.mock(BroadcastReceiver.class);
46+
getInstrumentation().getContext().registerReceiver(receiver, new IntentFilter(Event.USER_DATA_REPORTED.getKey()));
47+
}
48+
49+
@Override
50+
protected void tearDown() throws Exception {
51+
getInstrumentation().getContext().unregisterReceiver(receiver);
52+
53+
if (null != debugServer) {
54+
try {
55+
debugServer.stop();
56+
} catch (Exception e) {
57+
//ignore
58+
}
59+
}
60+
61+
super.tearDown();
62+
}
63+
64+
public void test_empty_user_data() throws Exception {
65+
debugServer.respondWith(NanoHTTPD.Response.Status.OK, "{}");
66+
67+
mobileMessaging.fetchUserData();
68+
69+
Mockito.verify(receiver, Mockito.after(1000).atLeastOnce()).onReceive(Mockito.any(Context.class), captor.capture());
70+
71+
UserData userData = UserData.createFrom(captor.getValue().getExtras());
72+
73+
assertTrue(userData.getPredefinedUserData() == null || userData.getPredefinedUserData().isEmpty());
74+
assertTrue(userData.getCustomUserData() == null || userData.getCustomUserData().isEmpty());
75+
}
76+
77+
public void test_remove_custom_element() throws Exception {
78+
UserData userData = new UserData();
79+
userData.setCustomUserDataElement("myKey1", new CustomUserDataValue("Some string"));
80+
userData.setCustomUserDataElement("myKey2", new CustomUserDataValue(12345));
81+
userData.setCustomUserDataElement("myKey2", new CustomUserDataValue(new Date()));
82+
83+
userData.removeCustomUserDataElement("myKey1");
84+
userData.removeCustomUserDataElement("myKey2");
85+
userData.removeCustomUserDataElement("myKey3");
86+
87+
debugServer.respondWith(NanoHTTPD.Response.Status.OK, "{}");
88+
89+
mobileMessaging.syncUserData(userData);
90+
91+
Mockito.verify(receiver, Mockito.after(1000).atLeastOnce()).onReceive(Mockito.any(Context.class), Mockito.any(Intent.class));
92+
93+
JSONAssert.assertEquals(
94+
"{" +
95+
"\"customUserData\": {" +
96+
"\"myKey1\":null," +
97+
"\"myKey2\":null," +
98+
"\"myKey3\":null" +
99+
"}" +
100+
"}", debugServer.getBody(), false);
101+
}
102+
}
Lines changed: 71 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package org.infobip.mobile.messaging;
22

3+
import org.infobip.mobile.messaging.util.DateTimeUtil;
34
import org.infobip.mobile.messaging.util.ISO8601DateParseException;
45

6+
import java.security.InvalidParameterException;
7+
import java.text.NumberFormat;
58
import java.text.ParseException;
6-
import java.text.SimpleDateFormat;
79
import java.util.Date;
810
import java.util.Locale;
911
import java.util.Map;
@@ -23,52 +25,69 @@
2325
*/
2426
public class CustomUserDataValue {
2527

26-
private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssZ";
27-
private static final String GMT_TIME_ZONE = "+00:00";
28-
private static final String ISO8601_GMT_Z_MATCHER = "Z$";
28+
public enum Type {
29+
String,
30+
Number,
31+
Date
32+
}
2933

3034
private Object value;
31-
private String type;
32-
33-
public CustomUserDataValue() {
34-
}
35+
private Type type;
3536

3637
public CustomUserDataValue(String someString) {
37-
set(someString);
38+
this.value = someString;
39+
this.type = Type.String;
3840
}
3941

4042
public CustomUserDataValue(Number someNumber) {
41-
set(someNumber);
43+
this.value = someNumber;
44+
this.type = Type.Number;
4245
}
4346

4447
public CustomUserDataValue(Date someDate) {
45-
set(someDate);
46-
}
47-
48-
public void set(String someString) {
49-
this.value = someString;
50-
this.type = getTypeForValue(someString);
48+
this.value = DateTimeUtil.ISO8601DateToString(someDate);
49+
this.type = Type.Date;
5150
}
5251

53-
public void set(Number someNumber) {
54-
this.value = someNumber;
55-
this.type = getTypeForValue(someNumber);
52+
/**
53+
* Parses string into CustomUserDataValue based on desired format.
54+
* </p>
55+
* For Date type this constructor accepts "yyyy-MM-dd" representation of date (for example 2016-12-31).
56+
*
57+
* @throws ParseException if stringValue cannot be parsed to {@code CustomUserDataValue}
58+
* @throws InvalidParameterException if provided type is invalid
59+
*/
60+
public CustomUserDataValue(String stringValue, Type type) throws ParseException, InvalidParameterException {
61+
this.type = type;
62+
switch (type) {
63+
case String:
64+
this.value = stringValue;
65+
break;
66+
case Number:
67+
this.value = NumberFormat.getNumberInstance(Locale.getDefault()).parse(stringValue);
68+
break;
69+
case Date:
70+
DateTimeUtil.DateFromYMDString(stringValue);
71+
this.value = stringValue;
72+
break;
73+
default:
74+
throw new InvalidParameterException();
75+
}
5676
}
5777

58-
public void set(Date someDate) {
59-
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT, Locale.getDefault());
60-
this.value = simpleDateFormat.format(someDate);
61-
this.type = getTypeForValue(someDate);
78+
protected CustomUserDataValue(CustomUserDataValue that) {
79+
this.value = that.value;
80+
this.type = that.type;
6281
}
6382

6483
/**
6584
* Return the value of specified {@code CustomUserDataValue} as {@link String}.
6685
*
6786
* @return {@link String}
68-
* @throws ClassCastException if {@code CustomUserDataValue} is not type of {@link String}
87+
* @throws ClassCastException if {@code CustomUserDataValue} is not of {@link String} type.
6988
*/
7089
public String stringValue() {
71-
if (!(value instanceof String)) {
90+
if (!(value instanceof String) || type != Type.String) {
7291
throw new ClassCastException();
7392
}
7493

@@ -79,10 +98,10 @@ public String stringValue() {
7998
* Return the value of specified {@code CustomUserDataValue} as {@link Number}.
8099
*
81100
* @return {@link Number}
82-
* @throws ClassCastException if {@code CustomUserDataValue} is not type of {@link Number}
101+
* @throws ClassCastException if {@code CustomUserDataValue} is not of {@link Number} type.
83102
*/
84103
public Number numberValue() {
85-
if (!(value instanceof Number)) {
104+
if (!(value instanceof Number) || type != Type.Number) {
86105
throw new ClassCastException();
87106
}
88107

@@ -93,39 +112,43 @@ public Number numberValue() {
93112
* Return the value of specified {@code CustomUserDataValue} as {@link Date}.
94113
*
95114
* @return {@link Date}
96-
* @throws ISO8601DateParseException if {@code CustomUserDataValue} is not type of {@link Date}.
115+
* @throws ClassCastException if {@code CustomUserDataValue} is not of {@link Date} type.
97116
*/
98117
public Date dateValue() {
99-
String dateValue = (String) this.value;
100-
String date = dateValue.trim().replaceAll(ISO8601_GMT_Z_MATCHER, GMT_TIME_ZONE);
101-
try {
102-
return new SimpleDateFormat(DATE_FORMAT, Locale.getDefault()).parse(date);
103-
} catch (ParseException e) {
104-
throw new ISO8601DateParseException(ISO8601DateParseException.Reason.DATE_PARSE_EXCEPTION, e);
118+
if (!(value instanceof String) || type != Type.Date) {
119+
throw new ClassCastException();
105120
}
106-
}
107121

108-
public Object getValue() {
109-
return value;
122+
try {
123+
return DateTimeUtil.ISO8601DateFromString((String) value);
124+
} catch (ISO8601DateParseException e) {
125+
throw new ClassCastException(e.getMessage());
126+
}
110127
}
111128

112-
public String getType() {
129+
public Type getType() {
113130
return type;
114131
}
115132

116-
private String getTypeForValue(Object value) {
117-
if (value instanceof String) {
118-
return "String";
119-
}
133+
protected Object getValue() {
134+
return value;
135+
}
120136

121-
if (value instanceof Date) {
122-
return "Date";
137+
@Override
138+
public String toString() {
139+
if (this.type == null) {
140+
return super.toString();
123141
}
124142

125-
if (value instanceof Number) {
126-
return "Number";
143+
switch (type) {
144+
case String:
145+
return stringValue();
146+
case Date:
147+
return DateTimeUtil.DateToYMDString(dateValue());
148+
case Number:
149+
return "" + numberValue();
150+
default:
151+
return super.toString();
127152
}
128-
129-
return null;
130153
}
131154
}

infobip-mobile-messaging-android-sdk/src/main/java/org/infobip/mobile/messaging/UserData.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22

33
import android.os.Bundle;
44

5-
import org.infobip.mobile.messaging.api.data.CustomUserDataValueReport;
65
import org.infobip.mobile.messaging.api.shaded.google.gson.Gson;
76
import org.infobip.mobile.messaging.api.shaded.google.gson.GsonBuilder;
87

9-
import java.util.Date;
108
import java.util.HashMap;
119
import java.util.Map;
1210

@@ -103,6 +101,10 @@ public CustomUserDataValue getCustomUserDataValue(String key) {
103101
return this.customUserData.get(key);
104102
}
105103

104+
public void removeCustomUserDataElement(String key) {
105+
this.customUserData.put(key, null);
106+
}
107+
106108
public String getMsisdn() {
107109
return getField(PredefinedField.MSISDN);
108110
}

infobip-mobile-messaging-android-sdk/src/main/java/org/infobip/mobile/messaging/geo/Geo.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
import android.os.Bundle;
44
import android.os.Parcel;
55
import android.os.Parcelable;
6+
import android.util.Log;
67

78
import com.google.gson.annotations.SerializedName;
89

910
import org.infobip.mobile.messaging.BroadcastParameter;
11+
import org.infobip.mobile.messaging.MobileMessaging;
1012
import org.infobip.mobile.messaging.util.DateTimeUtil;
13+
import org.infobip.mobile.messaging.util.ISO8601DateParseException;
1114

1215
import java.util.ArrayList;
1316
import java.util.Date;
@@ -114,11 +117,23 @@ protected DeliveryTime getDeliveryTime() {
114117
}
115118

116119
protected Date getExpiryDate() {
117-
return DateTimeUtil.ISO8601DateFromString(expiryTime);
120+
try {
121+
return DateTimeUtil.ISO8601DateFromString(expiryTime);
122+
} catch (ISO8601DateParseException e) {
123+
Log.e(MobileMessaging.TAG, "Cannot parse expiry date: " + e.getMessage());
124+
Log.d(MobileMessaging.TAG, Log.getStackTraceString(e));
125+
return null;
126+
}
118127
}
119128

120129
protected Date getStartDate() {
121-
return DateTimeUtil.ISO8601DateFromString(startTime);
130+
try {
131+
return DateTimeUtil.ISO8601DateFromString(startTime);
132+
} catch (ISO8601DateParseException e) {
133+
Log.e(MobileMessaging.TAG, "Cannot parse start date: " + e.getMessage());
134+
Log.d(MobileMessaging.TAG, Log.getStackTraceString(e));
135+
return null;
136+
}
122137
}
123138

124139
protected String getCampaignId() {

0 commit comments

Comments
 (0)