Skip to content

Commit

Permalink
[MOB 5730] Add callbacks to reading/removing in-app messages (#557) (#…
Browse files Browse the repository at this point in the history
…583)

* [MOB 5730] Add callbacks to reading/removing in-app messages (#557)

* add callback for setRead/removeMessage

* modify test for setRead and added test for removeMessage

* fixes

* Update build.gradle

* removed resultcallbackhandler

* Update IterableInAppManager.java

* fixes

---------

Co-authored-by: Akshay Ayyanchira <[email protected]>
Co-authored-by: Hardik Mashru <[email protected]>

* Fixing and adding test method

---------

Co-authored-by: devcsomnicg <[email protected]>
Co-authored-by: Hardik Mashru <[email protected]>
Co-authored-by: “Akshay <“[email protected]”>
  • Loading branch information
4 people authored Jun 14, 2023
1 parent 62ac73e commit b374b12
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ public void onInboxUpdated() {

@Override
public void onListItemTapped(@NonNull IterableInAppMessage message) {
IterableApi.getInstance().getInAppManager().setRead(message, true);
IterableApi.getInstance().getInAppManager().setRead(message, true, null);

if (inboxMode == InboxMode.ACTIVITY) {
startActivity(new Intent(getContext(), IterableInboxMessageActivity.class).putExtra(IterableInboxMessageActivity.ARG_MESSAGE_ID, message.getMessageId()));
Expand All @@ -255,7 +255,7 @@ public void onListItemTapped(@NonNull IterableInAppMessage message) {

@Override
public void onListItemDeleted(@NonNull IterableInAppMessage message, @NonNull IterableInAppDeleteActionType source) {
IterableApi.getInstance().getInAppManager().removeMessage(message, source, IterableInAppLocation.INBOX);
IterableApi.getInstance().getInAppManager().removeMessage(message, source, IterableInAppLocation.INBOX, null, null);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,26 @@ public void inAppConsume(@NonNull String messageId) {
IterableLogger.e(TAG, "inAppConsume: message is null");
return;
}
inAppConsume(message, null, null);
inAppConsume(message, null, null, null, null);
IterableLogger.printInfo();
}

/**
* Consumes an InApp message.
* @param messageId
* @param successHandler The callback which returns `success`.
* @param failureHandler The callback which returns `failure`.
*/
public void inAppConsume(@NonNull String messageId, @Nullable IterableHelper.SuccessHandler successHandler, @Nullable IterableHelper.FailureHandler failureHandler) {
IterableInAppMessage message = getInAppManager().getMessageById(messageId);
if (message == null) {
IterableLogger.e(TAG, "inAppConsume: message is null");
if (failureHandler != null) {
failureHandler.onFailure("inAppConsume: message is null", null);
}
return;
}
inAppConsume(message, null, null, successHandler, failureHandler);
IterableLogger.printInfo();
}

Expand All @@ -742,8 +761,25 @@ public void inAppConsume(@NonNull IterableInAppMessage message, @Nullable Iterab
if (!checkSDKInitialization()) {
return;
}
apiClient.inAppConsume(message, source, clickLocation, inboxSessionId, null, null);
}

apiClient.inAppConsume(message, source, clickLocation, inboxSessionId);
/**
* Tracks InApp delete.
* This method from informs Iterable about inApp messages deleted with additional paramters.
* Call this method from places where inApp deletion are invoked by user. The messages can be swiped to delete or can be deleted using the link to delete button.
*
* @param message message object
* @param source An enum describing how the in App delete was triggered
* @param clickLocation The module in which the action happened
* @param successHandler The callback which returns `success`.
* @param failureHandler The callback which returns `failure`.
*/
public void inAppConsume(@NonNull IterableInAppMessage message, @Nullable IterableInAppDeleteActionType source, @Nullable IterableInAppLocation clickLocation, @Nullable IterableHelper.SuccessHandler successHandler, @Nullable IterableHelper.FailureHandler failureHandler) {
if (!checkSDKInitialization()) {
return;
}
apiClient.inAppConsume(message, source, clickLocation, inboxSessionId, successHandler, failureHandler);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ void trackInAppDelivery(@NonNull IterableInAppMessage message) {
}
}

public void inAppConsume(@NonNull IterableInAppMessage message, @Nullable IterableInAppDeleteActionType source, @Nullable IterableInAppLocation clickLocation, @Nullable String inboxSessionId) {
public void inAppConsume(@NonNull IterableInAppMessage message, @Nullable IterableInAppDeleteActionType source, @Nullable IterableInAppLocation clickLocation, @Nullable String inboxSessionId, @Nullable final IterableHelper.SuccessHandler successHandler, @Nullable final IterableHelper.FailureHandler failureHandler) {
JSONObject requestJSON = new JSONObject();

try {
Expand All @@ -336,7 +336,7 @@ public void inAppConsume(@NonNull IterableInAppMessage message, @Nullable Iterab
addInboxSessionID(requestJSON, inboxSessionId);
}

sendPostRequest(IterableConstants.ENDPOINT_INAPP_CONSUME, requestJSON);
sendPostRequest(IterableConstants.ENDPOINT_INAPP_CONSUME, requestJSON, successHandler, failureHandler);
} catch (JSONException e) {
e.printStackTrace();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ private void processMessageRemoval() {
}

if (message.isMarkedForDeletion() && !message.isConsumed()) {
IterableApi.sharedInstance.getInAppManager().removeMessage(message);
IterableApi.sharedInstance.getInAppManager().removeMessage(message, null, null);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,13 @@ public synchronized int getUnreadInboxMessagesCount() {
* Set the read flag on an inbox message
* @param message Inbox message object retrieved from {@link IterableInAppManager#getInboxMessages()}
* @param read Read state flag. true = read, false = unread
* @param successHandler The callback which returns `success`.
*/
public synchronized void setRead(@NonNull IterableInAppMessage message, boolean read) {
public synchronized void setRead(@NonNull IterableInAppMessage message, boolean read, @Nullable IterableHelper.SuccessHandler successHandler) {
message.setRead(read);
if (successHandler != null) {
successHandler.onSuccess(new JSONObject()); // passing blank json object here as onSuccess is @Nonnull
}
notifyOnChange();
}

Expand Down Expand Up @@ -239,7 +243,7 @@ public void execute(Uri url) {
scheduleProcessing();
}
})) {
setRead(message, true);
setRead(message, true, null);
if (consume) {
message.markForDeletion(true);
}
Expand All @@ -249,17 +253,19 @@ public void execute(Uri url) {
/**
* Remove message from the list
* @param message The message to be removed
* @param successHandler The callback which returns `success`.
* @param failureHandler The callback which returns `failure`.
*/
public synchronized void removeMessage(@NonNull IterableInAppMessage message) {
public synchronized void removeMessage(@NonNull IterableInAppMessage message, @Nullable IterableHelper.SuccessHandler successHandler, @Nullable IterableHelper.FailureHandler failureHandler) {
message.setConsumed(true);
api.inAppConsume(message.getMessageId());
api.inAppConsume(message.getMessageId(), successHandler, failureHandler);
notifyOnChange();
}

public synchronized void removeMessage(@NonNull IterableInAppMessage message, @NonNull IterableInAppDeleteActionType source, @NonNull IterableInAppLocation clickLocation) {
public synchronized void removeMessage(@NonNull IterableInAppMessage message, @NonNull IterableInAppDeleteActionType source, @NonNull IterableInAppLocation clickLocation, @Nullable IterableHelper.SuccessHandler successHandler, @Nullable IterableHelper.FailureHandler failureHandler) {
IterableLogger.printInfo();
message.setConsumed(true);
api.inAppConsume(message, source, clickLocation);
api.inAppConsume(message, source, clickLocation, successHandler, failureHandler);
notifyOnChange();
}

Expand Down Expand Up @@ -432,7 +438,7 @@ private boolean canShowInAppAfterPrevious() {

private void handleIterableCustomAction(String actionName, IterableInAppMessage message) {
if (IterableConstants.ITERABLE_IN_APP_ACTION_DELETE.equals(actionName)) {
removeMessage(message, IterableInAppDeleteActionType.DELETE_BUTTON, IterableInAppLocation.IN_APP);
removeMessage(message, IterableInAppDeleteActionType.DELETE_BUTTON, IterableInAppLocation.IN_APP, null, null);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@

import android.app.Activity;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.iterable.iterableapi.unit.PathBasedQueueDispatcher;

import org.json.JSONObject;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.robolectric.Robolectric;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
Expand Down Expand Up @@ -78,18 +84,98 @@ public void testInboxMessageOrdering() throws Exception {
assertEquals("message4", inboxMessages.get(1).getMessageId());
}

@Test
public void testRemoveMessageSuccessCallbackOnSuccessfulResponse() throws Exception {
final CountDownLatch signal = new CountDownLatch(1);
dispatcher.enqueueResponse("/inApp/getMessages", new MockResponse().setBody(IterableTestUtils.getResourceString("inapp_payload_inbox_multiple.json")));
final IterableInAppManager inAppManager = IterableApi.getInstance().getInAppManager();
inAppManager.syncInApp();
shadowOf(getMainLooper()).idle();
List<IterableInAppMessage> inboxMessages = inAppManager.getInboxMessages();
assertEquals(2, inboxMessages.size());
assertEquals(1, inAppManager.getUnreadInboxMessagesCount());

final JSONObject responseData = new JSONObject("{\"key\":\"value\"}");
dispatcher.enqueueResponse("/events/inAppConsume", new MockResponse().setResponseCode(200).setBody(responseData.toString()));

inAppManager.removeMessage(inboxMessages.get(0), new IterableHelper.SuccessHandler() {
@Override
public void onSuccess(@NonNull JSONObject data) {
signal.countDown();
}
}, new IterableHelper.FailureHandler() {
@Override
public void onFailure(@NonNull String reason, @Nullable JSONObject data) {
assertFalse(true);
}
});
shadowOf(getMainLooper()).idle();
assertTrue("Message remove success callback called", signal.await(1, TimeUnit.SECONDS));
}

@Test
public void testRemoveMessageFailureCallbackOnFailedResponse() throws Exception {
final CountDownLatch signal = new CountDownLatch(1);
dispatcher.enqueueResponse("/inApp/getMessages", new MockResponse().setBody(IterableTestUtils.getResourceString("inapp_payload_inbox_multiple.json")));
final IterableInAppManager inAppManager = IterableApi.getInstance().getInAppManager();
inAppManager.syncInApp();
shadowOf(getMainLooper()).idle();
List<IterableInAppMessage> inboxMessages = inAppManager.getInboxMessages();
assertEquals(2, inboxMessages.size());
assertEquals(1, inAppManager.getUnreadInboxMessagesCount());

final JSONObject responseData = new JSONObject("{\"key\":\"value\"}");
dispatcher.enqueueResponse("/events/inAppConsume", new MockResponse().setResponseCode(500).setBody(responseData.toString()));

inAppManager.removeMessage(inboxMessages.get(0), new IterableHelper.SuccessHandler() {
@Override
public void onSuccess(@NonNull JSONObject data) {
assertFalse(true);
}
}, new IterableHelper.FailureHandler() {
@Override
public void onFailure(@NonNull String reason, @Nullable JSONObject data) {
signal.countDown();
}
});
shadowOf(getMainLooper()).idle();
assertTrue("Message remove failure callback called", signal.await(1, TimeUnit.SECONDS));
}

@Test
public void testSetRead() throws Exception {
// Set up mock response
dispatcher.enqueueResponse("/inApp/getMessages", new MockResponse().setBody(IterableTestUtils.getResourceString("inapp_payload_inbox_multiple.json")));

// Initialize in-app manager and wait for messages to be synced
IterableInAppManager inAppManager = IterableApi.getInstance().getInAppManager();
inAppManager.syncInApp();
shadowOf(getMainLooper()).idle();

// Get inbox messages
List<IterableInAppMessage> inboxMessages = inAppManager.getInboxMessages();

// Verify initial state
assertEquals(1, inAppManager.getUnreadInboxMessagesCount());
assertEquals(2, inboxMessages.size());
assertFalse(inboxMessages.get(0).isRead());
assertTrue(inboxMessages.get(1).isRead());
inAppManager.setRead(inboxMessages.get(0), true);

// Set first message as read with a callback
final boolean[] callbackCalled = { false };
inAppManager.setRead(inboxMessages.get(0), true, new IterableHelper.SuccessHandler() {
@Override
public void onSuccess(@NonNull JSONObject data) {
callbackCalled[0] = true;
assertTrue(callbackCalled[0]);
}
});

// Wait for callback to be called
shadowOf(getMainLooper()).idle();

// Verify that callback was called and that message is marked as read
assertTrue(callbackCalled[0]);
assertEquals(0, inAppManager.getUnreadInboxMessagesCount());
assertEquals(2, inAppManager.getInboxMessages().size());
assertTrue(inboxMessages.get(0).isRead());
Expand Down

0 comments on commit b374b12

Please sign in to comment.