diff --git a/CHANGELOG.md b/CHANGELOG.md index f1d22851..ab80f8b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,30 @@ # Changelog All notable changes to this project will be documented here. +## [0.9.18.0] -2022-05-02 -## [0.9.17.0] -2021-04-13 +### Added + +- Add LoudnessEnhancer for audio calls + +### Changed + +- Update compileSdkVersion to 30 + +- Update targetSdkVersion to 30 + +- Update Sentry DSN + +- Update PodCall version to 3.8.21-SNAPSHOT + +### Fixed + +- Minor bug fixes and improvements for assistants management + + + + +## [0.9.17.0] -2022-04-13 ### Added diff --git a/app/src/androidTest/java/com/example/podchat/AssistantCacheTest.java b/app/src/androidTest/java/com/example/podchat/AssistantCacheTest.java new file mode 100644 index 00000000..5178fa8d --- /dev/null +++ b/app/src/androidTest/java/com/example/podchat/AssistantCacheTest.java @@ -0,0 +1,1082 @@ +package com.example.podchat; + + +import static com.example.chat.application.chatexample.ChatActivity.APP_ID; +import static com.fanap.podchat.util.ChatStateType.ChatSateConstant.CHAT_READY; + +import android.app.Activity; +import android.content.Context; +import android.os.Looper; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.LargeTest; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; + +import com.example.chat.application.chatexample.BaseApplication; +import com.example.chat.application.chatexample.ChatActivity; +import com.example.chat.application.chatexample.ChatContract; +import com.example.chat.application.chatexample.ChatPresenter; +import com.fanap.podchat.chat.App; +import com.fanap.podchat.chat.Chat; +import com.fanap.podchat.chat.ChatListener; +import com.fanap.podchat.chat.RoleType; +import com.fanap.podchat.chat.assistant.model.AssistantHistoryVo; +import com.fanap.podchat.chat.assistant.model.AssistantVo; +import com.fanap.podchat.chat.assistant.request_model.BlockUnblockAssistantRequest; +import com.fanap.podchat.chat.assistant.request_model.GetAssistantHistoryRequest; +import com.fanap.podchat.chat.assistant.request_model.GetAssistantRequest; +import com.fanap.podchat.chat.assistant.request_model.GetBlockedAssistantsRequest; +import com.fanap.podchat.chat.assistant.request_model.RegisterAssistantRequest; +import com.fanap.podchat.example.R; +import com.fanap.podchat.mainmodel.Contact; +import com.fanap.podchat.mainmodel.Invitee; +import com.fanap.podchat.mainmodel.MessageVO; +import com.fanap.podchat.mainmodel.Participant; +import com.fanap.podchat.mainmodel.Thread; +import com.fanap.podchat.model.ChatResponse; +import com.fanap.podchat.model.ResultContact; +import com.fanap.podchat.model.ResultHistory; +import com.fanap.podchat.model.ResultParticipant; +import com.fanap.podchat.model.ResultThreads; +import com.fanap.podchat.requestobject.RequestConnect; +import com.fanap.podchat.requestobject.RequestGetContact; +import com.fanap.podchat.requestobject.RequestGetHistory; +import com.fanap.podchat.requestobject.RequestThread; +import com.fanap.podchat.requestobject.RequestThreadParticipant; +import com.fanap.podchat.util.InviteType; +import com.orhanobut.logger.Logger; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +@RunWith(AndroidJUnit4.class) +public class AssistantCacheTest { + + + public static final boolean CACHE = true; + private static ChatContract.presenter presenter; + @Mock + private static ChatContract.view view; + + + @Mock + private Activity activity; + private static Context appContext; + + private static String serverName = "chat-server"; + private static String appId = "POD-Chat"; + private static String ssoHost = BaseApplication.getInstance().getString(R.string.ssoHost); + private static String NAME = BaseApplication.getInstance().getString(R.string.sandbox_server_name); + private static String socketAddress = BaseApplication.getInstance().getString(R.string.sandbox_socketAddress); + private static String platformHost = BaseApplication.getInstance().getString(R.string.sandbox_platformHost); + private static String fileServer = BaseApplication.getInstance().getString(R.string.sandbox_fileServer); + private static String TOKEN = "cf06e0e5cc3f41fba837f4d05b9a4138"; + + + @Mock + ChatListener chatListeners; + + private ChatActivity chatActivity; + + + static Chat chat; + + static final Object sync = new Object(); + + @Rule + public ActivityTestRule chatActivityRule = new ActivityTestRule<>(ChatActivity.class); + + final ArrayList threads = new ArrayList<>(); + final ArrayList threadMessagesList = new ArrayList<>(); + final ArrayList threadParticipant = new ArrayList<>(); + final ArrayList contacts = new ArrayList<>(); + + @BeforeClass + public static void initial() { + + + appContext = InstrumentationRegistry.getTargetContext(); + + chat = Chat.init(appContext); + Looper.prepare(); + } + + @Before + public void createChat() { + + + view = Mockito.mock(ChatContract.view.class); + + chatActivity = chatActivityRule.getActivity(); + presenter = new ChatPresenter(appContext, view, chatActivity); + + RequestConnect rc = new RequestConnect.Builder( + socketAddress, + APP_ID, + serverName, + TOKEN, + ssoHost, + platformHost, + fileServer, + "podSpaceServer") + .build(); + + + chatListeners = new ChatListener() { + @Override + public void onChatState(String state) { + if (state.equals(CHAT_READY)) { + resumeProcess(); + } + } + }; + + chat.addListener(chatListeners); + + chat.connect(rc); + + chat.isCacheables(CACHE); + + pauseProcess(); + + + } + + ///////////////////////////////////////////////////////////////////////////////// + + + //requests for list of threads + public void populateThreadsListFromServerOrCache() { + + + chatListeners = new ChatListener() { + @Override + public void onGetThread(String content, ChatResponse thread) { + + print("Received List: " + content); + threads.addAll(thread.getResult().getThreads()); + chat.removeListener(chatListeners); + + } + }; + + chat.addListener(chatListeners); + + RequestThread requestThread = + new RequestThread.Builder() + .count(25) + .build(); + + presenter.getThreads(requestThread, null); + + long t1 = System.currentTimeMillis(); + Mockito.verify(view, Mockito.after(10000).atLeastOnce()).onGetThreadList(Mockito.any(), Mockito.any()); + long t2 = System.currentTimeMillis(); + System.out.println("Received List: " + threads.size() + " after: " + (t2 - t1) + " ms"); + + } + + //requests for list of threads from server + + public void populateThreadsListFromServerOnly() { + + + chatListeners = new ChatListener() { + @Override + public void onGetThread(String content, ChatResponse response) { + + if (!response.isCache()) { + print("Received List: " + content); + threads.addAll(response.getResult().getThreads() + .stream() + .filter(thread -> thread.getTitle() != null + && thread.getId() > 0 + && !thread.isClosed() + && thread.getLastMessageVO() != null) + .collect(Collectors.toList())); + + chat.removeListener(chatListeners); + resumeProcess(); + } + + } + }; + + chat.setListener(chatListeners); + + RequestThread requestThread = + new RequestThread.Builder() + .count(25) + .withNoCache() + .build(); + + presenter.getThreads(requestThread, null); + + pauseProcess(); + print("Received List: " + threads.size()); + + } + + //requests for list of threads from cache + + public void populateThreadsListFromCacheOnly() { + + + chatListeners = new ChatListener() { + @Override + public void onGetThread(String content, ChatResponse thread) { + + if (thread.isCache()) { + print("Received List: " + content); + threads.addAll(thread.getResult().getThreads()); + chat.removeListener(chatListeners); + resumeProcess(); + } + + } + }; + + chat.addListener(chatListeners); + + RequestThread requestThread = + new RequestThread.Builder() + .count(25) + .build(); + + presenter.getThreads(requestThread, null); + + pauseProcess(); + print("Received List: " + threads.size()); + + } + + + public void populateMessagesFromServer() { + populateThreadsListFromServerOnly(); + assert threads.size() > 0; + + Thread thread = threads.get(0); + + chatListeners = new ChatListener() { + @Override + public void onGetHistory(String content, ChatResponse history) { + + if (!history.isCache()) { + print("Received Message List Server: " + content); + + threadMessagesList.addAll(history.getResult().getHistory() + .stream() + .filter(messageVO -> + messageVO.getMessage() != null) + .collect(Collectors.toList())); + + chat.removeListener(chatListeners); + resumeProcess(); + } + } + }; + + chat.addListener(chatListeners); + + RequestGetHistory requestGetHistory + = new RequestGetHistory.Builder(thread.getId()) + .withNoCache() + .build(); + + chat.getHistory(requestGetHistory, null); + pauseProcess(); + } + + + public void populateMessagesFromCache() { + populateThreadsListFromServerOnly(); + assert threads.size() > 0; + + Thread thread = threads.get(0); + + chatListeners = new ChatListener() { + @Override + public void onGetHistory(String content, ChatResponse history) { + + if (history.isCache()) { + print("Received Message List Cache: " + content); + threadMessagesList.addAll(history.getResult().getHistory()); + chat.removeListener(chatListeners); + resumeProcess(); + } + } + }; + + chat.addListener(chatListeners); + + RequestGetHistory requestGetHistory + = new RequestGetHistory.Builder(thread.getId()) + .build(); + + chat.getHistory(requestGetHistory, null); + pauseProcess(); + } + + + public void populateMessagesFromServerOrCache() { + populateThreadsListFromServerOnly(); + assert threads.size() > 0; + + Thread thread = threads.get(0); + + chatListeners = new ChatListener() { + @Override + public void onGetHistory(String content, ChatResponse history) { + + System.out.println("Received Message List, Cache: " + history.isCache() + " Content: " + content); + threadMessagesList.addAll(history.getResult().getHistory()); + chat.removeListener(chatListeners); + resumeProcess(); + + } + }; + + chat.addListener(chatListeners); + + RequestGetHistory requestGetHistory + = new RequestGetHistory.Builder(thread.getId()) + .build(); + + chat.getHistory(requestGetHistory, null); + pauseProcess(); + } + + public void populateContactsFromServer() { + chatListeners = new ChatListener() { + @Override + public void onGetContacts(String content, ChatResponse response) { + if (!response.isCache()) { + print("Received List: " + content); + contacts.addAll(response.getResult().getContacts()); + chat.removeListener(chatListeners); + resumeProcess(); + } + } + }; + + chat.setListener(chatListeners); + + RequestGetContact request = + new RequestGetContact.Builder() + .count(50) + .offset(0) + .build(); + + chat.getContacts(request, null); + pauseProcess(); + print("Received Contact List: " + contacts.size()); + } + + @Test + public void populateParticipantList() { + populateThreadsListFromServerOnly(); + assert threads.size() > 0; + + Thread thread = getValidGroupThread(); + + chatListeners = new ChatListener() { + @Override + public void onGetThreadParticipant(String content, ChatResponse response) { + + System.out.println("Received Participant, Cache: " + response.isCache() + " Content: " + content); + if (response.getResult().getParticipants().size() > 1) { + threadParticipant.addAll(response.getResult().getParticipants()); + chat.removeListener(chatListeners); + resumeProcess(); + } else { + threads.remove(thread); + Thread t2 = getValidGroupThread(); + print("try again changing thread..."); + RequestThreadParticipant request = + new RequestThreadParticipant.Builder() + .threadId(t2.getId()) + .build(); + + chat.getThreadParticipants(request, null); + } + + + } + }; + + chat.addListener(chatListeners); + + RequestThreadParticipant request = + new RequestThreadParticipant.Builder() + .threadId(thread.getId()) + .build(); + + chat.getThreadParticipants(request, null); + pauseProcess(); + } + + + @Test + public void registerNewAssistant() { + populateContactsFromServer(); + + ChatListener mTestListener = Mockito.mock(ChatListener.class); + chat.addListener(mTestListener); + assert contacts.size() > 0; + Contact contact = getValidContact(); + print("Selected contact for register as assistant " + App.getGson().toJson(contact)); + ArrayList typeRoles = new ArrayList<>(); + typeRoles.add(RoleType.Constants.ADD_ROLE_TO_USER); + typeRoles.add(RoleType.Constants.READ_THREAD); + typeRoles.add(RoleType.Constants.EDIT_THREAD); + + + List assistantVos = new ArrayList<>(); + AssistantVo assistantVo = new AssistantVo(); + + Invitee invite = new Invitee(contact.getId(), InviteType.Constants.TO_BE_USER_CONTACT_ID); + + assistantVo.setInvitees(invite); + assistantVo.setContactType("default"); + assistantVo.setRoles(typeRoles); + + assistantVos.add(assistantVo); + + RegisterAssistantRequest request = new RegisterAssistantRequest.Builder(assistantVos).build(); + + chat.registerAssistant(request); + + Mockito.verify(mTestListener, Mockito.after(5000).atLeastOnce()).onRegisterAssistant( + Mockito.argThat((ChatResponse> response) -> response.getResult().stream().anyMatch( + assistantVo1 -> assistantVo1.getParticipantVO().getCoreUserId() == contact.getLinkedUser().getCoreUserId() + )) + ); + + } + + + @Test + public void getAssistantList() { + + ChatListener mTestListener = Mockito.mock(ChatListener.class); + chat.addListener(mTestListener); + GetAssistantRequest request = new GetAssistantRequest.Builder() + .setCount(25) + .setOffset(0) + .build(); + chat.getAssistants(request); + + Mockito.verify(mTestListener, Mockito.after(2000).atLeastOnce()).onGetAssistants(Mockito.any()); + + } + + //Register new assistant and check if it is in cache + + @LargeTest + @Test + public void checkRegisteredAssistantInCache() { + populateContactsFromServer(); + assert contacts.size() > 0; + Collections.shuffle(contacts); + Contact contact = getValidContact(); + print("Selected contact for register as assistant " + App.getGson().toJson(contact)); + ArrayList typeRoles = new ArrayList<>(); + typeRoles.add(RoleType.Constants.ADD_ROLE_TO_USER); + typeRoles.add(RoleType.Constants.READ_THREAD); + typeRoles.add(RoleType.Constants.EDIT_THREAD); + + + List assistantVos = new ArrayList<>(); + AssistantVo assistantVo = new AssistantVo(); + + Invitee invite = new Invitee(contact.getId(), InviteType.Constants.TO_BE_USER_CONTACT_ID); + + assistantVo.setInvitees(invite); + assistantVo.setContactType("default"); + assistantVo.setRoles(typeRoles); + + assistantVos.add(assistantVo); + + final AssistantVo[] registeredAssistant = new AssistantVo[1]; + + ChatListener mListener = new ChatListener() { + @Override + public void onRegisterAssistant(ChatResponse> response) { + + registeredAssistant[0] = response.getResult().get(0); + chat.removeListener(this); + resumeProcess(); + } + }; + chat.setListener(mListener); + RegisterAssistantRequest request = new RegisterAssistantRequest.Builder(assistantVos).build(); + + chat.registerAssistant(request); + pauseProcess(); + + ChatListener mTestListener = Mockito.mock(ChatListener.class); + chat.addListener(mTestListener); + GetAssistantRequest requestGet = new GetAssistantRequest.Builder() + .setCount(25) + .setOffset(0) + .build(); + chat.getAssistants(requestGet); + + Mockito.verify(mTestListener, Mockito.after(2000).atLeastOnce()).onGetAssistants( + Mockito.argThat((ChatResponse> response) -> (response.isCache() && validateAssistantsAreSame(registeredAssistant[0], response.getResult()))) + ); + + } + + @Test + public void checkCacheAndServerAssistantList() { + ArrayList inCache = new ArrayList<>(); + ArrayList inServer = new ArrayList<>(); + + chat.addListener(new ChatListener() { + @Override + public void onGetAssistants(ChatResponse> response) { + + if (response.isCache()) { + inCache.addAll(response.getResult()); + } else { + inServer.addAll(response.getResult()); + } + if (inCache.size() > 0 && inServer.size() > 0) { + chat.removeListener(this); + resumeProcess(); + } + + } + }); + + GetAssistantRequest request = new GetAssistantRequest.Builder() + .setCount(25) + .setOffset(0) + .build(); + chat.getAssistants(request); + pauseProcess(); + + Assert.assertEquals(inCache.size(), inServer.size()); + for (AssistantVo assistantInServer : + inServer) { + Assert.assertTrue(validateAssistantsAreSame(assistantInServer, inCache)); + } + } + + @Test + public void blockAssistantAndCheckCache() { + populateContactsFromServer(); + List assistantVos = new ArrayList<>(); + chat.addListener(new ChatListener() { + @Override + public void onGetAssistants(ChatResponse> response) { + if (!response.isCache()) { + prettyLog(response.getJson()); + assistantVos.addAll(response.getResult()); + chat.removeListener(this); + resumeProcess(); + } + + } + }); + GetAssistantRequest request = new GetAssistantRequest.Builder() + .setCount(25) + .withNoCache() + .setOffset(0) + .build(); + chat.getAssistants(request); + pauseProcess(); + + + //the block assistant method accepts only Invitee + + Collections.shuffle(assistantVos); + + List notBlockedAssistants = assistantVos.stream().filter(assistantVo -> !assistantVo.getBlock()).collect(Collectors.toList()); + + Contact assistantContactToBlock = + contacts.stream().filter( + contact -> + contact.getLinkedUser() != null + && Objects.equals(contact.getLinkedUser().getUsername(), + notBlockedAssistants.get(0).getParticipantVO().getUsername())) + .findFirst().get(); + + print("Going to block " + assistantContactToBlock.getFirstName()); + prettyLog(App.getGson().toJson(assistantContactToBlock)); + + Invitee invitee = new Invitee(assistantContactToBlock.getId(), InviteType.Constants.TO_BE_USER_CONTACT_ID); + AssistantVo assistantToBlock = new AssistantVo(); + assistantToBlock.setInvitees(invitee); + List toBlockAssistantList = new ArrayList<>(); + toBlockAssistantList.add(assistantToBlock); + + + chat.addListener(new ChatListener() { + @Override + public void onAssistantBlocked(ChatResponse> response) { + prettyLog(response.getJson()); + toBlockAssistantList.clear(); + toBlockAssistantList.addAll(response.getResult()); + chat.removeListener(this); + resumeProcess(); + } + }); + + + BlockUnblockAssistantRequest requestBlock = + new BlockUnblockAssistantRequest.Builder(toBlockAssistantList, true) + .build(); + chat.blockAssistant(requestBlock); + pauseProcess(); + + + ArrayList inCache = new ArrayList<>(); + + chat.addListener(new ChatListener() { + @Override + public void onGetAssistants(ChatResponse> response) { + + if (response.isCache()) { + prettyLog(response.getJson()); + inCache.addAll(response.getResult()); + chat.removeListener(this); + resumeProcess(); + } + + } + }); + + GetAssistantRequest requestGetAssistantFromCache = new GetAssistantRequest.Builder() + .setCount(25) + .setOffset(0) + .build(); + chat.getAssistants(requestGetAssistantFromCache); + pauseProcess(); + + assert inCache.size() > 0; + + Assert.assertTrue(inCache.stream().filter(anAssistantInCache -> + toBlockAssistantList.stream().anyMatch(blockListAssistant -> + anAssistantInCache.getParticipantVO().getId() == blockListAssistant.getParticipantVO().getId()) + ).findFirst().get().getBlock()); + + + } + + @Test + public void getBlockedAssistantsList() { + + + ArrayList blockedListFromServer = new ArrayList<>(); + ArrayList blockedListInCache = new ArrayList<>(); + chat.addListener(new ChatListener() { + @Override + public void onAssistantBlocks(ChatResponse> response) { + print("Blocked assistants list cache: " + response.isCache()); + prettyLog(response.getJson()); + if (response.isCache()) { + blockedListInCache.addAll(response.getResult()); + } else { + blockedListFromServer.addAll(response.getResult()); + } + + if (blockedListFromServer.size() == blockedListInCache.size()) { + print("Cache and Server data are filled now"); + chat.removeListener(this); + resumeProcess(); + } + } + }); + + + GetBlockedAssistantsRequest getBlockedAssistantsRequest = + new GetBlockedAssistantsRequest.Builder() + .build(); + chat.getBlocksAssistant(getBlockedAssistantsRequest); + pauseProcess(); + + + for (AssistantVo assistantCache : + blockedListInCache) { + + AssistantVo assistantServer = blockedListFromServer.stream().filter(assistantVo -> assistantVo.getParticipantVO().getId() + == assistantCache.getParticipantVO().getId()).findFirst().get(); + + + if (!assistantCache.getRoles().containsAll(assistantServer.getRoles())) { + Assert.fail("Roles are not same => " + assistantCache.getRoles() + " != " + assistantServer.getRoles()); + } + + } + + + Assert.assertTrue(true); + } + + @Test + public void unBlockAssistantAndCheckBlockListInCache() { + populateContactsFromServer(); + + + ArrayList blockedListFromServer = new ArrayList<>(); + chat.addListener(new ChatListener() { + @Override + public void onAssistantBlocks(ChatResponse> response) { + print("Blocked assistants list cache: " + response.isCache()); + prettyLog(response.getJson()); + blockedListFromServer.addAll(response.getResult()); + chat.removeListener(this); + resumeProcess(); + } + }); + GetBlockedAssistantsRequest getBlockedAssistantsRequest = + new GetBlockedAssistantsRequest.Builder() + .withNoCache() + .build(); + chat.getBlocksAssistant(getBlockedAssistantsRequest); + pauseProcess(); + + + Contact assistantContactToUnBlock = + contacts.stream().filter( + contact -> + contact.getLinkedUser() != null + && Objects.equals(contact.getLinkedUser().getUsername(), + blockedListFromServer.get(0).getParticipantVO().getUsername())) + .findFirst().get(); + + print("Going to unblock " + assistantContactToUnBlock.getFirstName()); + prettyLog(App.getGson().toJson(assistantContactToUnBlock)); + + Invitee invitee = new Invitee(assistantContactToUnBlock.getId(), InviteType.Constants.TO_BE_USER_CONTACT_ID); + AssistantVo assistantToUnBlock = new AssistantVo(); + assistantToUnBlock.setInvitees(invitee); + List toUnBlockAssistantList = new ArrayList<>(); + toUnBlockAssistantList.add(assistantToUnBlock); + + + chat.addListener(new ChatListener() { + @Override + public void onAssistantUnBlocked(ChatResponse> response) { + print("Assistant unblocked"); + prettyLog(response.getJson()); + toUnBlockAssistantList.clear(); + toUnBlockAssistantList.addAll(response.getResult()); + chat.removeListener(this); + resumeProcess(); + } + }); + + + ChatListener mMockedListener = Mockito.mock(ChatListener.class); + chat.addListener(mMockedListener); + + BlockUnblockAssistantRequest requestBlock = + new BlockUnblockAssistantRequest.Builder(toUnBlockAssistantList, false) + .build(); + chat.unBlockAssistant(requestBlock); + pauseProcess(); + + + ArrayList blockedListInCache = new ArrayList<>(); + chat.addListener(new ChatListener() { + @Override + public void onAssistantBlocks(ChatResponse> response) { + print("Blocked assistants list cache: " + response.isCache()); + prettyLog(response.getJson()); + if (response.isCache()) { + blockedListInCache.addAll(response.getResult()); + chat.removeListener(this); + resumeProcess(); + } + } + }); + + + GetBlockedAssistantsRequest getBlockedAssistantsRequest2 = + new GetBlockedAssistantsRequest.Builder() + .build(); + chat.getBlocksAssistant(getBlockedAssistantsRequest2); + pauseProcess(); + + + Assert.assertTrue(blockedListInCache.stream().noneMatch(assistantVo -> + assistantVo.getParticipantVO().getId() == toUnBlockAssistantList.get(0).getParticipantVO().getId())); + + + } + + + @Test + public void unBlockAssistantAndCheckAssistantListInCache() { + populateContactsFromServer(); + + + ArrayList blockedListFromServer = new ArrayList<>(); + chat.addListener(new ChatListener() { + @Override + public void onAssistantBlocks(ChatResponse> response) { + print("Blocked assistants list cache: " + response.isCache()); + prettyLog(response.getJson()); + blockedListFromServer.addAll(response.getResult()); + chat.removeListener(this); + resumeProcess(); + } + }); + GetBlockedAssistantsRequest getBlockedAssistantsRequest = + new GetBlockedAssistantsRequest.Builder() + .withNoCache() + .build(); + chat.getBlocksAssistant(getBlockedAssistantsRequest); + pauseProcess(); + + + Contact assistantContactToUnBlock = + contacts.stream().filter( + contact -> + contact.getLinkedUser() != null + && Objects.equals(contact.getLinkedUser().getUsername(), + blockedListFromServer.get(0).getParticipantVO().getUsername())) + .findFirst().get(); + + print("Going to unblock " + assistantContactToUnBlock.getFirstName()); + prettyLog(App.getGson().toJson(assistantContactToUnBlock)); + + Invitee invitee = new Invitee(assistantContactToUnBlock.getId(), InviteType.Constants.TO_BE_USER_CONTACT_ID); + AssistantVo assistantToUnBlock = new AssistantVo(); + assistantToUnBlock.setInvitees(invitee); + List toUnBlockAssistantList = new ArrayList<>(); + toUnBlockAssistantList.add(assistantToUnBlock); + + + chat.addListener(new ChatListener() { + @Override + public void onAssistantUnBlocked(ChatResponse> response) { + print("Assistant unblocked"); + prettyLog(response.getJson()); + toUnBlockAssistantList.clear(); + toUnBlockAssistantList.addAll(response.getResult()); + chat.removeListener(this); + resumeProcess(); + } + }); + + + ChatListener mMockedListener = Mockito.mock(ChatListener.class); + chat.addListener(mMockedListener); + + BlockUnblockAssistantRequest requestBlock = + new BlockUnblockAssistantRequest.Builder(toUnBlockAssistantList, false) + .build(); + chat.unBlockAssistant(requestBlock); + pauseProcess(); + + + ArrayList assistantListInCache = new ArrayList<>(); + chat.addListener(new ChatListener() { + @Override + public void onGetAssistants(ChatResponse> response) { + print("Receive assistants list cache: " + response.isCache()); + prettyLog(response.getJson()); + if (response.isCache()) { + assistantListInCache.addAll(response.getResult()); + chat.removeListener(this); + resumeProcess(); + } + } + }); + + + GetAssistantRequest getAssistantRequest = + new GetAssistantRequest.Builder() + .build(); + chat.getAssistants(getAssistantRequest); + pauseProcess(); + + + Assert.assertTrue(assistantListInCache.stream().anyMatch(assistantInCache -> + assistantInCache.getParticipantVO().getId() == toUnBlockAssistantList.get(0).getParticipantVO().getId() + && !assistantInCache.getBlock())); + + + } + + + @Test + public void getAssistantHistories() { + + + ArrayList assistantVoArrayList = new ArrayList<>(); + chat.addListener(new ChatListener() { + @Override + public void onGetAssistants(ChatResponse> response) { + + assistantVoArrayList.addAll(response.getResult()); + chat.removeListener(this); + resumeProcess(); + } + }); + GetAssistantRequest request = new GetAssistantRequest.Builder() + .setCount(25) + .setOffset(0) + .build(); + chat.getAssistants(request); + pauseProcess(); + + + Collections.shuffle(assistantVoArrayList); + + ChatListener mMockedListener = Mockito.mock(ChatListener.class); + chat.addListener(mMockedListener); + GetAssistantHistoryRequest getAssistantHistoryRequest = new GetAssistantHistoryRequest.Builder() + .setCount(50) + .build(); + chat.getAssistantHistory(getAssistantHistoryRequest); + + Mockito.verify(mMockedListener, Mockito.after(3000).atLeastOnce()) + .onGetAssistantHistory(Mockito.any()); + + } + + @Test + public void getAndValidateAssistantHistoriesCache() { + + + ArrayList assistantVoArrayList = new ArrayList<>(); + chat.addListener(new ChatListener() { + @Override + public void onGetAssistants(ChatResponse> response) { + + assistantVoArrayList.addAll(response.getResult()); + chat.removeListener(this); + resumeProcess(); + } + }); + GetAssistantRequest request = new GetAssistantRequest.Builder() + .setCount(25) + .setOffset(0) + .build(); + chat.getAssistants(request); + pauseProcess(); + + + Collections.shuffle(assistantVoArrayList); + + + ArrayList assistantHistoryVos = new ArrayList<>(); + ArrayList assistantHistoryVosCache = new ArrayList<>(); + chat.addListener(new ChatListener() { + @Override + public void onGetAssistantHistory(ChatResponse> response) { + print("Received Assistant Histories cache: " + response.isCache()); + prettyLog(App.getGson().toJson(response.getResult())); + if(response.isCache()){ + assistantHistoryVosCache.addAll(response.getResult()); + }else { + assistantHistoryVos.addAll(response.getResult()); + } + + if(assistantHistoryVos.size() == assistantHistoryVosCache.size()){ + chat.removeListener(this); + resumeProcess(); + } + } + }); + GetAssistantHistoryRequest getAssistantHistoryRequest = new GetAssistantHistoryRequest.Builder() + .setCount(50) + .build(); + chat.getAssistantHistory(getAssistantHistoryRequest); + pauseProcess(); + Assert.assertTrue(true); + + } + + private boolean checkWithBlocked(AssistantVo assistantVoInCache, List toBlockAssistantList) { + + AssistantVo blocked = toBlockAssistantList.stream().filter(assist -> assist.getParticipantVO().getId() == assistantVoInCache.getParticipantVO().getId()).findFirst().get(); + + + return false; + } + + private boolean validateAssistantsAreSame(AssistantVo assistantInServer, List assistantVoListFromCache) { + + + return assistantVoListFromCache.stream().anyMatch( + cacheAssistant -> + (assistantInServer.getParticipantVO().getId() == cacheAssistant.getParticipantVO().getId()) // existence of assistant in cache + && (assistantInServer.getBlock() == cacheAssistant.getBlock()) + && (assistantInServer.getRoles().containsAll(cacheAssistant.getRoles())) + && (assistantInServer.getContactType().equals(cacheAssistant.getContactType())) + && (assistantInServer.getParticipantVO().getName().equals(cacheAssistant.getParticipantVO().getName())) + && (assistantInServer.getParticipantVO().getAdmin().equals(cacheAssistant.getParticipantVO().getAdmin())) + && (assistantInServer.getParticipantVO().getChatProfileVO() == null || assistantInServer.getParticipantVO().getChatProfileVO().getBio().equals(cacheAssistant.getParticipantVO().getChatProfileVO().getBio())) + && (assistantInServer.getParticipantVO().getContactFirstName() == null || assistantInServer.getParticipantVO().getContactFirstName().equals(cacheAssistant.getParticipantVO().getContactFirstName())) + + + ); + + } + + private Contact getValidContact() { + return contacts.stream().filter(contact -> contact.isHasUser() && contact.getLinkedUser() != null).collect( + Collectors.toList() + ).get(0); + } + + + private Thread getValidGroupThread() { + Thread selected = threads.stream() + .filter(thread1 -> (thread1.isGroup() && !thread1.isClosed() && thread1.getAdmin())).collect(Collectors.toList()).get(0); + + print("Selected thread: " + App.getGson().toJson(selected)); + return selected; + } + + ///////////////////////////////////////////////////////////////////////////////////////// + private void resumeProcess() { + synchronized (sync) { + sync.notify(); + } + } + + private void pauseProcess() { + synchronized (sync) { + try { + sync.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + private void sleep(int i) { + try { + java.lang.Thread.sleep(i); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + private void print(String s) { + System.out.println(s); + } + + private void prettyLog(String jsonInfo) { + Logger.json(jsonInfo); + } +} diff --git a/app/src/androidTest/java/com/example/podchat/BotCacheTest.java b/app/src/androidTest/java/com/example/podchat/BotCacheTest.java deleted file mode 100644 index 9c66deb7..00000000 --- a/app/src/androidTest/java/com/example/podchat/BotCacheTest.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.example.podchat; - -import static com.example.chat.application.chatexample.ChatActivity.APP_ID; -import static com.fanap.podchat.util.ChatStateType.ChatSateConstant.CHAT_READY; - -import android.app.Activity; -import android.content.Context; -import android.os.Looper; -import android.support.test.InstrumentationRegistry; -import android.support.test.rule.ActivityTestRule; -import android.support.test.runner.AndroidJUnit4; - -import com.example.chat.application.chatexample.BaseApplication; -import com.example.chat.application.chatexample.ChatActivity; -import com.example.chat.application.chatexample.ChatContract; -import com.example.chat.application.chatexample.ChatPresenter; -import com.fanap.podchat.chat.Chat; -import com.fanap.podchat.chat.ChatListener; -import com.fanap.podchat.example.R; -import com.fanap.podchat.mainmodel.Contact; -import com.fanap.podchat.model.ChatResponse; -import com.fanap.podchat.model.ResultContact; -import com.fanap.podchat.requestobject.RequestConnect; -import com.fanap.podchat.requestobject.RequestGetContact; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; - -import java.util.ArrayList; - - -@RunWith(AndroidJUnit4.class) -public class BotCacheTest { - - public static final boolean CACHE = true; - private static ChatContract.presenter presenter; - @Mock - private static ChatContract.view view; - - @Mock - private Activity activity; - private static Context appContext; - - private static String serverName = "chat-server"; - private static String appId = "POD-Chat"; - private static String ssoHost = BaseApplication.getInstance().getString(R.string.ssoHost); - private static String NAME = BaseApplication.getInstance().getString(R.string.sandbox_server_name); - private static String socketAddress = BaseApplication.getInstance().getString(R.string.sandbox_socketAddress); - private static String platformHost = BaseApplication.getInstance().getString(R.string.sandbox_platformHost); - private static String fileServer = BaseApplication.getInstance().getString(R.string.sandbox_fileServer); - private static String TOKEN = "4efac6081fb348b6992b06c9bada213a"; - - @Mock - ChatListener chatListeners; - - private ChatActivity chatActivity; - - static Chat chat; - - static final Object sync = new Object(); - - @Rule - public ActivityTestRule chatActivityRule = new ActivityTestRule<>(ChatActivity.class); - - @BeforeClass - public static void initial() { - appContext = InstrumentationRegistry.getTargetContext(); - - chat = Chat.init(appContext); - Looper.prepare(); - } - - @Before - public void createChat() { - - - view = Mockito.mock(ChatContract.view.class); - - chatActivity = chatActivityRule.getActivity(); - presenter = new ChatPresenter(appContext, view, chatActivity); - - RequestConnect rc = new RequestConnect.Builder( - socketAddress, - APP_ID, - serverName, - TOKEN, - ssoHost, - platformHost, - fileServer, - "podSpaceServer") - .build(); - - - chatListeners = new ChatListener() { - @Override - public void onChatState(String state) { - if (state.equals(CHAT_READY)) { - resumeProcess(); - } - } - }; - - chat.addListener(chatListeners); - - chat.connect(rc); - - chat.isCacheables(CACHE); - - pauseProcess(); - - - } - - private void resumeProcess() { - synchronized (sync) { - sync.notify(); - } - } - - private void pauseProcess() { - synchronized (sync) { - try { - sync.wait(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - - private void sleep(int i) { - try { - java.lang.Thread.sleep(i); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } -} diff --git a/app/src/androidTest/java/com/example/podchat/CallTest.java b/app/src/androidTest/java/com/example/podchat/CallTest.java deleted file mode 100644 index ae209aab..00000000 --- a/app/src/androidTest/java/com/example/podchat/CallTest.java +++ /dev/null @@ -1,242 +0,0 @@ -package com.example.podchat; - -import static com.example.chat.application.chatexample.ChatActivity.APP_ID; -import static com.fanap.podchat.util.ChatStateType.ChatSateConstant.CHAT_READY; - -import android.app.Activity; -import android.content.Context; -import android.os.Looper; -import android.support.test.InstrumentationRegistry; -import android.support.test.rule.ActivityTestRule; -import android.support.test.runner.AndroidJUnit4; -import android.view.View; -import android.view.ViewGroup; - -import com.example.chat.application.chatexample.BaseApplication; -import com.example.chat.application.chatexample.CallActivity; -import com.example.chat.application.chatexample.CallContract; -import com.example.chat.application.chatexample.CallPresenter; -import com.fanap.podcall.view.CallPartnerView; -import com.fanap.podchat.call.constants.CallType; -import com.fanap.podchat.call.request_model.GetCallHistoryRequest; -import com.fanap.podchat.chat.CallPartnerViewManager; -import com.fanap.podchat.chat.Chat; -import com.fanap.podchat.chat.ChatAdapter; -import com.fanap.podchat.chat.ChatListener; -import com.fanap.podchat.example.R; -import com.fanap.podchat.requestobject.RequestConnect; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -import java.util.concurrent.ConcurrentLinkedQueue; - - -@RunWith(AndroidJUnit4.class) -public class CallTest extends ChatAdapter { - - private static CallContract.presenter presenter; - @Mock - private static CallContract.view view; - - - @Mock - private Activity activity; - private static Context appContext; - - private static String serverName = "chat-server"; - private static String appId = "POD-Chat"; - private static String ssoHost = BaseApplication.getInstance().getString(R.string.ssoHost); - private static String NAME = BaseApplication.getInstance().getString(R.string.sandbox_server_name); - private static String socketAddress = BaseApplication.getInstance().getString(R.string.sandbox_socketAddress); - private static String platformHost = BaseApplication.getInstance().getString(R.string.sandbox_platformHost); - private static String fileServer = BaseApplication.getInstance().getString(R.string.sandbox_fileServer); - private static String TOKEN = "cf06e0e5cc3f41fba837f4d05b9a4138"; - - - @Mock - ChatListener chatListeners; - - private CallActivity callActivty; - - - static Chat chat; - - static final Object sync = new Object(); - - @Rule - public ActivityTestRule callActivtyRule = new ActivityTestRule<>(CallActivity.class); - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @BeforeClass - public static void initial() { - - - appContext = InstrumentationRegistry.getTargetContext(); - - chat = Chat.init(appContext); - - } - - @Before - public void createChat() { - Looper.prepare(); - MockitoAnnotations.initMocks(this); - - RequestConnect rc = new RequestConnect.Builder( - socketAddress, - APP_ID, - serverName, - TOKEN, - ssoHost, - platformHost, - fileServer, - "podSpaceServer") - .build(); - - - chatListeners = new ChatListener() { - @Override - public void onChatState(String state) { - if (state.equals(CHAT_READY)) { - resumeProcess(); - } - } - }; - - chat.addListener(chatListeners); - - chat.connect(rc); - - pauseProcess(); - - - } - - @Before - public void setUp() { - - callActivty = callActivtyRule.getActivity(); - presenter = new CallPresenter(appContext, view, callActivty); - - - } - - - @Test - public void setupCallTest() { - CallPartnerViewManager viewManager = chat.useCallPartnerViewManager(); - Assert.assertNotNull(viewManager); - } - - - @Test - public void getCallHistoryList() { - - - GetCallHistoryRequest request = new GetCallHistoryRequest.Builder() - .setType(CallType.Constants.VIDEO_CALL) - .count(50) - .build(); - - ChatListener listener = Mockito.mock(ChatListener.class); - - chat.addListener(listener); - - String uniqueId = chat.getCallsHistory(request); - - Mockito.verify(listener, Mockito.after(5000).atLeast(2)).onReceiveCallHistory(Mockito.any()); - - } - - @Test - public void testAddView() { - - int viewListSize = chat.getVideoCallPartnerViews().size(); - - chat.addPartnerView(new CallPartnerView(callActivty)); - chat.addPartnerView(new CallPartnerView(callActivty)); - chat.addPartnerView(new CallPartnerView(callActivty)); - - viewListSize += 3; - - Assert.assertEquals(viewListSize, chat.getVideoCallPartnerViews().size()); - - } - - @Test - public void testUsingCallPartnerViewManager() { - - - chat.addPartnerView(new CallPartnerView(callActivty)); - chat.addPartnerView(new CallPartnerView(callActivty)); - chat.addPartnerView(new CallPartnerView(callActivty)); - - - chat.useCallPartnerViewManager(); - - Assert.assertEquals(0, chat.getVideoCallPartnerViews().size()); - - } - - - @Test - public void assignViewInChat() { - - chat.addPartnerView(new CallPartnerView(callActivty)); - chat.addPartnerView(new CallPartnerView(callActivty)); - chat.addPartnerView(new CallPartnerView(callActivty)); - - chat.useCallPartnerViewManager(); - - CallPartnerView assigned = chat.assignCallPartnerViewT(14); - - Assert.assertEquals((long) assigned.getPartnerId(), 14L); - } - - - @Test - public void generateViewTest() { - - CallPartnerViewManager manager = chat.useCallPartnerViewManager(); - - CallPartnerView partnerView = chat.assignCallPartnerViewT(1); - - assert partnerView != null; - - presenter.prepareNewView(partnerView); - - partnerView.setVisibility(View.VISIBLE); - - Mockito.verify(view, Mockito.after(5000)).addNewView( - Mockito.argThat(pView -> pView.getSurfaceView() != null) - ); - } - - - private void resumeProcess() { - synchronized (sync) { - sync.notify(); - } - } - - private void pauseProcess() { - synchronized (sync) { - try { - sync.wait(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } -} diff --git a/app/src/androidTest/java/com/example/podchat/TextMessagesQueueTest.java b/app/src/androidTest/java/com/example/podchat/TextMessagesQueueTest.java new file mode 100644 index 00000000..1353aaba --- /dev/null +++ b/app/src/androidTest/java/com/example/podchat/TextMessagesQueueTest.java @@ -0,0 +1,630 @@ +package com.example.podchat; + +import static com.example.chat.application.chatexample.ChatActivity.APP_ID; +import static com.fanap.podchat.util.ChatStateType.ChatSateConstant.CHAT_READY; + +import android.app.Activity; +import android.content.Context; +import android.os.Looper; +import android.support.test.InstrumentationRegistry; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; + +import com.example.chat.application.chatexample.BaseApplication; +import com.example.chat.application.chatexample.ChatActivity; +import com.example.chat.application.chatexample.ChatContract; +import com.example.chat.application.chatexample.ChatPresenter; +import com.fanap.podchat.cachemodel.queue.SendingQueueCache; +import com.fanap.podchat.cachemodel.queue.WaitQueueCache; +import com.fanap.podchat.chat.Chat; +import com.fanap.podchat.chat.ChatListener; +import com.fanap.podchat.example.R; +import com.fanap.podchat.mainmodel.MessageVO; +import com.fanap.podchat.mainmodel.Thread; +import com.fanap.podchat.model.ChatResponse; +import com.fanap.podchat.model.ErrorOutPut; +import com.fanap.podchat.model.ResultHistory; +import com.fanap.podchat.model.ResultMessage; +import com.fanap.podchat.model.ResultNewMessage; +import com.fanap.podchat.model.ResultThreads; +import com.fanap.podchat.requestobject.RequestConnect; +import com.fanap.podchat.requestobject.RequestGetHistory; +import com.fanap.podchat.requestobject.RequestMessage; +import com.fanap.podchat.requestobject.RequestThread; +import com.fanap.podchat.util.TextMessageType; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +@RunWith(AndroidJUnit4.class) +public class TextMessagesQueueTest { + + public static final boolean CACHE = true; + private static ChatContract.presenter presenter; + @Mock + private static ChatContract.view view; + + + @Mock + private Activity activity; + private static Context appContext; + + private static String serverName = "chat-server"; + private static String appId = "POD-Chat"; + private static String ssoHost = BaseApplication.getInstance().getString(R.string.ssoHost); + private static String NAME = BaseApplication.getInstance().getString(R.string.sandbox_server_name); + private static String socketAddress = BaseApplication.getInstance().getString(R.string.sandbox_socketAddress); + private static String platformHost = BaseApplication.getInstance().getString(R.string.sandbox_platformHost); + private static String fileServer = BaseApplication.getInstance().getString(R.string.sandbox_fileServer); + private static String TOKEN = "cf06e0e5cc3f41fba837f4d05b9a4138"; + + + @Mock + ChatListener chatListeners; + + private ChatActivity chatActivity; + + + static Chat chat; + + static final Object sync = new Object(); + + @Rule + public ActivityTestRule chatActivityRule = new ActivityTestRule<>(ChatActivity.class); + + final ArrayList threads = new ArrayList<>(); + final ArrayList threadMessagesList = new ArrayList<>(); + + @BeforeClass + public static void initial() { + + + appContext = InstrumentationRegistry.getTargetContext(); + + chat = Chat.init(appContext); + Looper.prepare(); + } + + @Before + public void createChat() { + + + view = Mockito.mock(ChatContract.view.class); + + chatActivity = chatActivityRule.getActivity(); + presenter = new ChatPresenter(appContext, view, chatActivity); + + RequestConnect rc = new RequestConnect.Builder( + socketAddress, + APP_ID, + serverName, + TOKEN, + ssoHost, + platformHost, + fileServer, + "podSpaceServer") + .build(); + + + chatListeners = new ChatListener() { + @Override + public void onChatState(String state) { + if (state.equals(CHAT_READY)) { + resumeProcess(); + } + } + }; + + chat.addListener(chatListeners); + + chat.connect(rc); + + chat.isCacheables(CACHE); + + pauseProcess(); + + + } + + + //requests for list of threads + public void populateThreadsListFromServerOrCache() { + + + chatListeners = new ChatListener() { + @Override + public void onGetThread(String content, ChatResponse thread) { + + System.out.println("Received List: " + content); + threads.addAll(thread.getResult().getThreads()); + chat.removeListener(chatListeners); + + } + }; + + chat.addListener(chatListeners); + + RequestThread requestThread = + new RequestThread.Builder() + .count(25) + .build(); + + presenter.getThreads(requestThread, null); + + long t1 = System.currentTimeMillis(); + Mockito.verify(view, Mockito.after(10000).atLeastOnce()).onGetThreadList(Mockito.any(), Mockito.any()); + long t2 = System.currentTimeMillis(); + System.out.println("Received List: " + threads.size() + " after: " + (t2 - t1) + " ms"); + + } + + //requests for list of threads from server + + public void populateThreadsListFromServerOnly() { + + + chatListeners = new ChatListener() { + @Override + public void onGetThread(String content, ChatResponse response) { + + if (!response.isCache()) { + System.out.println("Received List: " + content); + threads.addAll(response.getResult().getThreads() + .stream() + .filter(thread -> thread.getTitle() != null + && thread.getId() > 0 + && !thread.isClosed() + && thread.getLastMessageVO() != null) + .collect(Collectors.toList())); + + chat.removeListener(chatListeners); + resumeProcess(); + } + + } + }; + + chat.setListener(chatListeners); + + RequestThread requestThread = + new RequestThread.Builder() + .count(25) + .withNoCache() + .build(); + + presenter.getThreads(requestThread, null); + + pauseProcess(); + System.out.println("Received List: " + threads.size()); + + } + + //requests for list of threads from cache + + public void populateThreadsListFromCacheOnly() { + + + chatListeners = new ChatListener() { + @Override + public void onGetThread(String content, ChatResponse thread) { + + if (thread.isCache()) { + System.out.println("Received List: " + content); + threads.addAll(thread.getResult().getThreads()); + chat.removeListener(chatListeners); + resumeProcess(); + } + + } + }; + + chat.addListener(chatListeners); + + RequestThread requestThread = + new RequestThread.Builder() + .count(25) + .build(); + + presenter.getThreads(requestThread, null); + + pauseProcess(); + System.out.println("Received List: " + threads.size()); + + } + + + public void populateMessagesFromServer() { + populateThreadsListFromServerOnly(); + assert threads.size() > 0; + + Thread thread = threads.get(0); + + chatListeners = new ChatListener() { + @Override + public void onGetHistory(String content, ChatResponse history) { + + if (!history.isCache()) { + System.out.println("Received Message List Server: " + content); + + threadMessagesList.addAll(history.getResult().getHistory() + .stream() + .filter(messageVO -> + messageVO.getMessage() != null) + .collect(Collectors.toList())); + + chat.removeListener(chatListeners); + resumeProcess(); + } + } + }; + + chat.addListener(chatListeners); + + RequestGetHistory requestGetHistory + = new RequestGetHistory.Builder(thread.getId()) + .withNoCache() + .build(); + + chat.getHistory(requestGetHistory, null); + pauseProcess(); + } + + + public void populateMessagesFromCache() { + populateThreadsListFromServerOnly(); + assert threads.size() > 0; + + Thread thread = threads.get(0); + + chatListeners = new ChatListener() { + @Override + public void onGetHistory(String content, ChatResponse history) { + + if (history.isCache()) { + System.out.println("Received Message List Cache: " + content); + threadMessagesList.addAll(history.getResult().getHistory()); + chat.removeListener(chatListeners); + resumeProcess(); + } + } + }; + + chat.addListener(chatListeners); + + RequestGetHistory requestGetHistory + = new RequestGetHistory.Builder(thread.getId()) + .build(); + + chat.getHistory(requestGetHistory, null); + pauseProcess(); + } + + + public void populateMessagesFromServerOrCache() { + populateThreadsListFromServerOnly(); + assert threads.size() > 0; + + Thread thread = threads.get(0); + + chatListeners = new ChatListener() { + @Override + public void onGetHistory(String content, ChatResponse history) { + + System.out.println("Received Message List, Cache: " + history.isCache() + " Content: " + content); + threadMessagesList.addAll(history.getResult().getHistory()); + chat.removeListener(chatListeners); + resumeProcess(); + + } + }; + + chat.addListener(chatListeners); + + RequestGetHistory requestGetHistory + = new RequestGetHistory.Builder(thread.getId()) + .build(); + + chat.getHistory(requestGetHistory, null); + pauseProcess(); + } + + @Test + public void sendMessageToThread() { + populateThreadsListFromServerOnly(); + + assert threads.size() > 0; + + Thread thread = threads.get(0); + + ChatListener mTestListener = Mockito.mock(ChatListener.class); + + chat.setListener(mTestListener); + + RequestMessage request = + new RequestMessage.Builder("Android Test " + new Date(), thread.getId()) + .messageType(TextMessageType.Constants.TEXT) + .build(); + + chat.sendTextMessage(request, null); + + + Mockito.verify(mTestListener, Mockito.after(2000).atLeastOnce()) + .onNewMessage(Mockito.any(), Mockito.any()); + + sleep(2000); + + + } + + @Test + public void closeChatTest() { + + chat.closeChat(); + + sleep(2000); + + Assert.assertNotEquals(chat.getChatState(), CHAT_READY); + + } + + + @Test + public void sendMessageWhenChatIsNotReady() { + + populateThreadsListFromServerOnly(); + + assert threads.size() > 0; + + Thread thread = threads.get(0); + + ChatListener mTestListener = Mockito.mock(ChatListener.class); + + chat.setListener(mTestListener); + + + chat.closeChat(); + + sleep(2000); + + Assert.assertNotEquals(chat.getChatState(), CHAT_READY); + + + RequestMessage request = + new RequestMessage.Builder("Android Test " + new Date(), thread.getId()) + .messageType(TextMessageType.Constants.TEXT) + .build(); + + String uniqueId = chat.sendTextMessage(request, null); + + + Mockito.verify(mTestListener, Mockito.after(2000).never()) + .onNewMessage(Mockito.any(), Mockito.any()); + + } + + @Test + public void sendMessageFromSendingQueue() { + + populateThreadsListFromServerOnly(); + + assert threads.size() > 0; + + Thread thread = threads.get(0); + + ChatListener mTestListener = Mockito.mock(ChatListener.class); + + chat.setListener(mTestListener); + + + chat.closeChat(); + + sleep(2000); + + Assert.assertNotEquals(chat.getChatState(), CHAT_READY); + + + RequestMessage request = + new RequestMessage.Builder("Android Test " + new Date(), thread.getId()) + .messageType(TextMessageType.Constants.TEXT) + .build(); + + String uniqueId = chat.sendTextMessage(request, null); + + + chat.resumeChat(); + + Mockito.verify(mTestListener, Mockito.after(5000).atLeastOnce()) + .onNewMessage(Mockito.any(), Mockito.any()); + + } + + @Test + public void checkSendingQueue() { + + populateThreadsListFromServerOnly(); + + assert threads.size() > 0; + + Thread thread = threads.get(0); + + ChatListener mTestListener = Mockito.mock(ChatListener.class); + + chat.setListener(mTestListener); + + + chat.closeChat(); + + sleep(2000); + + Assert.assertNotEquals(chat.getChatState(), CHAT_READY); + + + RequestMessage request = + new RequestMessage.Builder("Android Test " + new Date(), thread.getId()) + .messageType(TextMessageType.Constants.TEXT) + .build(); + + String uniqueId = chat.sendTextMessage(request, null); + + List sendQ = chat.getSendingQ(); + + Assert.assertTrue(sendQ.stream().anyMatch(sendingQueueCache -> sendingQueueCache.getUniqueId().equals(uniqueId))); + + } + + @Test + public void banUserScenario() { + populateThreadsListFromServerOnly(); + + assert threads.size() > 0; + + Thread thread = threads.get(0); + + final boolean[] isBanned = {false}; + ChatListener mTestListener = new ChatListener() { + @Override + public void onError(String content, ErrorOutPut error) { + + if (error.getErrorCode() == 208) { + isBanned[0] = true; + } + } + }; + + chat.setListener(mTestListener); + + int counter = 0; + + while (!isBanned[0]) { + counter++; + + RequestMessage request = + new RequestMessage.Builder("Ban me i'm the " + counter + "th message", thread.getId()) + .messageType(TextMessageType.Constants.TEXT) + .build(); + + chat.sendTextMessage(request, null); + } + + RequestMessage request = + new RequestMessage.Builder("Ok! i'm ban now. but i'll be send after 60 000 milli second is passed", thread.getId()) + .messageType(TextMessageType.Constants.TEXT) + .build(); + + chat.sendTextMessage(request, null); + + Assert.assertTrue(chat.getWaitingQ().size() > 0); + + + } + + @Test + public void checkWaitingQList() { +// populateThreadsListFromServerOnly(); +// +// assert threads.size() > 0; +// +// Thread thread = threads.get(0); +// +// ChatListener mTestListener = Mockito.mock(ChatListener.class); +// +// chat.setListener(mTestListener); +// +// RequestMessage request = +// new RequestMessage.Builder("Android Test " + new Date(), thread.getId()) +// .messageType(TextMessageType.Constants.TEXT) +// .build(); +// +// chat.sendTextMessage(request, null); + + Assert.assertTrue(chat.getWaitingQ().size() > 0); + System.out.println(chat.getWaitingQ().size() + " message are waiting..."); + } + + + @Test + public void movingMessageFromWaitingQToSendingQ() { + + ChatListener mTestListener = Mockito.mock(ChatListener.class); + + chat.setListener(mTestListener); + + List waitList = chat.getWaitingQ(); + + WaitQueueCache wToSend = waitList.remove(0); + + chat.resendMessage(wToSend.getUniqueId()); + sleep(1000); + Assert.assertTrue(chat.getWaitingQ().stream().noneMatch(waitQueueCache -> waitQueueCache.getUniqueId().equals(wToSend.getUniqueId()))); + + + } + + @Test + public void resendMessageFromWaitingQ() { + + ChatListener mTestListener = Mockito.mock(ChatListener.class); + + chat.setListener(mTestListener); + + List waitList = chat.getWaitingQ(); + + WaitQueueCache wToSend = waitList.remove(0); + + chat.resendMessage(wToSend.getUniqueId()); + + Mockito.verify(mTestListener, Mockito.after(2000).atLeastOnce()).onNewMessage(Mockito.any(), + Mockito.argThat((ChatResponse result) -> + result.getResult().getMessageVO().getUniqueId().equals(wToSend.getUniqueId()))); + + + } + + @Test + public void cancelMessage() { + List waiting = chat.getWaitingQ(); + System.out.println(">>> Message waiting: " + waiting.size()); + WaitQueueCache msgWaiting = waiting.get(0); + chat.cancelMessage(msgWaiting.getUniqueId()); + sleep(1000); + Assert.assertTrue(chat.getWaitingQ().stream().noneMatch(message -> message.getUniqueId().equals(msgWaiting.getUniqueId()))); + System.out.println(">>> Message waiting: " + chat.getWaitingQ().size()); + } + + + private void resumeProcess() { + synchronized (sync) { + sync.notify(); + } + } + + private void pauseProcess() { + synchronized (sync) { + try { + sync.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + private void sleep(int i) { + try { + java.lang.Thread.sleep(i); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/app/src/androidTest/java/com/example/podchat/ThreadCacheTest.java b/app/src/androidTest/java/com/example/podchat/ThreadCacheTest.java index 7c9e298d..332ef888 100644 --- a/app/src/androidTest/java/com/example/podchat/ThreadCacheTest.java +++ b/app/src/androidTest/java/com/example/podchat/ThreadCacheTest.java @@ -19,12 +19,21 @@ import com.fanap.podchat.chat.mention.model.RequestGetMentionList; import com.fanap.podchat.example.R; import com.fanap.podchat.mainmodel.MessageVO; +import com.fanap.podchat.mainmodel.ResultDeleteMessage; import com.fanap.podchat.mainmodel.Thread; import com.fanap.podchat.model.ChatResponse; +import com.fanap.podchat.model.ErrorOutPut; import com.fanap.podchat.model.ResultHistory; +import com.fanap.podchat.model.ResultNewMessage; +import com.fanap.podchat.model.ResultThread; import com.fanap.podchat.model.ResultThreads; import com.fanap.podchat.requestobject.RequestConnect; +import com.fanap.podchat.requestobject.RequestDeleteMessage; +import com.fanap.podchat.requestobject.RequestEditMessage; +import com.fanap.podchat.requestobject.RequestMessage; import com.fanap.podchat.requestobject.RequestThread; +import com.fanap.podchat.requestobject.RequestThreadInfo; +import com.fanap.podchat.util.TextMessageType; import org.junit.Assert; import org.junit.Before; @@ -34,8 +43,12 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; import java.util.stream.Collectors; @@ -58,7 +71,7 @@ public class ThreadCacheTest { private static String socketAddress = BaseApplication.getInstance().getString(R.string.sandbox_socketAddress); private static String platformHost = BaseApplication.getInstance().getString(R.string.sandbox_platformHost); private static String fileServer = BaseApplication.getInstance().getString(R.string.sandbox_fileServer); - private static String TOKEN = "e94904e70bd04c9f8c58a4c0f4d7ff40"; + private static String TOKEN = "f32ddf7e1bb0481fb5df2eaedcc62883"; @Mock ChatListener chatListeners; @@ -72,8 +85,8 @@ public class ThreadCacheTest { @Rule public ActivityTestRule chatActivityRule = new ActivityTestRule<>(ChatActivity.class); - - final ArrayList threads = new ArrayList<>(); + final ArrayList threadsInServer = new ArrayList<>(); + final ArrayList threadsInCache = new ArrayList<>(); @BeforeClass public static void initial() { @@ -127,69 +140,304 @@ public void onChatState(String state) { public void testThreadsAreSame() { populateThreadsFromServer(); populateThreadsFromCache(); - checkThreadsAreSameInCacheAndServer(); + checkThreadMessagesAreSameInCacheAndServer(); } @Test public void testThreadMessagesAreSame() { populateThreadsFromServer(); populateThreadsFromCache(); - checkThreadMessagesAreSameInCacheAndServer(); } @Test public void testThreadInfoAreSameAfterDeleteMessage() { + sendMessageAndDelete(); populateThreadsFromServer(); populateThreadsFromCache(); - deleteMessage(); - checkThreadInfoAreSameInCacheAndServer(); + checkThreadsAreSameInCacheAndServer(); } @Test public void testThreadInfoAreSameAfterSendNewMessage() { + sendMessage(); populateThreadsFromServer(); populateThreadsFromCache(); - sendNewMesage(); - checkThreadInfoAreSameInCacheAndServer(); + checkThreadsAreSameInCacheAndServer(); } @Test - public void testThreadInfoAreSameAfterUpdateThreadInfo() { + public void testThreadInfoAreSameAfterUpdateMessage() { + sendMessageAndEdit(); populateThreadsFromServer(); populateThreadsFromCache(); - updateThreadInfo(); - checkThreadInfoAreSameInCacheAndServer(); + checkThreadsAreSameInCacheAndServer(); } - public void updateThreadInfo() { - } + public void sendMessageAndDelete() { + populateThreadsFromServer(); + Collections.shuffle(threadsInServer); + Thread thread = threadsInServer.get(0); + Assert.assertNotNull(thread); + ArrayList msgIds = new ArrayList<>(); + + //send new message + chatListeners = new ChatListener() { + @Override + public void onNewMessage(String content, ChatResponse response) { + resumeProcess(); + msgIds.add(response.getResult().getMessageVO().getId()); + System.out.println("new message sent -> msg : " + content); + chat.removeListener(chatListeners); + } + + @Override + public void onError(String content, ErrorOutPut error) { + resumeProcess(); + System.out.println("Error: " + content); + Assert.assertEquals(0, 1); + chat.removeListener(chatListeners); + } + }; + chat.addListener(chatListeners); + + + RequestMessage request = + new RequestMessage.Builder("Message for test delete :" + thread.getId(), thread.getId()) + .messageType(TextMessageType.Constants.TEXT) + .build(); + + chat.sendTextMessage(request, null); + pauseProcess(); + + //delete last message + chatListeners = new ChatListener() { + @Override + public void onDeleteMessage(String content, ChatResponse response) { + resumeProcess(); + System.out.println("Deleted: " + content); + chat.removeListener(chatListeners); + } + + @Override + public void onError(String content, ErrorOutPut error) { + resumeProcess(); + System.out.println("Error: " + content); + Assert.assertEquals(0, 1); + chat.removeListener(chatListeners); + } + }; + chat.addListener(chatListeners); + + RequestDeleteMessage requestDeleteMessage = new RequestDeleteMessage + .Builder() + .messageIds(msgIds) + .deleteForAll(true) + .build(); + + presenter.deleteMessage(requestDeleteMessage, null); + pauseProcess(); - public void deleteMessage() { } - public void sendNewMesage() { + public void sendMessage() { + populateThreadsFromServer(); + Collections.shuffle(threadsInServer); + Thread thread = threadsInServer.get(0); + System.out.println("Thread : " + thread.getTitle()); + Assert.assertNotNull(thread); + chatListeners = new ChatListener() { + @Override + public void onNewMessage(String content, ChatResponse response) { + resumeProcess(); + chat.removeListener(chatListeners); + } + + @Override + public void onError(String content, ErrorOutPut error) { + resumeProcess(); + System.out.println("Error: " + content); + Assert.assertEquals(0, 1); + chat.removeListener(chatListeners); + } + }; + chat.addListener(chatListeners); + + + RequestMessage request = + new RequestMessage.Builder("Android Test " + new Date(), thread.getId()) + .messageType(TextMessageType.Constants.TEXT) + .build(); + + chat.sendTextMessage(request, null); + } - public void checkThreadInfoAreSameInCacheAndServer() { + + public void sendMessageAndEdit() { + populateThreadsFromServer(); + Collections.shuffle(threadsInServer); + Thread thread = threadsInServer.get(0); + Assert.assertNotNull(thread); + final long[] messageId = {0}; + + //send new message + chatListeners = new ChatListener() { + @Override + public void onNewMessage(String content, ChatResponse response) { + messageId[0] = response.getResult().getMessageVO().getId(); + resumeProcess(); + System.out.println("new message sent -> msg : " + content); + chat.removeListener(chatListeners); + } + + @Override + public void onError(String content, ErrorOutPut error) { + resumeProcess(); + System.out.println("Error: " + content); + Assert.assertEquals(0, 1); + chat.removeListener(chatListeners); + } + }; + chat.addListener(chatListeners); + + + RequestMessage request = + new RequestMessage.Builder("Message for test edit :" + thread.getId(), thread.getId()) + .messageType(TextMessageType.Constants.TEXT) + .build(); + + chat.sendTextMessage(request, null); + pauseProcess(); + + //delete last message + chatListeners = new ChatListener() { + @Override + public void onEditedMessage(String content, ChatResponse response) { + resumeProcess(); + System.out.println("Edited: " + content); + chat.removeListener(chatListeners); + } + + @Override + public void onError(String content, ErrorOutPut error) { + resumeProcess(); + System.out.println("Error: " + content); + Assert.assertEquals(0, 1); + chat.removeListener(chatListeners); + } + }; + chat.addListener(chatListeners); + + RequestEditMessage requestEditMessage = new RequestEditMessage.Builder("last message edited " + messageId[0], + messageId[0]) + .build(); + + chat.editMessage(requestEditMessage, null); + pauseProcess(); } public void populateThreadsFromServer() { + chatListeners = new ChatListener() { + @Override + public void onGetThread(String content, ChatResponse thread) { + assert thread.getResult().getThreads().size() > 0; + if (!thread.isCache()) { + threadsInServer.addAll(new ArrayList<>(thread.getResult().getThreads())); + chat.removeListener(chatListeners); + } + } + }; + + chat.addListener(chatListeners); + + RequestThread requestThread = + new RequestThread.Builder() + .count(25) + .build(); + + presenter.getThreads(requestThread, null); + + long t1 = System.currentTimeMillis(); + sleep(2500); + long t2 = System.currentTimeMillis(); + System.out.println("Received List: " + threadsInServer.size() + " after: " + (t2 - t1) + " ms"); } public void populateThreadsFromCache() { + chatListeners = new ChatListener() { + @Override + public void onGetThread(String content, ChatResponse thread) { + if (thread.isCache()) { + threadsInCache.addAll(thread.getResult().getThreads()); + chat.removeListener(chatListeners); + } else + Assert.assertEquals(0, 1); + resumeProcess(); + } + }; + + chat.addListener(chatListeners); + + RequestThread requestThread = + new RequestThread.Builder() + .count(25) + .build(); + presenter.getThreads(requestThread, null); + + long t1 = System.currentTimeMillis(); + pauseProcess(); + long t2 = System.currentTimeMillis(); + System.out.println("Received List: " + threadsInCache.size() + " after: " + (t2 - t1) + " ms"); } public void checkThreadsAreSameInCacheAndServer() { + for (Thread threadInServer : + threadsInServer) { + + if (threadInServer == null) continue; + + Thread threadInCache = threadsInCache.stream().filter(thread -> thread.getId() == threadInServer.getId()).findFirst().get(); + System.out.println(">>>>>>>>>>> Thread in server " + threadInServer.getTitle()); + System.out.println(">>>>>>>>>>> Thread in cache " + threadInCache.getTitle()); + + Assert.assertEquals(threadInServer.getId(), threadInCache.getId()); + System.out.println(">>>>>>>>>>> Threads are same " + threadInCache.getTitle() + " threadId : " + threadInCache.getId()); + Assert.assertNotNull(threadInServer.getLastMessageVO()); + Assert.assertNotNull(threadInCache.getLastMessageVO()); + System.out.println(">>>>>>>>>>> Last message in cache " + threadInCache.getLastMessageVO().getMessage()); + System.out.println(">>>>>>>>>>> Last message in server " + threadInServer.getLastMessageVO().getMessage()); + Assert.assertEquals(threadInCache.getLastMessage(), threadInCache.getLastMessageVO().getMessage()); + } } public void checkThreadMessagesAreSameInCacheAndServer() { + for (Thread threadInServer : + threadsInServer) { + + if (threadInServer == null) continue; + + Thread threadInCache = threadsInCache.stream().filter(thread -> thread.getId() == threadInServer.getId()).findFirst().get(); + System.out.println(">>>>>>>>>>> Thread in server " + threadInServer.getTitle()); + System.out.println(">>>>>>>>>>> Thread in cache " + threadInCache.getTitle()); + + Assert.assertEquals(threadInServer.getId(), threadInCache.getId()); + System.out.println(">>>>>>>>>>> Threads are same " + threadInCache.getTitle() + " threadId : " + threadInCache.getId()); + Assert.assertNotNull(threadInServer.getLastMessageVO()); + Assert.assertNotNull(threadInCache.getLastMessageVO()); + System.out.println(">>>>>>>>>>> Last message in cache " + threadInCache.getLastMessageVO().getMessage()); + System.out.println(">>>>>>>>>>> Last message in server " + threadInServer.getLastMessageVO().getMessage()); + Assert.assertEquals(threadInCache.getLastMessage(), threadInCache.getLastMessageVO().getMessage()); + + // GET THREAD HISTRORY + + } } private void resumeProcess() { diff --git a/app/src/main/java/com/example/chat/application/chatexample/ChatPresenter.java b/app/src/main/java/com/example/chat/application/chatexample/ChatPresenter.java index e31fb927..01a207fb 100644 --- a/app/src/main/java/com/example/chat/application/chatexample/ChatPresenter.java +++ b/app/src/main/java/com/example/chat/application/chatexample/ChatPresenter.java @@ -145,6 +145,7 @@ import com.fanap.podchat.util.NetworkUtils.NetworkPingSender; import com.fanap.podchat.util.RequestMapSearch; import com.fanap.podchat.util.Util; +import com.orhanobut.logger.Logger; import java.util.ArrayList; import java.util.List; @@ -582,6 +583,10 @@ public void onLogEvent(String log) { view.onLogEvent(log); } + @Override + public void onLogEvent(String logName, String json) { + view.onLogEvent(json); + } @Override public void searchMap(String searchTerm, double lat, double lon) { diff --git a/podchat/build.gradle b/podchat/build.gradle index 7d1c155c..428b1d1b 100644 --- a/podchat/build.gradle +++ b/podchat/build.gradle @@ -5,17 +5,17 @@ apply plugin: 'com.kezong.fat-aar' //apply plugin: 'com.google.gms.google-services' ext { - libraryVersion = '0.9.17.2' - libraryVersionCode = 193 - libraryVersionLight = '0.9.14.2' + libraryVersion = '0.9.18.0-BETA' + libraryVersionCode = 194 + libraryVersionLight = '0.9.15.0-BETA' podcallVersion = '3.8.21-SNAPSHOT' } android { - compileSdkVersion 29 + compileSdkVersion 30 defaultConfig { minSdkVersion 17 - targetSdkVersion 29 + targetSdkVersion 30 versionCode libraryVersionCode versionName libraryVersion @@ -123,8 +123,8 @@ dependencies { implementation 'com.google.firebase:firebase-analytics:16.0.0' implementation 'com.google.firebase:firebase-messaging:18.0.0' - implementation 'com.github.bumptech.glide:glide:4.7.1' - annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1' + implementation 'com.github.bumptech.glide:glide:4.8.0' + annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0' api 'com.fanap.async:podasync:0.2.13.8' diff --git a/podchat/src/main/java/com/fanap/podchat/chat/ChatCore.java b/podchat/src/main/java/com/fanap/podchat/chat/ChatCore.java index de539bff..99aeec1f 100644 --- a/podchat/src/main/java/com/fanap/podchat/chat/ChatCore.java +++ b/podchat/src/main/java/com/fanap/podchat/chat/ChatCore.java @@ -18,16 +18,17 @@ import android.provider.MediaStore; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.RestrictTo; import android.support.v4.content.CursorLoader; import android.text.TextUtils; import android.util.Log; -import android.view.View; import android.webkit.MimeTypeMap; import com.fanap.podasync.Async; import com.fanap.podasync.AsyncAdapter; import com.fanap.podasync.model.Device; import com.fanap.podasync.model.DeviceResult; +import com.fanap.podchat.BuildConfig; import com.fanap.podchat.ProgressHandler; import com.fanap.podchat.R; import com.fanap.podchat.cachemodel.CacheMessageVO; @@ -276,7 +277,6 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashMap; @@ -295,6 +295,7 @@ import io.sentry.core.Sentry; import io.sentry.core.SentryEvent; import io.sentry.core.SentryLevel; +import io.sentry.core.protocol.SentryException; import io.sentry.core.protocol.User; import okhttp3.MediaType; import okhttp3.MultipartBody; @@ -304,7 +305,6 @@ import retrofit2.Response; import rx.Observable; import rx.Subscription; -import rx.android.BuildConfig; import rx.android.schedulers.AndroidSchedulers; import rx.schedulers.Schedulers; import rx.subjects.PublishSubject; @@ -508,10 +508,6 @@ public synchronized static Chat init(Context context) { return instance; } - private static String sentryCachDir = ""; - private static final StringBuilder sentrylogs = new StringBuilder(); - private static final StringBuilder sentryCashedlogs = new StringBuilder(); - private static void setupSentry(Context context) { SentryAndroid.init(context.getApplicationContext(), options -> { @@ -520,8 +516,6 @@ private static void setupSentry(Context context) { options.setSentryClientName("PodChat-Android"); options.addInAppInclude("com.fanap.podchat"); options.setEnvironment("PODCHAT"); -// options.setEnableNdk(false); - sentryCachDir = options.getCacheDirPath(); options.setBeforeSend((event, hint) -> { options.setDsn(context.getApplicationContext().getString(R.string.sentry_dsn)); @@ -1606,7 +1600,7 @@ private void handleOnRegisterAssistant(ChatMessage chatMessage) { showLog("ON REGISTER ASSISTANT"); } - ChatResponse> response = AssistantManager.handleAssitantResponse(chatMessage); + ChatResponse> response = AssistantManager.handleAssistantResponse(chatMessage); if (cache && !response.getResult().isEmpty()) { messageDatabaseHelper.insertAssistantVo(response.getResult()); } @@ -1622,7 +1616,7 @@ private void handleOnDeActiveAssistant(ChatMessage chatMessage) { showLog("ON DEACTIVE ASSISTANT"); } - ChatResponse> response = AssistantManager.handleAssitantResponse(chatMessage); + ChatResponse> response = AssistantManager.handleAssistantResponse(chatMessage); if (cache && !response.getResult().isEmpty()) { messageDatabaseHelper.deleteCacheAssistantVos(response.getResult()); @@ -1641,16 +1635,10 @@ private void handleOnGetAssistants(ChatMessage chatMessage) { showLog("ON GET ASSISTANTS"); } - ChatResponse> response = AssistantManager.handleAssitantResponse(chatMessage); + ChatResponse> response = AssistantManager.handleAssistantResponse(chatMessage); if (cache && !response.getResult().isEmpty()) { - messageDatabaseHelper.updateCashAssistant(new OnWorkDone() { - @Override - public void onWorkDone(@Nullable Object o) { - - } - }, response.getResult()); - + messageDatabaseHelper.insertAssistantVo(response.getResult()); } listenerManager.callOnGetAssistants(response); @@ -1665,16 +1653,11 @@ private void handleOnGetAssistantHistory(ChatMessage chatMessage) { showLog("ON GET ASSISTANT HISTORY"); } - ChatResponse> response = AssistantManager.handleAssitantHistoryResponse(chatMessage); + ChatResponse> response = AssistantManager.handleAssistantHistoryResponse(chatMessage); if (cache && !response.getResult().isEmpty()) { - messageDatabaseHelper.updateCashAssistantHistory(new OnWorkDone() { - @Override - public void onWorkDone(@Nullable Object o) { - - } - }, response.getResult()); + messageDatabaseHelper.updateCashAssistantHistory(o -> {}, response.getResult()); } @@ -1718,10 +1701,9 @@ private void handleOnAssistantBlocked(ChatMessage chatMessage) { showLog("ON BLOCK ASSISTANT"); } - ChatResponse> response = AssistantManager.handleAssitantResponse(chatMessage); + ChatResponse> response = AssistantManager.handleAssistantResponse(chatMessage); if (cache && !response.getResult().isEmpty()) { messageDatabaseHelper.insertAssistantVo(response.getResult()); - Log.e(TAG, "handleOnAssistantBlocked: "); } listenerManager.callOnAssistantBlocked(response); @@ -1735,10 +1717,9 @@ private void handleOnAssistantUnBlocked(ChatMessage chatMessage) { showLog("ON UNBLOCK ASSISTANT"); } - ChatResponse> response = AssistantManager.handleAssitantResponse(chatMessage); + ChatResponse> response = AssistantManager.handleAssistantResponse(chatMessage); if (cache && !response.getResult().isEmpty()) { messageDatabaseHelper.insertAssistantVo(response.getResult()); - Log.e(TAG, "handleOnAssistantUnBlocked: "); } listenerManager.callOnAssistantUnBlocked(response); @@ -1753,10 +1734,9 @@ private void handleOnAssistantsBlocks(ChatMessage chatMessage) { showLog("ON GET BLOCKED ASSISTANTS"); } - ChatResponse> response = AssistantManager.handleAssitantResponse(chatMessage); + ChatResponse> response = AssistantManager.handleAssistantResponse(chatMessage); if (cache && !response.getResult().isEmpty()) { messageDatabaseHelper.insertAssistantVo(response.getResult()); - Log.e(TAG, "handleOnAssistantsBlocks: "); } listenerManager.callOnAssistantBlocks(response); } @@ -1966,7 +1946,6 @@ void handleOnCallStarted(Callback callback, ChatMessage chatMessage) { } - void handleOnVoiceCallEnded(ChatMessage chatMessage) { } @@ -2460,7 +2439,7 @@ public String getAssistantHistory(GetAssistantHistoryRequest request) { public String getAssistants(GetAssistantRequest request) { String uniqueId = generateUniqueId(); - if (cache) { + if (cache && request.useCacheData()) { try { getAssistantFromCache(request, uniqueId); } catch (RoomIntegrityException e) { @@ -2517,11 +2496,19 @@ public String unBlockAssistant(BlockUnblockAssistantRequest request) { } /** - * @param request You can get list of bloked assistants + * @param request You can get list of blocked assistants */ public String getBlocksAssistant(GetBlockedAssistantsRequest request) { String uniqueId = generateUniqueId(); + if (cache && request.useCacheData()) { + try { + getBlockedAssistantFromCache(request, uniqueId); + } catch (RoomIntegrityException e) { + disableCache(); + } + } + if (chatReady) { String message = AssistantManager.createGetBlockedAssistantsRequest(request, uniqueId); sendAsyncMessage(message, AsyncAckType.Constants.WITHOUT_ACK, "GET_BLOCKES_ASSISTANTS"); @@ -2532,12 +2519,29 @@ public String getBlocksAssistant(GetBlockedAssistantsRequest request) { return uniqueId; } + private void getBlockedAssistantFromCache(GetBlockedAssistantsRequest request, String uniqueId) throws RoomIntegrityException { + messageDatabaseHelper.getCacheBlockedAssistantVos(request, (count, cacheAssistantList) -> { + + ChatResponse> cacheResponse = new ChatResponse<>(); + cacheResponse.setResult((List) cacheAssistantList); + cacheResponse.setUniqueId(uniqueId); + cacheResponse.setCache(true); + + if (sentryResponseLog) { + showLog("ON_GET_BLOCKED_ASSISTANT_CACHE", cacheResponse.getJson()); + } else { + showLog("ON_GET_BLOCKED_ASSISTANT_CACHE"); + } + listenerManager.callOnAssistantBlocks(cacheResponse); + }); + } + private void getAssistantFromCache(GetAssistantRequest request, String uniqueId) throws RoomIntegrityException { - messageDatabaseHelper.getCacheAssistantVos(request, (count, cachResponseList) -> { + messageDatabaseHelper.getCacheAssistantVos(request, (count, cacheResponseList) -> { ChatResponse> cacheResponse = new ChatResponse<>(); - cacheResponse.setResult((List) cachResponseList); + cacheResponse.setResult((List) cacheResponseList); cacheResponse.setUniqueId(uniqueId); cacheResponse.setCache(true); listenerManager.callOnGetAssistants(cacheResponse); @@ -3178,6 +3182,22 @@ private void handleAddContacts(String uniqueId, List phoneContacts } } + @RestrictTo(RestrictTo.Scope.TESTS) + public List getWaitingQ() { + if (cache) { + return messageDatabaseHelper.getAllWaitQueueMsg(); + } + return new ArrayList<>(waitQList.values()); + } + + @RestrictTo(RestrictTo.Scope.TESTS) + public List getSendingQ() { + if (cache) { + return messageDatabaseHelper.getAllSendingQueue(); + } + return new ArrayList<>(sendingQList.values()); + } + // public String syncContactTest(Activity activity) { // @@ -11592,8 +11612,8 @@ private void handleForwardMessage(ChatMessage chatMessage) { async.sendMessage(asyncContent, AsyncAckType.Constants.WITHOUT_ACK); } - if(cache){ - dataSource.saveMessageResultFromServer(messageVO,chatMessage.getSubjectId()); + if (cache) { + dataSource.saveMessageResultFromServer(messageVO, chatMessage.getSubjectId()); } listenerManager.callOnNewMessage(json, chatResponse); diff --git a/podchat/src/main/java/com/fanap/podchat/chat/assistant/AssistantManager.java b/podchat/src/main/java/com/fanap/podchat/chat/assistant/AssistantManager.java index 037bbe93..5beb7c69 100644 --- a/podchat/src/main/java/com/fanap/podchat/chat/assistant/AssistantManager.java +++ b/podchat/src/main/java/com/fanap/podchat/chat/assistant/AssistantManager.java @@ -64,11 +64,11 @@ public static String createDeActiveAssistantRequest(DeActiveAssistantRequest req public static String createGetAssistantsRequest(GetAssistantRequest request, String uniqueId) { JsonObject content = new JsonObject(); - content.addProperty("contactType", request.getTypeCode()); - if ((Long)request.getOffset() != null) { + content.addProperty("contactType", request.getTypeCode() != null ? request.getTypeCode() : CoreConfig.typeCode); + if ((Long) request.getOffset() != null) { content.addProperty("offset", request.getOffset()); } - if ((Long)request.getCount() != null) { + if ((Long) request.getCount() != null) { content.addProperty("count", request.getCount()); } else { content.addProperty("count", 50); @@ -85,6 +85,7 @@ public static String createGetAssistantsRequest(GetAssistantRequest request, return App.getGson().toJson(message); } + public static String createUnBlockAssistantRequest(BlockUnblockAssistantRequest request, String uniqueId) { String content = App.getGson().toJson(request.getAssistantVos()); @@ -123,10 +124,10 @@ public static String createGetBlockedAssistantsRequest(GetBlockedAssistantsReque String uniqueId) { JsonObject content = new JsonObject(); content.addProperty("contactType", request.getTypeCode()); - if ((Long)request.getOffset() != null) { + if ((Long) request.getOffset() != null) { content.addProperty("offset", request.getOffset()); } - if ((Long)request.getCount() != null) { + if ((Long) request.getCount() != null) { content.addProperty("count", request.getCount()); } else { content.addProperty("count", 50); @@ -143,6 +144,7 @@ public static String createGetBlockedAssistantsRequest(GetBlockedAssistantsReque return App.getGson().toJson(message); } + public static String createGetAssistantHistoryRequest(GetAssistantHistoryRequest request, String uniqueId) { JsonObject content = new JsonObject(); @@ -159,7 +161,7 @@ public static String createGetAssistantHistoryRequest(GetAssistantHistoryRequest return App.getGson().toJson(message); } - public static ChatResponse> handleAssitantResponse(ChatMessage chatMessage) { + public static ChatResponse> handleAssistantResponse(ChatMessage chatMessage) { ChatResponse> response = new ChatResponse<>(); List result = App.getGson().fromJson(chatMessage.getContent(), new TypeToken>() { @@ -175,7 +177,7 @@ public static ChatResponse> handleAssitantResponse(ChatMessage } - public static ChatResponse> handleAssitantHistoryResponse(ChatMessage chatMessage) { + public static ChatResponse> handleAssistantHistoryResponse(ChatMessage chatMessage) { ChatResponse> response = new ChatResponse<>(); List result = App.getGson().fromJson(chatMessage.getContent(), new TypeToken>() { @@ -183,18 +185,21 @@ public static ChatResponse> handleAssitantHistoryRespon for (AssistantHistoryVo history : result) { switch (history.getActionType()) { - case AsisstantActionType.REGISTER_ASSISTANT: + case AssistantActionType.REGISTER_ASSISTANT: history.setActionName("REGISTER_ASSISTANT"); break; - case AsisstantActionType.ACTIVATE_ASSISTANT: + case AssistantActionType.ACTIVATE_ASSISTANT: history.setActionName("ACTIVATE_ASSISTANT"); break; - case AsisstantActionType.DIACTIVE_ASSISTANT: - history.setActionName("DIACTIVE_ASSISTANT"); + case AssistantActionType.DEACTIVE_ASSISTANT: + history.setActionName("DEACTIVE_ASSISTANT"); break; - case AsisstantActionType.BLOCK_ASSISTANT: + case AssistantActionType.BLOCK_ASSISTANT: history.setActionName("BLOCK_ASSISTANT"); break; + case AssistantActionType.UNBLOCK_ASSISTANT: + history.setActionName("UNBLOCK_ASSISTANT"); + break; } } response.setResult(result); @@ -207,10 +212,11 @@ public static ChatResponse> handleAssitantHistoryRespon } @Retention(RetentionPolicy.SOURCE) - public @interface AsisstantActionType { + public @interface AssistantActionType { int REGISTER_ASSISTANT = 1; int ACTIVATE_ASSISTANT = 2; - int DIACTIVE_ASSISTANT = 3; + int DEACTIVE_ASSISTANT = 3; int BLOCK_ASSISTANT = 4; + int UNBLOCK_ASSISTANT = 5; } } diff --git a/podchat/src/main/java/com/fanap/podchat/chat/assistant/model/AssistantHistoryVo.java b/podchat/src/main/java/com/fanap/podchat/chat/assistant/model/AssistantHistoryVo.java index ae95a1bc..7adaf04b 100644 --- a/podchat/src/main/java/com/fanap/podchat/chat/assistant/model/AssistantHistoryVo.java +++ b/podchat/src/main/java/com/fanap/podchat/chat/assistant/model/AssistantHistoryVo.java @@ -33,7 +33,7 @@ public long getActionTime() { return actionTime; } - public void setActionTime(int actionTime) { + public void setActionTime(long actionTime) { this.actionTime = actionTime; } diff --git a/podchat/src/main/java/com/fanap/podchat/chat/assistant/request_model/GetAssistantHistoryRequest.java b/podchat/src/main/java/com/fanap/podchat/chat/assistant/request_model/GetAssistantHistoryRequest.java index 5c1f7272..5f1e8d52 100644 --- a/podchat/src/main/java/com/fanap/podchat/chat/assistant/request_model/GetAssistantHistoryRequest.java +++ b/podchat/src/main/java/com/fanap/podchat/chat/assistant/request_model/GetAssistantHistoryRequest.java @@ -6,14 +6,26 @@ import java.util.List; public class GetAssistantHistoryRequest extends GeneralRequestObject { + private final long count; + private final long offset; GetAssistantHistoryRequest(GetAssistantHistoryRequest.Builder builder) { super(builder); + count = builder.count; + offset = builder.offset; + } + public long getCount() { + return count; } - public static class Builder extends GeneralRequestObject.Builder { + public long getOffset() { + return offset; + } + public static class Builder extends GeneralRequestObject.Builder { + private long count; + private long offset; public Builder() { @@ -23,6 +35,16 @@ public GetAssistantHistoryRequest build() { return new GetAssistantHistoryRequest(this); } + public Builder setCount(long count) { + this.count = count; + return this; + } + + public Builder setOffset(long offset) { + this.offset = offset; + return this; + } + @Override protected GetAssistantHistoryRequest.Builder self() { return this; diff --git a/podchat/src/main/java/com/fanap/podchat/persistance/MessageDatabaseHelper.java b/podchat/src/main/java/com/fanap/podchat/persistance/MessageDatabaseHelper.java index 8c38f9b1..42550998 100644 --- a/podchat/src/main/java/com/fanap/podchat/persistance/MessageDatabaseHelper.java +++ b/podchat/src/main/java/com/fanap/podchat/persistance/MessageDatabaseHelper.java @@ -43,6 +43,7 @@ import com.fanap.podchat.chat.assistant.model.AssistantVo; import com.fanap.podchat.chat.assistant.request_model.GetAssistantHistoryRequest; import com.fanap.podchat.chat.assistant.request_model.GetAssistantRequest; +import com.fanap.podchat.chat.assistant.request_model.GetBlockedAssistantsRequest; import com.fanap.podchat.chat.hashtag.model.RequestGetHashTagList; import com.fanap.podchat.chat.mention.model.RequestGetMentionList; import com.fanap.podchat.chat.messge.MessageManager; @@ -4604,11 +4605,21 @@ private void insertCacheAssistantVo(AssistantVo assistantVo) { if (assistantVo.getParticipantVO() != null) { Participant participant = assistantVo.getParticipantVO(); - String participantJson = App.getGson().toJson(participant); - CacheParticipant cacheParticipant = App.getGson().fromJson(participantJson, CacheParticipant.class); - messageDao.insertParticipant(cacheParticipant); + CacheParticipant pInCache = messageDao.getParticipant(participant.getId()); + CacheParticipant cacheParticipant; + if(pInCache!=null){ + cacheParticipant = new CacheParticipant(participant,pInCache.getThreadId()); + }else { + cacheParticipant = new CacheParticipant(participant,0); + } cacheFile.setParticipantVOId(cacheParticipant.getId()); cacheFile.setInviteeId(cacheParticipant.getId()); + messageDao.insertParticipant(cacheParticipant); + + if(participant.getChatProfileVO()!=null){ + participant.getChatProfileVO().setId(participant.getId()); + messageDao.insertChatProfile(participant.getChatProfileVO()); + } } cacheFile.setContactType(assistantVo.getContactType()); @@ -4638,8 +4649,7 @@ public void getCacheAssistantVos(GetAssistantRequest request, FunctionalListener if (!canUseDatabase()) throw new RoomIntegrityException(); worker(() -> { - - List list = messageDao.getCacheAssistantVos(); + List list = messageDao.getCacheAssistantVos(request.getCount()>0?request.getCount():25,request.getOffset()); List cachResponseList = new ArrayList<>(); for (CacheAssistantVo item : list) { AssistantVo assistantVo = new AssistantVo(); @@ -4647,6 +4657,8 @@ public void getCacheAssistantVos(GetAssistantRequest request, FunctionalListener assistantVo.setBlock(item.isBlock()); assistantVo.setContactType(item.getContactType()); Participant participant = cacheToParticipantMapper(messageDao.getParticipant(item.getParticipantVOId()), false, null); + ChatProfileVO profileVO = messageDao.getChatProfileVOById(participant.getId()); + participant.setChatProfileVO(profileVO); assistantVo.setParticipantVO(participant); cachResponseList.add(assistantVo); } @@ -4657,64 +4669,63 @@ public void getCacheAssistantVos(GetAssistantRequest request, FunctionalListener } - public void getCacheAssistantHistoryVos(GetAssistantHistoryRequest request, FunctionalListener callback) throws RoomIntegrityException { + public void getCacheBlockedAssistantVos(GetBlockedAssistantsRequest request, FunctionalListener callback) throws RoomIntegrityException { if (!canUseDatabase()) throw new RoomIntegrityException(); worker(() -> { - List list = messageDao.getCacheAssistantHistory(); - List cachResponseList = new ArrayList<>(); - for (CacheAssistantHistoryVo item : list) { - AssistantHistoryVo assistantHistoryVo = new AssistantHistoryVo(); - assistantHistoryVo.setActionName(item.getActionName()); - assistantHistoryVo.setActionTime((int) item.getActionTime()); - assistantHistoryVo.setActionType(item.getActionType()); + List list = messageDao.getCacheBlockedAssistantVos( + request.getCount()>0?request.getCount():25,request.getOffset()); + List cacheResponseList = new ArrayList<>(); + for (CacheAssistantVo item : list) { + AssistantVo assistantVo = new AssistantVo(); + assistantVo.setRoles((ArrayList) item.getRoles()); + assistantVo.setBlock(item.isBlock()); + assistantVo.setContactType(item.getContactType()); Participant participant = cacheToParticipantMapper(messageDao.getParticipant(item.getParticipantVOId()), false, null); - assistantHistoryVo.setParticipantVO(participant); - cachResponseList.add(assistantHistoryVo); + ChatProfileVO profileVO = messageDao.getChatProfileVOById(participant.getId()); + participant.setChatProfileVO(profileVO); + assistantVo.setParticipantVO(participant); + cacheResponseList.add(assistantVo); } - callback.onWorkDone(list.size(), cachResponseList); + callback.onWorkDone(list.size(), cacheResponseList); }); } - public void updateCashAssistant(OnWorkDone listener, List response) { - worker(() -> { - List cacheAssistantVos = new ArrayList<>(); - messageDao.deleteAllCacheAssistantVo(); - for (AssistantVo assistantVo : response) { - CacheAssistantVo cacheFile = new CacheAssistantVo(); - cacheFile.setRoles(assistantVo.getRoles()); - cacheFile.setBlock(assistantVo.getBlock()); - if (assistantVo.getParticipantVO() != null) { - Participant participant = assistantVo.getParticipantVO(); - String participantJson = App.getGson().toJson(participant); - CacheParticipant cacheParticipant = App.getGson().fromJson(participantJson, CacheParticipant.class); - messageDao.insertParticipant(cacheParticipant); - cacheFile.setParticipantVOId(assistantVo.getParticipantVO().getId()); - cacheFile.setInviteeId(assistantVo.getParticipantVO().getId()); - } + public void getCacheAssistantHistoryVos(GetAssistantHistoryRequest request, FunctionalListener callback) throws RoomIntegrityException { - cacheFile.setContactType(assistantVo.getContactType()); + if (!canUseDatabase()) throw new RoomIntegrityException(); + + worker(() -> { - cacheAssistantVos.add(cacheFile); + List list = messageDao.getCacheAssistantHistory( + request.getCount() > 0 ? request.getCount() : 25, + request.getOffset() + ); + List cacheResponseList = new ArrayList<>(); + for (CacheAssistantHistoryVo item : list) { + AssistantHistoryVo assistantHistoryVo = new AssistantHistoryVo(); + assistantHistoryVo.setActionName(item.getActionName()); + assistantHistoryVo.setActionTime(item.getActionTime()); + assistantHistoryVo.setActionType(item.getActionType()); + Participant participant = cacheToParticipantMapper(messageDao.getParticipant(item.getParticipantVOId()), false, null); + assistantHistoryVo.setParticipantVO(participant); + cacheResponseList.add(assistantHistoryVo); } - messageDao.insertCacheAssistantVos(cacheAssistantVos); - listener.onWorkDone(true); - }); + callback.onWorkDone(list.size(), cacheResponseList); + }); } - public void updateCashAssistantHistory(OnWorkDone listener, List response) { worker(() -> { List cashAssitantHistory = new ArrayList<>(); - messageDao.deleteAllCacheAssistantHistoryVo(); for (AssistantHistoryVo assistantVo : response) { CacheAssistantHistoryVo cashAsisstantHistory = new CacheAssistantHistoryVo(); if (assistantVo.getParticipantVO() != null) { diff --git a/podchat/src/main/java/com/fanap/podchat/persistance/dao/MessageDao.java b/podchat/src/main/java/com/fanap/podchat/persistance/dao/MessageDao.java index 2da9ff3d..faec5e21 100644 --- a/podchat/src/main/java/com/fanap/podchat/persistance/dao/MessageDao.java +++ b/podchat/src/main/java/com/fanap/podchat/persistance/dao/MessageDao.java @@ -548,6 +548,9 @@ public interface MessageDao { @Query("SELECT * FROM CacheAssistantVo") List getCacheAssistantVos(); + @Query("SELECT * FROM CacheAssistantVo LIMIT :count OFFSET :offset") + List getCacheAssistantVos(long count,long offset); + @Query("delete from CacheAssistantVo where inviteeId = :inviteeId") void deleteCacheAssistantVo(long inviteeId); @@ -558,10 +561,17 @@ public interface MessageDao { @Query("SELECT * FROM CacheAssistantHistoryVo") List getCacheAssistantHistory(); + @Query("SELECT * FROM CacheAssistantHistoryVo LIMIT :count OFFSET :offset") + List getCacheAssistantHistory(long count , long offset); + @Insert(onConflict = REPLACE) void insertCacheAssistantHistoryVo(List assistantVo); + @Query("SELECT * FROM CacheAssistantVo where block") + List getCacheBlockedAssistantVos(); + @Query("SELECT * FROM CacheAssistantVo where block LIMIT :count OFFSET :offset") + List getCacheBlockedAssistantVos(long count,long offset); @Query("DELETE FROM CacheAssistantHistoryVo") void deleteAllCacheAssistantHistoryVo();