diff --git a/p2p-sync/src/main/java/org/smartregister/p2p/activity/P2pModeSelectActivity.java b/p2p-sync/src/main/java/org/smartregister/p2p/activity/P2pModeSelectActivity.java index 63e70e7..23d926f 100644 --- a/p2p-sync/src/main/java/org/smartregister/p2p/activity/P2pModeSelectActivity.java +++ b/p2p-sync/src/main/java/org/smartregister/p2p/activity/P2pModeSelectActivity.java @@ -39,8 +39,8 @@ import org.smartregister.p2p.handler.OnActivityRequestPermissionHandler; import org.smartregister.p2p.handler.OnActivityResultHandler; import org.smartregister.p2p.handler.OnResumeHandler; -import org.smartregister.p2p.interactor.P2pModeSelectInteractor; -import org.smartregister.p2p.presenter.P2pModeSelectPresenter; +import org.smartregister.p2p.presenter.P2PReceiverPresenter; +import org.smartregister.p2p.presenter.P2PSenderPresenter; import org.smartregister.p2p.util.Constants; import org.smartregister.p2p.util.DialogUtils; import org.smartregister.p2p.util.Permissions; @@ -59,8 +59,8 @@ public class P2pModeSelectActivity extends AppCompatActivity implements P2pModeS private TextView messagesTv; private EditText messageToSendEt; - private P2pModeSelectContract.Presenter presenter; - private P2pModeSelectContract.Interactor interactor; + private P2pModeSelectContract.SenderPresenter senderBasePresenter; + private P2pModeSelectContract.ReceiverPresenter receiverBasePresenter; private ArrayList onActivityResultHandlers = new ArrayList<>(); private ArrayList onResumeHandlers = new ArrayList<>(); @@ -85,7 +85,11 @@ protected void onCreate(Bundle savedInstanceState) { public void onClick(View v) { if (messageToSendEt.getText() != null) { String messageToSend = messageToSendEt.getText().toString(); - interactor.sendMessage(messageToSend); + + // This is not ideal but for testing purposes for now + // It will not be in the any final release + receiverBasePresenter.sendTextMessage(messageToSend); + senderBasePresenter.sendTextMessage(messageToSend); displayMessage("YOU: " + messageToSend); messageToSendEt.setText(""); @@ -97,18 +101,18 @@ public void onClick(View v) { @Override protected void onStart() { super.onStart(); - initializePresenter(); + initializePresenters(); sendButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - presenter.onSendButtonClicked(); + senderBasePresenter.onSendButtonClicked(); } }); receiveButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - presenter.onReceiveButtonClicked(); + receiverBasePresenter.onReceiveButtonClicked(); } }); } @@ -408,9 +412,9 @@ public Context getContext() { } @Override - public void initializePresenter() { - interactor = new P2pModeSelectInteractor(this); - presenter = new P2pModeSelectPresenter(this, interactor); + public void initializePresenters() { + receiverBasePresenter = new P2PReceiverPresenter(this); + senderBasePresenter = new P2PSenderPresenter(this); } @Override @@ -434,7 +438,8 @@ protected void onStop() { sendButton.setOnClickListener(null); receiveButton.setOnClickListener(null); - presenter.onStop(); + receiverBasePresenter.onStop(); + senderBasePresenter.onStop(); } diff --git a/p2p-sync/src/main/java/org/smartregister/p2p/authenticator/BaseSyncConnectionAuthenticator.java b/p2p-sync/src/main/java/org/smartregister/p2p/authenticator/BaseSyncConnectionAuthenticator.java index badf3e1..e82697b 100644 --- a/p2p-sync/src/main/java/org/smartregister/p2p/authenticator/BaseSyncConnectionAuthenticator.java +++ b/p2p-sync/src/main/java/org/smartregister/p2p/authenticator/BaseSyncConnectionAuthenticator.java @@ -13,13 +13,13 @@ public abstract class BaseSyncConnectionAuthenticator { protected P2pModeSelectContract.View view; protected P2pModeSelectContract.Interactor interactor; - protected P2pModeSelectContract.Presenter presenter; + protected P2pModeSelectContract.BasePresenter basePresenter; public BaseSyncConnectionAuthenticator(@NonNull P2pModeSelectContract.View view - , @NonNull P2pModeSelectContract.Interactor interactor, @NonNull P2pModeSelectContract.Presenter presenter) { + , @NonNull P2pModeSelectContract.Interactor interactor, @NonNull P2pModeSelectContract.BasePresenter basePresenter) { this.view = view; this.interactor = interactor; - this.presenter = presenter; + this.basePresenter = basePresenter; } public P2pModeSelectContract.View getView() { @@ -30,8 +30,8 @@ public P2pModeSelectContract.Interactor getInteractor() { return interactor; } - public P2pModeSelectContract.Presenter getPresenter() { - return presenter; + public P2pModeSelectContract.BasePresenter getBasePresenter() { + return basePresenter; } public abstract void authenticate(@NonNull DiscoveredDevice discoveredDevice, @NonNull final AuthenticationCallback authenticationCallback); diff --git a/p2p-sync/src/main/java/org/smartregister/p2p/authenticator/ReceiverConnectionAuthenticator.java b/p2p-sync/src/main/java/org/smartregister/p2p/authenticator/ReceiverConnectionAuthenticator.java index 666f13c..ea65e2b 100644 --- a/p2p-sync/src/main/java/org/smartregister/p2p/authenticator/ReceiverConnectionAuthenticator.java +++ b/p2p-sync/src/main/java/org/smartregister/p2p/authenticator/ReceiverConnectionAuthenticator.java @@ -15,8 +15,8 @@ public class ReceiverConnectionAuthenticator extends BaseSyncConnectionAuthentic public ReceiverConnectionAuthenticator(@NonNull P2pModeSelectContract.View view , @NonNull P2pModeSelectContract.Interactor interactor - , @NonNull P2pModeSelectContract.Presenter presenter) { - super(view, interactor, presenter); + , @NonNull P2pModeSelectContract.BasePresenter basePresenter) { + super(view, interactor, basePresenter); } @Override diff --git a/p2p-sync/src/main/java/org/smartregister/p2p/authenticator/SenderConnectionAuthenticator.java b/p2p-sync/src/main/java/org/smartregister/p2p/authenticator/SenderConnectionAuthenticator.java index 4336f52..08822eb 100644 --- a/p2p-sync/src/main/java/org/smartregister/p2p/authenticator/SenderConnectionAuthenticator.java +++ b/p2p-sync/src/main/java/org/smartregister/p2p/authenticator/SenderConnectionAuthenticator.java @@ -20,8 +20,8 @@ public class SenderConnectionAuthenticator extends BaseSyncConnectionAuthenticat public SenderConnectionAuthenticator(@NonNull P2pModeSelectContract.View view , @NonNull P2pModeSelectContract.Interactor interactor - , @NonNull P2pModeSelectContract.Presenter presenter) { - super(view, interactor, presenter); + , @NonNull P2pModeSelectContract.BasePresenter basePresenter) { + super(view, interactor, basePresenter); } @Override diff --git a/p2p-sync/src/main/java/org/smartregister/p2p/contract/BaseView.java b/p2p-sync/src/main/java/org/smartregister/p2p/contract/BaseView.java index f271b30..d7e72e9 100644 --- a/p2p-sync/src/main/java/org/smartregister/p2p/contract/BaseView.java +++ b/p2p-sync/src/main/java/org/smartregister/p2p/contract/BaseView.java @@ -13,7 +13,7 @@ public interface BaseView extends ActivityResultHandler, ActivityResumeHandler, ActivityRequestPermissionResultHandler { - void initializePresenter(); + void initializePresenters(); void runOnUiThread(@NonNull Runnable runnable); diff --git a/p2p-sync/src/main/java/org/smartregister/p2p/contract/P2pModeSelectContract.java b/p2p-sync/src/main/java/org/smartregister/p2p/contract/P2pModeSelectContract.java index 221dcaf..6d306a2 100644 --- a/p2p-sync/src/main/java/org/smartregister/p2p/contract/P2pModeSelectContract.java +++ b/p2p-sync/src/main/java/org/smartregister/p2p/contract/P2pModeSelectContract.java @@ -65,9 +65,14 @@ interface OnLocationEnabled { } } - interface Presenter { + interface BasePresenter { - void onSendButtonClicked(); + void onStop(); + + void sendTextMessage(@NonNull String message); + } + + interface ReceiverPresenter extends BasePresenter { void onReceiveButtonClicked(); @@ -75,11 +80,15 @@ interface Presenter { void startAdvertisingMode(); + } + + interface SenderPresenter extends BasePresenter { + + void onSendButtonClicked(); + void prepareForDiscovering(boolean returningFromRequestingPermissions); void startDiscoveringMode(); - - void onStop(); } interface Interactor extends BaseInteractor { diff --git a/p2p-sync/src/main/java/org/smartregister/p2p/handler/AdvertisingResumeHandler.java b/p2p-sync/src/main/java/org/smartregister/p2p/handler/AdvertisingResumeHandler.java index a3816e6..6837301 100644 --- a/p2p-sync/src/main/java/org/smartregister/p2p/handler/AdvertisingResumeHandler.java +++ b/p2p-sync/src/main/java/org/smartregister/p2p/handler/AdvertisingResumeHandler.java @@ -1,7 +1,6 @@ package org.smartregister.p2p.handler; import android.support.annotation.NonNull; - import org.smartregister.p2p.contract.P2pModeSelectContract; /** @@ -10,12 +9,13 @@ public class AdvertisingResumeHandler implements OnResumeHandler { - private P2pModeSelectContract.Presenter presenter; + private P2pModeSelectContract.ReceiverPresenter receiverPresenter; private P2pModeSelectContract.Interactor interactor; - public AdvertisingResumeHandler(@NonNull P2pModeSelectContract.Presenter presenter, P2pModeSelectContract.Interactor interactor) { - this.presenter = presenter; + public AdvertisingResumeHandler(@NonNull P2pModeSelectContract.ReceiverPresenter receiverPresenter + , P2pModeSelectContract.Interactor interactor) { + this.receiverPresenter = receiverPresenter; this.interactor = interactor; } @@ -23,7 +23,7 @@ public AdvertisingResumeHandler(@NonNull P2pModeSelectContract.Presenter present @Override public void onResume() { if (interactor.isAdvertising()) { - presenter.prepareForAdvertising(false); + receiverPresenter.prepareForAdvertising(false); } } } diff --git a/p2p-sync/src/main/java/org/smartregister/p2p/presenter/BaseP2pModeSelectPresenter.java b/p2p-sync/src/main/java/org/smartregister/p2p/presenter/BaseP2pModeSelectPresenter.java new file mode 100644 index 0000000..c9a5ad7 --- /dev/null +++ b/p2p-sync/src/main/java/org/smartregister/p2p/presenter/BaseP2pModeSelectPresenter.java @@ -0,0 +1,48 @@ +package org.smartregister.p2p.presenter; + +import android.support.annotation.NonNull; + +import org.smartregister.p2p.contract.P2pModeSelectContract; +import org.smartregister.p2p.interactor.P2pModeSelectInteractor; + +/** + * Created by Ephraim Kigamba - ekigamba@ona.io on 08/03/2019 + */ + +public abstract class BaseP2pModeSelectPresenter implements P2pModeSelectContract.BasePresenter { + + protected P2pModeSelectContract.View view; + protected P2pModeSelectContract.Interactor interactor; + + public BaseP2pModeSelectPresenter(@NonNull P2pModeSelectContract.View view) { + this(view, new P2pModeSelectInteractor(view.getContext())); + } + + protected BaseP2pModeSelectPresenter(@NonNull P2pModeSelectContract.View view, @NonNull P2pModeSelectContract.Interactor p2pModeSelectInteractor) { + this.view = view; + this.interactor = p2pModeSelectInteractor; + + // This will be added when issue https://github.com/OpenSRP/android-p2p-sync/issues/24 + // is being worked on + //view.addOnResumeHandler(new AdvertisingResumeHandler(this, interactor)); + } + + @Override + public void sendTextMessage(@NonNull String message) { + interactor.sendMessage(message); + } + + @Override + public void onStop() { + view.dismissAllDialogs(); + view.enableSendReceiveButtons(true); + + interactor.stopAdvertising(); + interactor.stopDiscovering(); + interactor.closeAllEndpoints(); + + interactor.cleanupResources(); + interactor = null; + } + +} diff --git a/p2p-sync/src/main/java/org/smartregister/p2p/sync/ReceiverSyncLifecycleCallback.java b/p2p-sync/src/main/java/org/smartregister/p2p/presenter/P2PReceiverPresenter.java similarity index 65% rename from p2p-sync/src/main/java/org/smartregister/p2p/sync/ReceiverSyncLifecycleCallback.java rename to p2p-sync/src/main/java/org/smartregister/p2p/presenter/P2PReceiverPresenter.java index 04af3e2..9a54bf0 100644 --- a/p2p-sync/src/main/java/org/smartregister/p2p/sync/ReceiverSyncLifecycleCallback.java +++ b/p2p-sync/src/main/java/org/smartregister/p2p/presenter/P2PReceiverPresenter.java @@ -1,7 +1,9 @@ -package org.smartregister.p2p.sync; +package org.smartregister.p2p.presenter; +import android.content.DialogInterface; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; import android.widget.Toast; import com.google.android.gms.nearby.connection.ConnectionInfo; @@ -14,6 +16,12 @@ import org.smartregister.p2p.authenticator.BaseSyncConnectionAuthenticator; import org.smartregister.p2p.authenticator.ReceiverConnectionAuthenticator; import org.smartregister.p2p.contract.P2pModeSelectContract; +import org.smartregister.p2p.handler.OnActivityRequestPermissionHandler; +import org.smartregister.p2p.sync.DiscoveredDevice; +import org.smartregister.p2p.sync.IReceiverSyncLifecycleCallback; +import org.smartregister.p2p.util.Constants; + +import java.util.List; import timber.log.Timber; @@ -21,20 +29,75 @@ * Created by Ephraim Kigamba - ekigamba@ona.io on 18/03/2019 */ -public class ReceiverSyncLifecycleCallback implements IReceiverSyncLifecycleCallback { - - private P2pModeSelectContract.View view; - private P2pModeSelectContract.Presenter presenter; - private P2pModeSelectContract.Interactor interactor; +public class P2PReceiverPresenter extends BaseP2pModeSelectPresenter implements P2pModeSelectContract.ReceiverPresenter + , IReceiverSyncLifecycleCallback { @Nullable private DiscoveredDevice currentSender; - public ReceiverSyncLifecycleCallback(@NonNull P2pModeSelectContract.View view, @NonNull P2pModeSelectContract.Presenter presenter - , @NonNull P2pModeSelectContract.Interactor interactor) { - this.view = view; - this.presenter = presenter; - this.interactor = interactor; + public P2PReceiverPresenter(@NonNull P2pModeSelectContract.View view) { + super(view); + } + + @VisibleForTesting + public P2PReceiverPresenter(@NonNull P2pModeSelectContract.View view, @NonNull P2pModeSelectContract.Interactor p2pModeSelectInteractor) { + super(view, p2pModeSelectInteractor); + } + + @Override + public void onReceiveButtonClicked() { + prepareForAdvertising(false); + } + + @Override + public void prepareForAdvertising(boolean returningFromRequestingPermissions) { + List unauthorisedPermissions = view.getUnauthorisedPermissions(); + // Are all required permissions given + if (unauthorisedPermissions.size() == 0) { + // Check if location is enabled + if (view.isLocationEnabled()) { + startAdvertisingMode(); + } else { + view.requestEnableLocation(new P2pModeSelectContract.View.OnLocationEnabled() { + @Override + public void locationEnabled() { + startAdvertisingMode(); + } + }); + } + } else { + if (!returningFromRequestingPermissions) { + view.addOnActivityRequestPermissionHandler(new OnActivityRequestPermissionHandler() { + @Override + public int getRequestCode() { + return Constants.RQ_CODE.PERMISSIONS; + } + + @Override + public void handlePermissionResult(@NonNull String[] permissions, @NonNull int[] grantResults) { + view.removeOnActivityRequestPermissionHandler(this); + prepareForAdvertising(true); + } + }); + view.requestPermissions(unauthorisedPermissions); + } + } + } + + @Override + public void startAdvertisingMode() { + if (!interactor.isAdvertising()) { + view.enableSendReceiveButtons(false); + view.showReceiveProgressDialog(new P2pModeSelectContract.View.DialogCancelCallback() { + @Override + public void onCancelClicked(DialogInterface dialogInterface) { + interactor.stopAdvertising(); + dialogInterface.dismiss(); + view.enableSendReceiveButtons(true); + } + }); + interactor.startAdvertising(this); + } } @Override @@ -63,7 +126,7 @@ public void onConnectionInitiated(@NonNull String endpointId, @NonNull Connectio view.removeReceiveProgressDialog(); // This can be moved to the library for easy customisation by host applications - BaseSyncConnectionAuthenticator syncConnectionAuthenticator = new ReceiverConnectionAuthenticator(view, interactor, presenter); + BaseSyncConnectionAuthenticator syncConnectionAuthenticator = new ReceiverConnectionAuthenticator(view, interactor, this); syncConnectionAuthenticator.authenticate(currentSender, this); } else { Timber.e("Ignoring connection initiated by the other device %s, %s, %s" @@ -86,7 +149,7 @@ public void onConnectionAccepted(@NonNull String endpointId, @NonNull Connection public void onConnectionRejected(@NonNull String endpointId, @NonNull ConnectionResolution connectionResolution) { view.showToast(view.getContext().getString(R.string.receiver_rejected_the_connection), Toast.LENGTH_LONG); resetState(); - presenter.startAdvertisingMode(); + startAdvertisingMode(); } @Override @@ -95,7 +158,7 @@ public void onConnectionUnknownError(@NonNull String endpointId, @NonNull Connec //Todo: And show the user an error view.showToast(view.getContext().getString(R.string.an_error_occurred_before_acceptance_or_rejection), Toast.LENGTH_LONG); resetState(); - presenter.startAdvertisingMode(); + startAdvertisingMode(); } @Override @@ -104,7 +167,7 @@ public void onConnectionBroken(@NonNull String endpointId) { //Todo: Go back to advertising mode resetState(); view.showToast(String.format("The connection to %s has broken", endpointId), Toast.LENGTH_LONG); - presenter.startAdvertisingMode(); + startAdvertisingMode(); } @Override @@ -122,7 +185,7 @@ public void onPayloadReceived(@NonNull String endpointId, @NonNull Payload paylo public void onDisconnected(@NonNull String endpointId) { Timber.e("Endpoint lost %s", endpointId); resetState(); - presenter.startAdvertisingMode(); + startAdvertisingMode(); } @Override @@ -131,7 +194,7 @@ public void onAuthenticationSuccessful() { interactor.acceptConnection(currentSender.getEndpointId(), new PayloadCallback() { @Override public void onPayloadReceived(@NonNull String endpointId, @NonNull Payload payload) { - ReceiverSyncLifecycleCallback.this.onPayloadReceived(endpointId, payload); + P2PReceiverPresenter.this.onPayloadReceived(endpointId, payload); } @Override diff --git a/p2p-sync/src/main/java/org/smartregister/p2p/sync/SenderSyncLifecycleCallback.java b/p2p-sync/src/main/java/org/smartregister/p2p/presenter/P2PSenderPresenter.java similarity index 71% rename from p2p-sync/src/main/java/org/smartregister/p2p/sync/SenderSyncLifecycleCallback.java rename to p2p-sync/src/main/java/org/smartregister/p2p/presenter/P2PSenderPresenter.java index 9355cf6..9f18ebf 100644 --- a/p2p-sync/src/main/java/org/smartregister/p2p/sync/SenderSyncLifecycleCallback.java +++ b/p2p-sync/src/main/java/org/smartregister/p2p/presenter/P2PSenderPresenter.java @@ -1,7 +1,9 @@ -package org.smartregister.p2p.sync; +package org.smartregister.p2p.presenter; +import android.content.DialogInterface; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; import android.widget.Toast; import com.google.android.gms.nearby.connection.ConnectionInfo; @@ -16,6 +18,13 @@ import org.smartregister.p2p.contract.P2pModeSelectContract; import org.smartregister.p2p.authenticator.BaseSyncConnectionAuthenticator; import org.smartregister.p2p.authenticator.SenderConnectionAuthenticator; +import org.smartregister.p2p.handler.OnActivityRequestPermissionHandler; +import org.smartregister.p2p.presenter.BaseP2pModeSelectPresenter; +import org.smartregister.p2p.sync.DiscoveredDevice; +import org.smartregister.p2p.sync.ISenderSyncLifecycleCallback; +import org.smartregister.p2p.util.Constants; + +import java.util.List; import timber.log.Timber; @@ -23,20 +32,74 @@ * Created by Ephraim Kigamba - ekigamba@ona.io on 15/03/2019 */ -public class SenderSyncLifecycleCallback implements ISenderSyncLifecycleCallback { - - private P2pModeSelectContract.View view; - private P2pModeSelectContract.Presenter presenter; - private P2pModeSelectContract.Interactor interactor; +public class P2PSenderPresenter extends BaseP2pModeSelectPresenter implements ISenderSyncLifecycleCallback, P2pModeSelectContract.SenderPresenter { @Nullable private DiscoveredDevice currentReceiver; - public SenderSyncLifecycleCallback(@NonNull P2pModeSelectContract.View view, @NonNull P2pModeSelectContract.Presenter presenter - , @NonNull P2pModeSelectContract.Interactor interactor) { - this.view = view; - this.presenter = presenter; - this.interactor = interactor; + public P2PSenderPresenter(@NonNull P2pModeSelectContract.View view) { + super(view); + } + + @VisibleForTesting + public P2PSenderPresenter(@NonNull P2pModeSelectContract.View view, @NonNull P2pModeSelectContract.Interactor p2pModeSelectInteractor) { + super(view, p2pModeSelectInteractor); + } + + @Override + public void onSendButtonClicked() { + prepareForDiscovering(false); + } + + @Override + public void prepareForDiscovering(boolean returningFromRequestingPermissions) { + List unauthorisedPermissions = view.getUnauthorisedPermissions(); + // Are all required permissions given + if (unauthorisedPermissions.size() == 0) { + // Check if location is enabled + if (view.isLocationEnabled()) { + startDiscoveringMode(); + } else { + view.requestEnableLocation(new P2pModeSelectContract.View.OnLocationEnabled() { + @Override + public void locationEnabled() { + startDiscoveringMode(); + } + }); + } + } else { + if (!returningFromRequestingPermissions) { + view.addOnActivityRequestPermissionHandler(new OnActivityRequestPermissionHandler() { + @Override + public int getRequestCode() { + return Constants.RQ_CODE.PERMISSIONS; + } + + @Override + public void handlePermissionResult(@NonNull String[] permissions, @NonNull int[] grantResults) { + view.removeOnActivityRequestPermissionHandler(this); + prepareForDiscovering(true); + } + }); + view.requestPermissions(unauthorisedPermissions); + } + } + } + + @Override + public void startDiscoveringMode() { + if (!interactor.isDiscovering()) { + view.enableSendReceiveButtons(false); + view.showDiscoveringProgressDialog (new P2pModeSelectContract.View.DialogCancelCallback() { + @Override + public void onCancelClicked(DialogInterface dialogInterface) { + interactor.stopDiscovering(); + dialogInterface.dismiss(); + view.enableSendReceiveButtons(true); + } + }); + interactor.startDiscovering(this); + } } @Override @@ -89,7 +152,7 @@ public void onRequestConnectionFailed(@NonNull Exception exception) { // Show the user an error trying to connect device XYZ view.showToast("COULD NOT INITIATE CONNECTION REQUEST TO THE DEVICE", Toast.LENGTH_LONG); resetState(); - presenter.startDiscoveringMode(); + startDiscoveringMode(); } @Override @@ -100,7 +163,7 @@ public void onConnectionInitiated(@NonNull final String endpointId, @NonNull fin currentReceiver.setConnectionInfo(connectionInfo); // This can be moved to the library for easy customisation by host applications - BaseSyncConnectionAuthenticator syncConnectionAuthenticator = new SenderConnectionAuthenticator(view, interactor, presenter); + BaseSyncConnectionAuthenticator syncConnectionAuthenticator = new SenderConnectionAuthenticator(view, interactor, this); syncConnectionAuthenticator.authenticate(currentReceiver, this); } else { //("Connection was initiated by other device"); @@ -180,7 +243,7 @@ public void onConnectionAccepted(@NonNull String endpointId, @NonNull Connection public void onConnectionRejected(@NonNull String endpointId, @NonNull ConnectionResolution connectionResolution) { view.showToast(view.getContext().getString(R.string.receiver_rejected_the_connection), Toast.LENGTH_LONG); resetState(); - presenter.startDiscoveringMode(); + startDiscoveringMode(); } @Override @@ -189,7 +252,7 @@ public void onConnectionUnknownError(@NonNull String endpointId, @NonNull Connec //Todo: And show the user an error view.showToast(view.getContext().getString(R.string.an_error_occurred_before_acceptance_or_rejection), Toast.LENGTH_LONG); resetState(); - presenter.startDiscoveringMode(); + startDiscoveringMode(); } @Override @@ -198,7 +261,7 @@ public void onConnectionBroken(@NonNull String endpointId) { //Todo: Go back to discovering mode resetState(); view.showToast(String.format("The connection to %s has broken", endpointId), Toast.LENGTH_LONG); - presenter.startDiscoveringMode(); + startDiscoveringMode(); } @Override @@ -211,7 +274,7 @@ public void onDisconnected(@NonNull String endpointId) { Timber.e("Endpoint lost %s", endpointId); view.displayMessage("DISCONNECTED"); resetState(); - presenter.startDiscoveringMode(); + startDiscoveringMode(); } private void resetState() { diff --git a/p2p-sync/src/main/java/org/smartregister/p2p/presenter/P2pModeSelectPresenter.java b/p2p-sync/src/main/java/org/smartregister/p2p/presenter/P2pModeSelectPresenter.java deleted file mode 100644 index 93ac38b..0000000 --- a/p2p-sync/src/main/java/org/smartregister/p2p/presenter/P2pModeSelectPresenter.java +++ /dev/null @@ -1,164 +0,0 @@ -package org.smartregister.p2p.presenter; - -import android.content.DialogInterface; -import android.support.annotation.NonNull; - -import org.smartregister.p2p.contract.P2pModeSelectContract; -import org.smartregister.p2p.handler.OnActivityRequestPermissionHandler; -import org.smartregister.p2p.sync.IReceiverSyncLifecycleCallback; -import org.smartregister.p2p.sync.ISenderSyncLifecycleCallback; -import org.smartregister.p2p.sync.ReceiverSyncLifecycleCallback; -import org.smartregister.p2p.sync.SenderSyncLifecycleCallback; -import org.smartregister.p2p.util.Constants; - -import java.util.List; - -/** - * Created by Ephraim Kigamba - ekigamba@ona.io on 08/03/2019 - */ - -public class P2pModeSelectPresenter implements P2pModeSelectContract.Presenter { - - private P2pModeSelectContract.View view; - private P2pModeSelectContract.Interactor interactor; - - private ISenderSyncLifecycleCallback senderSyncLifecycleCallback; - private IReceiverSyncLifecycleCallback receiverSyncLifecycleCallback; - - public P2pModeSelectPresenter(@NonNull P2pModeSelectContract.View view, @NonNull P2pModeSelectContract.Interactor p2pModeSelectInteractor) { - this.view = view; - this.interactor = p2pModeSelectInteractor; - - // This will be added when issue https://github.com/OpenSRP/android-p2p-sync/issues/24 - // is being worked on - //view.addOnResumeHandler(new AdvertisingResumeHandler(this, interactor)); - senderSyncLifecycleCallback = new SenderSyncLifecycleCallback(view, this, interactor); - receiverSyncLifecycleCallback = new ReceiverSyncLifecycleCallback(view, this, interactor); - } - - @Override - public void onSendButtonClicked() { - prepareForDiscovering(false); - } - - @Override - public void onReceiveButtonClicked() { - prepareForAdvertising(false); - } - - @Override - public void prepareForAdvertising(boolean returningFromRequestingPermissions) { - List unauthorisedPermissions = view.getUnauthorisedPermissions(); - // Are all required permissions given - if (unauthorisedPermissions.size() == 0) { - // Check if location is enabled - if (view.isLocationEnabled()) { - startAdvertisingMode(); - } else { - view.requestEnableLocation(new P2pModeSelectContract.View.OnLocationEnabled() { - @Override - public void locationEnabled() { - startAdvertisingMode(); - } - }); - } - } else { - if (!returningFromRequestingPermissions) { - view.addOnActivityRequestPermissionHandler(new OnActivityRequestPermissionHandler() { - @Override - public int getRequestCode() { - return Constants.RQ_CODE.PERMISSIONS; - } - - @Override - public void handlePermissionResult(@NonNull String[] permissions, @NonNull int[] grantResults) { - view.removeOnActivityRequestPermissionHandler(this); - P2pModeSelectPresenter.this.prepareForAdvertising(true); - } - }); - view.requestPermissions(unauthorisedPermissions); - } - } - } - - @Override - public void startAdvertisingMode() { - if (!interactor.isAdvertising()) { - view.enableSendReceiveButtons(false); - view.showReceiveProgressDialog(new P2pModeSelectContract.View.DialogCancelCallback() { - @Override - public void onCancelClicked(DialogInterface dialogInterface) { - interactor.stopAdvertising(); - dialogInterface.dismiss(); - view.enableSendReceiveButtons(true); - } - }); - interactor.startAdvertising(receiverSyncLifecycleCallback); - } - } - - @Override - public void prepareForDiscovering(boolean returningFromRequestingPermissions) { - List unauthorisedPermissions = view.getUnauthorisedPermissions(); - // Are all required permissions given - if (unauthorisedPermissions.size() == 0) { - // Check if location is enabled - if (view.isLocationEnabled()) { - startDiscoveringMode(); - } else { - view.requestEnableLocation(new P2pModeSelectContract.View.OnLocationEnabled() { - @Override - public void locationEnabled() { - startDiscoveringMode(); - } - }); - } - } else { - if (!returningFromRequestingPermissions) { - view.addOnActivityRequestPermissionHandler(new OnActivityRequestPermissionHandler() { - @Override - public int getRequestCode() { - return Constants.RQ_CODE.PERMISSIONS; - } - - @Override - public void handlePermissionResult(@NonNull String[] permissions, @NonNull int[] grantResults) { - view.removeOnActivityRequestPermissionHandler(this); - P2pModeSelectPresenter.this.prepareForDiscovering(true); - } - }); - view.requestPermissions(unauthorisedPermissions); - } - } - } - - @Override - public void startDiscoveringMode() { - if (!interactor.isDiscovering()) { - view.enableSendReceiveButtons(false); - view.showDiscoveringProgressDialog (new P2pModeSelectContract.View.DialogCancelCallback() { - @Override - public void onCancelClicked(DialogInterface dialogInterface) { - interactor.stopDiscovering(); - dialogInterface.dismiss(); - view.enableSendReceiveButtons(true); - } - }); - interactor.startDiscovering(senderSyncLifecycleCallback); - } - } - - @Override - public void onStop() { - view.dismissAllDialogs(); - view.enableSendReceiveButtons(true); - - interactor.stopAdvertising(); - interactor.stopDiscovering(); - interactor.closeAllEndpoints(); - - interactor.cleanupResources(); - interactor = null; - } - -} diff --git a/p2p-sync/src/test/java/org/smartregister/p2p/authenticator/ReceiverConnectionAuthenticatorTest.java b/p2p-sync/src/test/java/org/smartregister/p2p/authenticator/ReceiverConnectionAuthenticatorTest.java index f0e10b5..5093b62 100644 --- a/p2p-sync/src/test/java/org/smartregister/p2p/authenticator/ReceiverConnectionAuthenticatorTest.java +++ b/p2p-sync/src/test/java/org/smartregister/p2p/authenticator/ReceiverConnectionAuthenticatorTest.java @@ -30,7 +30,7 @@ public class ReceiverConnectionAuthenticatorTest { @Mock private P2pModeSelectContract.View view; @Mock - private P2pModeSelectContract.Presenter presenter; + private P2pModeSelectContract.BasePresenter basePresenter; @Mock private P2pModeSelectContract.Interactor interactor; @@ -38,7 +38,7 @@ public class ReceiverConnectionAuthenticatorTest { @Before public void setUp() { - receiverConnectionAuthenticator = new ReceiverConnectionAuthenticator(view, interactor, presenter); + receiverConnectionAuthenticator = new ReceiverConnectionAuthenticator(view, interactor, basePresenter); } @Test diff --git a/p2p-sync/src/test/java/org/smartregister/p2p/authenticator/SenderConnectionAuthenticatorTest.java b/p2p-sync/src/test/java/org/smartregister/p2p/authenticator/SenderConnectionAuthenticatorTest.java index e43f6a7..75d834b 100644 --- a/p2p-sync/src/test/java/org/smartregister/p2p/authenticator/SenderConnectionAuthenticatorTest.java +++ b/p2p-sync/src/test/java/org/smartregister/p2p/authenticator/SenderConnectionAuthenticatorTest.java @@ -40,7 +40,7 @@ public class SenderConnectionAuthenticatorTest { @Mock private P2pModeSelectContract.View view; @Mock - private P2pModeSelectContract.Presenter presenter; + private P2pModeSelectContract.BasePresenter basePresenter; @Mock private P2pModeSelectContract.Interactor interactor; @@ -48,7 +48,7 @@ public class SenderConnectionAuthenticatorTest { @Before public void setUp() { - senderConnectionAuthenticator = new SenderConnectionAuthenticator(view, interactor, presenter); + senderConnectionAuthenticator = new SenderConnectionAuthenticator(view, interactor, basePresenter); } @Test diff --git a/p2p-sync/src/test/java/org/smartregister/p2p/interactor/P2pModeSelectInteractorTest.java b/p2p-sync/src/test/java/org/smartregister/p2p/interactor/P2pModeSelectInteractorTest.java index 5346bd1..41e4760 100644 --- a/p2p-sync/src/test/java/org/smartregister/p2p/interactor/P2pModeSelectInteractorTest.java +++ b/p2p-sync/src/test/java/org/smartregister/p2p/interactor/P2pModeSelectInteractorTest.java @@ -33,7 +33,7 @@ import org.smartregister.p2p.contract.P2pModeSelectContract; import org.smartregister.p2p.shadows.Shadowzzbd; import org.smartregister.p2p.sync.IReceiverSyncLifecycleCallback; -import org.smartregister.p2p.sync.SenderSyncLifecycleCallback; +import org.smartregister.p2p.presenter.P2PSenderPresenter; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -133,9 +133,8 @@ public Object answer(InvocationOnMock invocation) throws Throwable { @Test public void startDiscoveringShouldChangeDiscoveringFlag() { - interactor.startDiscovering(new SenderSyncLifecycleCallback( + interactor.startDiscovering(new P2PSenderPresenter( Mockito.mock(P2pModeSelectContract.View.class) - , Mockito.mock(P2pModeSelectContract.Presenter.class) , interactor)); assertTrue((boolean) ReflectionHelpers.getField(interactor, "discovering")); @@ -163,12 +162,12 @@ public Object answer(InvocationOnMock invocation) throws Throwable { , Mockito.any(EndpointDiscoveryCallback.class) , Mockito.any(DiscoveryOptions.class)); - SenderSyncLifecycleCallback senderSyncLifecycleCallback = Mockito.mock(SenderSyncLifecycleCallback.class); + P2PSenderPresenter p2PSenderPresenter = Mockito.mock(P2PSenderPresenter.class); ReflectionHelpers.setField(interactor, "connectionsClient", connectionsClient); - interactor.startDiscovering(senderSyncLifecycleCallback); + interactor.startDiscovering(p2PSenderPresenter); - Mockito.verify(senderSyncLifecycleCallback, Mockito.times(1)) + Mockito.verify(p2PSenderPresenter, Mockito.times(1)) .onDeviceFound(ArgumentMatchers.eq("id"), Mockito.any(DiscoveredEndpointInfo.class)); } @@ -194,12 +193,12 @@ public Object answer(InvocationOnMock invocation) throws Throwable { , Mockito.any(EndpointDiscoveryCallback.class) , Mockito.any(DiscoveryOptions.class)); - SenderSyncLifecycleCallback senderSyncLifecycleCallback = Mockito.mock(SenderSyncLifecycleCallback.class); + P2PSenderPresenter p2PSenderPresenter = Mockito.mock(P2PSenderPresenter.class); ReflectionHelpers.setField(interactor, "connectionsClient", connectionsClient); - interactor.startDiscovering(senderSyncLifecycleCallback); + interactor.startDiscovering(p2PSenderPresenter); - Mockito.verify(senderSyncLifecycleCallback, Mockito.times(1)) + Mockito.verify(p2PSenderPresenter, Mockito.times(1)) .onDisconnected(ArgumentMatchers.eq("id")); } @@ -239,12 +238,12 @@ public Object answer(InvocationOnMock invocation) throws Throwable { , Mockito.any(EndpointDiscoveryCallback.class) , Mockito.any(DiscoveryOptions.class)); - SenderSyncLifecycleCallback senderSyncLifecycleCallback = Mockito.mock(SenderSyncLifecycleCallback.class); + P2PSenderPresenter p2PSenderPresenter = Mockito.mock(P2PSenderPresenter.class); ReflectionHelpers.setField(interactor, "connectionsClient", connectionsClient); - interactor.startDiscovering(senderSyncLifecycleCallback); + interactor.startDiscovering(p2PSenderPresenter); - Mockito.verify(senderSyncLifecycleCallback, Mockito.times(1)) + Mockito.verify(p2PSenderPresenter, Mockito.times(1)) .onDiscoveringFailed(ArgumentMatchers.any(Exception.class)); assertFalse((boolean) ReflectionHelpers.getField(interactor, "discovering")); } diff --git a/p2p-sync/src/test/java/org/smartregister/p2p/presenter/P2PReceiverPresenterTest.java b/p2p-sync/src/test/java/org/smartregister/p2p/presenter/P2PReceiverPresenterTest.java new file mode 100644 index 0000000..a4bef09 --- /dev/null +++ b/p2p-sync/src/test/java/org/smartregister/p2p/presenter/P2PReceiverPresenterTest.java @@ -0,0 +1,504 @@ +package org.smartregister.p2p.presenter; + +import android.Manifest; +import android.content.DialogInterface; +import android.widget.Toast; + +import com.google.android.gms.nearby.connection.ConnectionInfo; +import com.google.android.gms.nearby.connection.ConnectionResolution; +import com.google.android.gms.nearby.connection.Payload; +import com.google.android.gms.nearby.connection.PayloadCallback; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.mockito.stubbing.Answer; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.util.ReflectionHelpers; +import org.smartregister.p2p.contract.P2pModeSelectContract; +import org.smartregister.p2p.dialog.QRCodeGeneratorDialog; +import org.smartregister.p2p.handler.OnActivityRequestPermissionHandler; +import org.smartregister.p2p.sync.DiscoveredDevice; +import org.smartregister.p2p.sync.IReceiverSyncLifecycleCallback; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +/** + * Created by Ephraim Kigamba - ekigamba@ona.io on 19/03/2019 + */ +@RunWith(RobolectricTestRunner.class) +public class P2PReceiverPresenterTest { + + @Rule + public MockitoRule mockitoRule = MockitoJUnit.rule(); + + @Mock + private P2pModeSelectContract.View view; + @Mock + private P2pModeSelectContract.Interactor interactor; + + private P2PReceiverPresenter p2PReceiverPresenter; + + @Before + public void setUp() throws Exception { + Mockito.doReturn(RuntimeEnvironment.application) + .when(view) + .getContext(); + + p2PReceiverPresenter = Mockito.spy(new P2PReceiverPresenter(view, interactor)); + } + + @Test + public void onReceiveButtonClickedShouldCallPrepareForAdvertising() { + p2PReceiverPresenter.onReceiveButtonClicked(); + + Mockito.verify(p2PReceiverPresenter, Mockito.times(1)) + .prepareForAdvertising(false); + } + + @Test + public void prepareAdvertisingShouldRequestPermissionsWhenPermissionsAreNotGranted() { + List unauthorizedPermissions = new ArrayList<>(); + unauthorizedPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION); + + Mockito.doReturn(unauthorizedPermissions) + .when(view) + .getUnauthorisedPermissions(); + + p2PReceiverPresenter.prepareForAdvertising(false); + + Mockito.verify(view, Mockito.times(1)) + .requestPermissions(unauthorizedPermissions); + Mockito.verify(view, Mockito.times(1)) + .addOnActivityRequestPermissionHandler(Mockito.any(OnActivityRequestPermissionHandler.class)); + } + + @Test + public void prepareAdvertisingShouldCallItselfWhenPermissionsGrantedExplicitlyByUserOnView() { + final ArrayList sensitiveObjects = new ArrayList<>(); + List unauthorizedPermissions = new ArrayList<>(); + unauthorizedPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION); + + Mockito.doReturn(unauthorizedPermissions) + .when(view) + .getUnauthorisedPermissions(); + + Mockito.doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + OnActivityRequestPermissionHandler onActivityRequestPermissionHandler = invocation.getArgument(0); + sensitiveObjects.add(onActivityRequestPermissionHandler); + + onActivityRequestPermissionHandler.handlePermissionResult(new String[]{""}, new int[]{0}); + return null; + } + }).when(view) + .addOnActivityRequestPermissionHandler(Mockito.any(OnActivityRequestPermissionHandler.class)); + + p2PReceiverPresenter.prepareForAdvertising(false); + + Mockito.verify(p2PReceiverPresenter, Mockito.times(1)) + .prepareForAdvertising(true); + Mockito.verify(view, Mockito.times(1)) + .removeOnActivityRequestPermissionHandler((OnActivityRequestPermissionHandler) sensitiveObjects.get(0)); + } + + @Test + public void prepareAdvertisingShouldCallStartAdvertisingModeWhenPermissionsAreGrantedAndLocationEnabled() { + List unauthorizedPermissions = new ArrayList<>(); + Mockito.doReturn(unauthorizedPermissions) + .when(view) + .getUnauthorisedPermissions(); + + Mockito.doReturn(true) + .when(view) + .isLocationEnabled(); + + p2PReceiverPresenter.prepareForAdvertising(false); + + Mockito.verify(p2PReceiverPresenter, Mockito.times(1)) + .startAdvertisingMode(); + } + + @Test + public void prepareAdvertisingShouldRequestLocationEnableWhenPermissionsAreGrantedAndLocationDisabled() { + List unauthorizedPermissions = new ArrayList<>(); + Mockito.doReturn(unauthorizedPermissions) + .when(view) + .getUnauthorisedPermissions(); + + Mockito.doReturn(false) + .when(view) + .isLocationEnabled(); + + p2PReceiverPresenter.prepareForAdvertising(false); + + Mockito.verify(view, Mockito.times(1)) + .requestEnableLocation(Mockito.any(P2pModeSelectContract.View.OnLocationEnabled.class)); + } + + @Test + public void prepareAdvertisingShouldCallNothingWhenPermissionsAreNotGrantedAndReturnedFromRequestingPermissions() { + List unauthorizedPermissions = new ArrayList<>(); + unauthorizedPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION); + + Mockito.doReturn(unauthorizedPermissions) + .when(view) + .getUnauthorisedPermissions(); + + p2PReceiverPresenter.prepareForAdvertising(false); + + Mockito.verify(view, Mockito.times(1)) + .requestPermissions(unauthorizedPermissions); + } + + @Test + public void startAdvertisingModeShouldDisableButtonsWhenAdvertisingIsFalse() { + // The interactor.advertising is false by default + p2PReceiverPresenter.startAdvertisingMode(); + + Mockito.verify(view, Mockito.times(1)) + .enableSendReceiveButtons(false); + } + + @Test + public void startAdvertisingModeShouldCallNothingWhenAdvertisingIsTrue() { + Mockito.doReturn(true) + .when(interactor) + .isAdvertising(); + + p2PReceiverPresenter.startAdvertisingMode(); + + Mockito.verify(view, Mockito.times(0)) + .enableSendReceiveButtons(false); + } + + @Test + public void startAdvertisingModeShouldShowProgressDialogBarWhenAdvertisingIsFalse() { + // interactor.advertising is false by default + p2PReceiverPresenter.startAdvertisingMode(); + + Mockito.verify(view, Mockito.times(1)) + .showReceiveProgressDialog(Mockito.any(P2pModeSelectContract.View.DialogCancelCallback.class)); + } + + @Test + public void startAdvertisingModeShouldCallInteractorAdvertisingWhenAdvertisingIsFalse() { + // interactor.advertising is false by default + p2PReceiverPresenter.startAdvertisingMode(); + Mockito.verify(interactor, Mockito.times(1)) + .startAdvertising(Mockito.any(IReceiverSyncLifecycleCallback.class)); + } + + @Test + public void cancelDialogShouldCallStopAdvertisingWhenClicked(){ + // interactor.advertising is false by default + Mockito.doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + P2pModeSelectContract.View.DialogCancelCallback dialogCancelCallback = invocation.getArgument(0); + dialogCancelCallback.onCancelClicked(new DialogInterface() { + @Override + public void cancel() { + // Do nothing + } + + @Override + public void dismiss() { + // Do nothing + } + }); + + return null; + } + }).when(view) + .showReceiveProgressDialog(Mockito.any(P2pModeSelectContract.View.DialogCancelCallback.class)); + + + p2PReceiverPresenter.startAdvertisingMode(); + Mockito.verify(interactor, Mockito.times(1)) + .stopAdvertising(); + } + + @Test + public void cancelDialogShouldCallDialogIDismissWhenClicked(){ + // interactor.advertising is false by default + final DialogInterface dialogInterface = Mockito.mock(DialogInterface.class); + + Mockito.doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + P2pModeSelectContract.View.DialogCancelCallback dialogCancelCallback = invocation.getArgument(0); + dialogCancelCallback.onCancelClicked(dialogInterface); + + return null; + } + }).when(view) + .showReceiveProgressDialog(Mockito.any(P2pModeSelectContract.View.DialogCancelCallback.class)); + + + p2PReceiverPresenter.startAdvertisingMode(); + Mockito.verify(dialogInterface, Mockito.times(1)) + .dismiss(); + } + + @Test + public void cancelDialogShouldEnableButtonsWhenClicked(){ + // interactor.advertising is false by default + final DialogInterface dialogInterface = Mockito.mock(DialogInterface.class); + + Mockito.doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + P2pModeSelectContract.View.DialogCancelCallback dialogCancelCallback = invocation.getArgument(0); + dialogCancelCallback.onCancelClicked(dialogInterface); + + return null; + } + }).when(view) + .showReceiveProgressDialog(Mockito.any(P2pModeSelectContract.View.DialogCancelCallback.class)); + + + p2PReceiverPresenter.startAdvertisingMode(); + Mockito.verify(view, Mockito.times(1)) + .enableSendReceiveButtons(true); + } + + @Test + public void onAdvertisingFailedShouldResetUI() { + p2PReceiverPresenter.onAdvertisingFailed(Mockito.mock(Exception.class)); + + Mockito.verify(view, Mockito.times(1)) + .removeReceiveProgressDialog(); + Mockito.verify(view, Mockito.times(1)) + .enableSendReceiveButtons(true); + } + + @Test + public void onConnectionInitiatedShouldDoNothingWhenNoAnotherConnectionIsBeingNegotiated() { + ReflectionHelpers.setField(p2PReceiverPresenter, "currentSender", Mockito.mock(DiscoveredDevice.class)); + assertNotNull(ReflectionHelpers.getField(p2PReceiverPresenter, "currentSender")); + p2PReceiverPresenter.onConnectionInitiated("id", Mockito.mock(ConnectionInfo.class)); + + Mockito.verify(interactor, Mockito.times(0)) + .stopAdvertising(); + + Mockito.verify(view, Mockito.times(0)) + .removeReceiveProgressDialog(); + } + + @Test + public void onConnectionInitiatedShouldStopAdvertisingAndAuthenticateConnectionWhenNoOtherConnectionIsBeingNegotiated() { + ConnectionInfo connectionInfo = Mockito.mock(ConnectionInfo.class); + String authenticationCode = "iowejncCJD"; + String deviceName = "SAMSUNG SM78"; + + Mockito.doReturn(true) + .when(connectionInfo) + .isIncomingConnection(); + + Mockito.doReturn(deviceName) + .when(connectionInfo) + .getEndpointName(); + + Mockito.doReturn(authenticationCode) + .when(connectionInfo) + .getAuthenticationToken(); + + p2PReceiverPresenter.onConnectionInitiated("id", connectionInfo); + assertNotNull(ReflectionHelpers.getField(p2PReceiverPresenter, "currentSender")); + + Mockito.verify(interactor, Mockito.times(1)) + .stopAdvertising(); + + Mockito.verify(view, Mockito.times(1)) + .removeReceiveProgressDialog(); + + Mockito.verify(view, Mockito.times(1)) + .showQRCodeGeneratorDialog(ArgumentMatchers.eq(authenticationCode) + , ArgumentMatchers.eq(deviceName) + , Mockito.any(QRCodeGeneratorDialog.QRCodeAuthenticationCallback.class)); + } + + @Test + public void onConnectionAcceptedShouldRegisterSenderDeviceWithInteractor() { + String endpointId = "id"; + DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); + + Mockito.doReturn(endpointId) + .when(discoveredDevice) + .getEndpointId(); + + ReflectionHelpers.setField(p2PReceiverPresenter, "currentSender", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PReceiverPresenter, "currentSender")); + + + p2PReceiverPresenter.onConnectionAccepted(endpointId, Mockito.mock(ConnectionResolution.class)); + + Mockito.verify(interactor, Mockito.times(1)) + .connectedTo(ArgumentMatchers.eq(endpointId)); + } + + @Test + public void onConnectionRejectedShouldRestartAdvertisingModeAndResetState() { + String endpointId = "id"; + + DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); + + ReflectionHelpers.setField(p2PReceiverPresenter, "currentSender", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PReceiverPresenter, "currentSender")); + + p2PReceiverPresenter.onConnectionRejected(endpointId, Mockito.mock(ConnectionResolution.class)); + + Mockito.verify(p2PReceiverPresenter, Mockito.times(1)) + .startAdvertisingMode(); + assertNull(ReflectionHelpers.getField(p2PReceiverPresenter, "currentSender")); + } + + @Test + public void onConnectionUnknownErrorShouldRestartAdvertisingAndResetState() { + String endpointId = "id"; + + DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); + + ReflectionHelpers.setField(p2PReceiverPresenter, "currentSender", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PReceiverPresenter, "currentSender")); + + p2PReceiverPresenter.onConnectionUnknownError(endpointId, Mockito.mock(ConnectionResolution.class)); + + Mockito.verify(p2PReceiverPresenter, Mockito.times(1)) + .startAdvertisingMode(); + assertNull(ReflectionHelpers.getField(p2PReceiverPresenter, "currentSender")); + } + + @Test + public void onConnectionBrokenShouldRestartAdvertisingAndResetState() { + String endpointId = "id"; + + DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); + + ReflectionHelpers.setField(p2PReceiverPresenter, "currentSender", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PReceiverPresenter, "currentSender")); + + p2PReceiverPresenter.onConnectionBroken(endpointId); + + Mockito.verify(p2PReceiverPresenter, Mockito.times(1)) + .startAdvertisingMode(); + assertNull(ReflectionHelpers.getField(p2PReceiverPresenter, "currentSender")); + } + + @Test + public void onDisconnectedShouldRestartAdvertisingAndResetState() { + String endpointId = "id"; + + DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); + + ReflectionHelpers.setField(p2PReceiverPresenter, "currentSender", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PReceiverPresenter, "currentSender")); + + p2PReceiverPresenter.onDisconnected(endpointId); + + Mockito.verify(p2PReceiverPresenter, Mockito.times(1)) + .startAdvertisingMode(); + assertNull(ReflectionHelpers.getField(p2PReceiverPresenter, "currentSender")); + } + + @Test + public void onAuthenticationSuccessfulShouldAcceptConnectWhenNegotiatingConnectionWithSender() { + String endpointId = "id"; + DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); + + Mockito.doReturn(endpointId) + .when(discoveredDevice) + .getEndpointId(); + + ReflectionHelpers.setField(p2PReceiverPresenter, "currentSender", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PReceiverPresenter, "currentSender")); + + p2PReceiverPresenter.onAuthenticationSuccessful(); + Mockito.verify(interactor, Mockito.times(1)) + .acceptConnection(ArgumentMatchers.eq(endpointId), Mockito.any(PayloadCallback.class)); + } + + @Test + public void onAuthenticationSuccessfulShouldRegisterCurrentInstanceAsPayloadListener() { + final String endpointId = "id"; + DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); + + Mockito.doReturn(endpointId) + .when(discoveredDevice) + .getEndpointId(); + + P2PReceiverPresenter spiedCallback = Mockito.spy(p2PReceiverPresenter); + + ReflectionHelpers.setField(spiedCallback, "currentSender", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(spiedCallback, "currentSender")); + + Mockito.doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + ((PayloadCallback) invocation.getArgument(1)) + .onPayloadReceived(endpointId, Mockito.mock(Payload.class)); + + return null; + } + }) + .when(interactor) + .acceptConnection(ArgumentMatchers.eq(endpointId), Mockito.any(PayloadCallback.class)); + + spiedCallback.onAuthenticationSuccessful(); + Mockito.verify(spiedCallback, Mockito.times(1)) + .onPayloadReceived(ArgumentMatchers.eq(endpointId), Mockito.any(Payload.class)); + } + + @Test + public void onAuthenticationFailedShouldRejectConnectionWhenNegotiatingWithASender() { + final String endpointId = "id"; + DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); + + Mockito.doReturn(endpointId) + .when(discoveredDevice) + .getEndpointId(); + + ReflectionHelpers.setField(p2PReceiverPresenter, "currentSender", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PReceiverPresenter, "currentSender")); + + p2PReceiverPresenter.onAuthenticationFailed(new Exception()); + + Mockito.verify(interactor, Mockito.times(1)) + .rejectConnection(ArgumentMatchers.eq(endpointId)); + Mockito.verify(view, Mockito.times(1)) + .showToast(ArgumentMatchers.eq("Authentication failed! The connection has been rejected") + , ArgumentMatchers.eq(Toast.LENGTH_LONG)); + } + + @Test + public void onAuthenticationCancelledShouldRejectConnectionWhenNegotiatingWithASender() { + final String endpointId = "id"; + DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); + + Mockito.doReturn(endpointId) + .when(discoveredDevice) + .getEndpointId(); + + ReflectionHelpers.setField(p2PReceiverPresenter, "currentSender", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PReceiverPresenter, "currentSender")); + + p2PReceiverPresenter.onAuthenticationCancelled(""); + + Mockito.verify(interactor, Mockito.times(1)) + .rejectConnection(ArgumentMatchers.eq(endpointId)); + } +} \ No newline at end of file diff --git a/p2p-sync/src/test/java/org/smartregister/p2p/sync/SenderSyncLifecycleCallbackTest.java b/p2p-sync/src/test/java/org/smartregister/p2p/presenter/P2PSenderPresenterTest.java similarity index 57% rename from p2p-sync/src/test/java/org/smartregister/p2p/sync/SenderSyncLifecycleCallbackTest.java rename to p2p-sync/src/test/java/org/smartregister/p2p/presenter/P2PSenderPresenterTest.java index 0a2c7ae..462813c 100644 --- a/p2p-sync/src/test/java/org/smartregister/p2p/sync/SenderSyncLifecycleCallbackTest.java +++ b/p2p-sync/src/test/java/org/smartregister/p2p/presenter/P2PSenderPresenterTest.java @@ -1,5 +1,6 @@ -package org.smartregister.p2p.sync; +package org.smartregister.p2p.presenter; +import android.Manifest; import android.widget.Toast; import com.google.android.gms.nearby.connection.ConnectionInfo; @@ -25,6 +26,12 @@ import org.smartregister.p2p.callback.OnResultCallback; import org.smartregister.p2p.contract.P2pModeSelectContract; import org.smartregister.p2p.dialog.QRCodeScanningDialog; +import org.smartregister.p2p.handler.OnActivityRequestPermissionHandler; +import org.smartregister.p2p.presenter.P2PSenderPresenter; +import org.smartregister.p2p.sync.DiscoveredDevice; + +import java.util.ArrayList; +import java.util.List; import static org.junit.Assert.*; @@ -32,7 +39,7 @@ * Created by Ephraim Kigamba - ekigamba@ona.io on 19/03/2019 */ @RunWith(RobolectricTestRunner.class) -public class SenderSyncLifecycleCallbackTest { +public class P2PSenderPresenterTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); @@ -41,10 +48,8 @@ public class SenderSyncLifecycleCallbackTest { private P2pModeSelectContract.View view; @Mock private P2pModeSelectContract.Interactor interactor; - @Mock - private P2pModeSelectContract.Presenter presenter; - private SenderSyncLifecycleCallback senderSyncLifecycleCallback; + private P2PSenderPresenter p2PSenderPresenter; @Before public void setUp() throws Exception { @@ -52,12 +57,113 @@ public void setUp() throws Exception { .when(view) .getContext(); - senderSyncLifecycleCallback = new SenderSyncLifecycleCallback(view, presenter, interactor); + p2PSenderPresenter = Mockito.spy(new P2PSenderPresenter(view, interactor)); + } + + @Test + public void onSendButtonClickedShouldCallPrepareDiscovering() { + + p2PSenderPresenter.onSendButtonClicked(); + + Mockito.verify(p2PSenderPresenter, Mockito.times(1)) + .prepareForDiscovering(false); + } + + @Test + public void prepareDiscoveringShouldCallStartDiscoveringModeWhenPermissionsGrantedAndLocationEnabled() { + List unauthorizedPermissions = new ArrayList<>(); + + Mockito.doReturn(unauthorizedPermissions) + .when(view) + .getUnauthorisedPermissions(); + + Mockito.doReturn(true) + .when(view) + .isLocationEnabled(); + + p2PSenderPresenter.prepareForDiscovering(false); + Mockito.verify(p2PSenderPresenter, Mockito.times(1)) + .startDiscoveringMode(); + } + + @Test + public void prepareDiscoveringShouldCallRequestPermissionsWhenPermissionsNotGrantedAndNotReturningFromRequestingPermissions() { + List unauthorizedPermissions = new ArrayList<>(); + unauthorizedPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION); + + Mockito.doReturn(unauthorizedPermissions) + .when(view) + .getUnauthorisedPermissions(); + + p2PSenderPresenter.prepareForDiscovering(false); + Mockito.verify(view, Mockito.times(1)) + .requestPermissions(unauthorizedPermissions); + Mockito.verify(view, Mockito.times(1)) + .addOnActivityRequestPermissionHandler(Mockito.any(OnActivityRequestPermissionHandler.class)); + } + + @Test + public void prepareDiscoveringShouldNotCallRequestPermissionsWhenPermissionsNotGrantedAndReturningFromRequestionPermissions() { + List unauthorizedPermissions = new ArrayList<>(); + unauthorizedPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION); + + Mockito.doReturn(unauthorizedPermissions) + .when(view) + .getUnauthorisedPermissions(); + + p2PSenderPresenter.prepareForDiscovering(true); + Mockito.verify(view, Mockito.times(0)) + .requestPermissions(unauthorizedPermissions); + } + + @Test + public void prepareDiscoveringShouldRequestEnableLocationWhenPermissionsGrantedAndLocationNotEnabled() { + List unauthorizedPermissions = new ArrayList<>(); + Mockito.doReturn(unauthorizedPermissions) + .when(view) + .getUnauthorisedPermissions(); + + Mockito.doReturn(false) + .when(view) + .isLocationEnabled(); + + p2PSenderPresenter.prepareForDiscovering(false); + + Mockito.verify(view, Mockito.times(1)) + .requestEnableLocation(Mockito.any(P2pModeSelectContract.View.OnLocationEnabled.class)); + } + + @Test + public void prepareDiscoveringShouldCallItselfAfterPermissionsGrantedExplicitlyByUserOnView() { + final ArrayList sensitiveObjects = new ArrayList<>(); + List unauthorizedPermissions = new ArrayList<>(); + unauthorizedPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION); + Mockito.doReturn(unauthorizedPermissions) + .when(view) + .getUnauthorisedPermissions(); + + Mockito.doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + OnActivityRequestPermissionHandler onActivityRequestPermissionHandler = invocation.getArgument(0); + sensitiveObjects.add(onActivityRequestPermissionHandler); + onActivityRequestPermissionHandler.handlePermissionResult(new String[] {""}, new int[]{0}); + return null; + } + }).when(view) + .addOnActivityRequestPermissionHandler(Mockito.any(OnActivityRequestPermissionHandler.class)); + + p2PSenderPresenter.prepareForDiscovering(false); + + Mockito.verify(p2PSenderPresenter, Mockito.times(1)) + .prepareForDiscovering(true); + Mockito.verify(view, Mockito.times(1)) + .removeOnActivityRequestPermissionHandler((OnActivityRequestPermissionHandler) sensitiveObjects.get(0)); } @Test public void onDiscoveringFailedShouldResetUI() { - senderSyncLifecycleCallback.onDiscoveringFailed(new Exception()); + p2PSenderPresenter.onDiscoveringFailed(new Exception()); Mockito.verify(view, Mockito.times(1)) .removeDiscoveringProgressDialog(); @@ -82,7 +188,7 @@ public void onDeviceFoundShouldStopDiscoveringAndRequestConnectionWhenNoOtherCon .when(discoveredEndpointInfo) .getServiceId(); - senderSyncLifecycleCallback.onDeviceFound(endpointId, discoveredEndpointInfo); + p2PSenderPresenter.onDeviceFound(endpointId, discoveredEndpointInfo); Mockito.verify(interactor, Mockito.times(1)) .stopDiscovering(); @@ -95,7 +201,7 @@ public void onDeviceFoundShouldStopDiscoveringAndRequestConnectionWhenNoOtherCon , Mockito.any(OnResultCallback.class) , Mockito.any(ConnectionLifecycleCallback.class)); - assertNotNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + assertNotNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); } @Test @@ -106,10 +212,10 @@ public void onDeviceFoundShouldDoNothingWhenAnotherConnectionIsBeingNegotiated() DiscoveredDevice discoveredDevice = new DiscoveredDevice(endpointId, discoveredEndpointInfo); - ReflectionHelpers.setField(senderSyncLifecycleCallback, "currentReceiver", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + ReflectionHelpers.setField(p2PSenderPresenter, "currentReceiver", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); - senderSyncLifecycleCallback.onDeviceFound(endpointId, discoveredEndpointInfo); + p2PSenderPresenter.onDeviceFound(endpointId, discoveredEndpointInfo); Mockito.verify(interactor, Mockito.times(0)) .stopDiscovering(); @@ -153,7 +259,7 @@ public Object answer(InvocationOnMock invocation) throws Throwable { , Mockito.any(OnResultCallback.class) , Mockito.any(ConnectionLifecycleCallback.class)); - SenderSyncLifecycleCallback spiedCallback = Mockito.spy(senderSyncLifecycleCallback); + P2PSenderPresenter spiedCallback = Mockito.spy(p2PSenderPresenter); spiedCallback.onDeviceFound(endpointId, discoveredEndpointInfo); @@ -191,7 +297,7 @@ public Object answer(InvocationOnMock invocation) throws Throwable { , Mockito.any(OnResultCallback.class) , Mockito.any(ConnectionLifecycleCallback.class)); - SenderSyncLifecycleCallback spiedCallback = Mockito.spy(senderSyncLifecycleCallback); + P2PSenderPresenter spiedCallback = Mockito.spy(p2PSenderPresenter); spiedCallback.onDeviceFound(endpointId, discoveredEndpointInfo); @@ -203,14 +309,14 @@ public Object answer(InvocationOnMock invocation) throws Throwable { public void onRequestConnectionFailedShouldResetStateAndStartDiscoveringMode() { DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); - ReflectionHelpers.setField(senderSyncLifecycleCallback, "currentReceiver", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + ReflectionHelpers.setField(p2PSenderPresenter, "currentReceiver", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); - senderSyncLifecycleCallback.onRequestConnectionFailed(new Exception()); + p2PSenderPresenter.onRequestConnectionFailed(new Exception()); - Mockito.verify(presenter, Mockito.times(1)) + Mockito.verify(p2PSenderPresenter, Mockito.times(1)) .startDiscoveringMode(); - assertNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + assertNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); } @Test @@ -225,12 +331,12 @@ public void onConnectionInitiatedShouldUpdateDiscoveredDeviceInfoAndShowQRCodeSc DiscoveredDevice discoveredDevice = new DiscoveredDevice(endpointId, discoveredEndpointInfo); - ReflectionHelpers.setField(senderSyncLifecycleCallback, "currentReceiver", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + ReflectionHelpers.setField(p2PSenderPresenter, "currentReceiver", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); - senderSyncLifecycleCallback.onConnectionInitiated(endpointId, connectionInfo); + p2PSenderPresenter.onConnectionInitiated(endpointId, connectionInfo); - assertEquals(connectionInfo, ((DiscoveredDevice)ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")) + assertEquals(connectionInfo, ((DiscoveredDevice)ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")) .getConnectionInfo()); Mockito.verify(view, Mockito.times(1)) @@ -242,9 +348,9 @@ public void onConnectionInitiatedShouldDoNothingWhenNotNegotiatingDeviceConnecti String endpointId = "id"; ConnectionInfo connectionInfo = Mockito.mock(ConnectionInfo.class); - assertNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + assertNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); - senderSyncLifecycleCallback.onConnectionInitiated(endpointId, connectionInfo); + p2PSenderPresenter.onConnectionInitiated(endpointId, connectionInfo); Mockito.verify(view, Mockito.times(0)) .showQRCodeScanningDialog(Mockito.any(QRCodeScanningDialog.QRCodeScanDialogCallback.class)); @@ -257,9 +363,9 @@ public void onAuthenticationSuccessfulShouldAcceptConnectionWhenNegotiatingDevic DiscoveredDevice discoveredDevice = new DiscoveredDevice(endpointId, discoveredEndpointInfo); - ReflectionHelpers.setField(senderSyncLifecycleCallback, "currentReceiver", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); - senderSyncLifecycleCallback.onAuthenticationSuccessful(); + ReflectionHelpers.setField(p2PSenderPresenter, "currentReceiver", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); + p2PSenderPresenter.onAuthenticationSuccessful(); Mockito.verify(interactor, Mockito.times(1)) .acceptConnection(ArgumentMatchers.eq(endpointId) @@ -276,10 +382,10 @@ public void onAuthenticationFailedShouldRejectConnectionWhenNegotiatingDeviceCon DiscoveredDevice discoveredDevice = new DiscoveredDevice(endpointId, discoveredEndpointInfo); - ReflectionHelpers.setField(senderSyncLifecycleCallback, "currentReceiver", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + ReflectionHelpers.setField(p2PSenderPresenter, "currentReceiver", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); - senderSyncLifecycleCallback.onAuthenticationFailed(new Exception()); + p2PSenderPresenter.onAuthenticationFailed(new Exception()); Mockito.verify(interactor, Mockito.times(1)) .rejectConnection(ArgumentMatchers.eq(endpointId)); @@ -295,10 +401,10 @@ public void onAuthenticationCancelledShouldRejectConnectionWhenNegotiatingDevice DiscoveredDevice discoveredDevice = new DiscoveredDevice(endpointId, discoveredEndpointInfo); - ReflectionHelpers.setField(senderSyncLifecycleCallback, "currentReceiver", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + ReflectionHelpers.setField(p2PSenderPresenter, "currentReceiver", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); - senderSyncLifecycleCallback.onAuthenticationCancelled(""); + p2PSenderPresenter.onAuthenticationCancelled(""); Mockito.verify(interactor, Mockito.times(1)) .rejectConnection(ArgumentMatchers.eq(endpointId)); @@ -311,12 +417,12 @@ public void onConnectionAcceptedShouldRegisterReceiverDeviceWithInteractor() { DiscoveredDevice discoveredDevice = new DiscoveredDevice(endpointId, discoveredEndpointInfo); - ReflectionHelpers.setField(senderSyncLifecycleCallback, "currentReceiver", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + ReflectionHelpers.setField(p2PSenderPresenter, "currentReceiver", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); ConnectionResolution connectionResolution = Mockito.mock(ConnectionResolution.class); - senderSyncLifecycleCallback.onConnectionAccepted(endpointId, connectionResolution); + p2PSenderPresenter.onConnectionAccepted(endpointId, connectionResolution); Mockito.verify(interactor, Mockito.times(1)) .connectedTo(ArgumentMatchers.eq(endpointId)); @@ -330,14 +436,14 @@ public void onConnectionRejectedShouldResetStateAndStartDiscoveringMode() { DiscoveredDevice discoveredDevice = new DiscoveredDevice(endpointId, discoveredEndpointInfo); - ReflectionHelpers.setField(senderSyncLifecycleCallback, "currentReceiver", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + ReflectionHelpers.setField(p2PSenderPresenter, "currentReceiver", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); - senderSyncLifecycleCallback.onConnectionRejected(endpointId, connectionResolution); + p2PSenderPresenter.onConnectionRejected(endpointId, connectionResolution); - Mockito.verify(presenter, Mockito.times(1)) + Mockito.verify(p2PSenderPresenter, Mockito.times(1)) .startDiscoveringMode(); - assertNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + assertNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); } @Test @@ -348,14 +454,14 @@ public void onConnectionUnknownErrorShouldResetStateAndStartDiscoveringMode() { DiscoveredDevice discoveredDevice = new DiscoveredDevice(endpointId, discoveredEndpointInfo); - ReflectionHelpers.setField(senderSyncLifecycleCallback, "currentReceiver", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + ReflectionHelpers.setField(p2PSenderPresenter, "currentReceiver", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); - senderSyncLifecycleCallback.onConnectionUnknownError(endpointId, connectionResolution); + p2PSenderPresenter.onConnectionUnknownError(endpointId, connectionResolution); - Mockito.verify(presenter, Mockito.times(1)) + Mockito.verify(p2PSenderPresenter, Mockito.times(1)) .startDiscoveringMode(); - assertNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + assertNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); } @Test @@ -365,14 +471,14 @@ public void onConnectionBrokenShouldResetStateAndStartDiscoveringMode() { DiscoveredDevice discoveredDevice = new DiscoveredDevice(endpointId, discoveredEndpointInfo); - ReflectionHelpers.setField(senderSyncLifecycleCallback, "currentReceiver", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + ReflectionHelpers.setField(p2PSenderPresenter, "currentReceiver", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); - senderSyncLifecycleCallback.onConnectionBroken(endpointId); + p2PSenderPresenter.onConnectionBroken(endpointId); - Mockito.verify(presenter, Mockito.times(1)) + Mockito.verify(p2PSenderPresenter, Mockito.times(1)) .startDiscoveringMode(); - assertNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + assertNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); } @Test @@ -382,13 +488,13 @@ public void onDisconnectedShouldResetStateAndStartDiscoveringMode() { DiscoveredDevice discoveredDevice = new DiscoveredDevice(endpointId, discoveredEndpointInfo); - ReflectionHelpers.setField(senderSyncLifecycleCallback, "currentReceiver", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + ReflectionHelpers.setField(p2PSenderPresenter, "currentReceiver", discoveredDevice); + assertNotNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); - senderSyncLifecycleCallback.onDisconnected(endpointId); + p2PSenderPresenter.onDisconnected(endpointId); - Mockito.verify(presenter, Mockito.times(1)) + Mockito.verify(p2PSenderPresenter, Mockito.times(1)) .startDiscoveringMode(); - assertNull(ReflectionHelpers.getField(senderSyncLifecycleCallback, "currentReceiver")); + assertNull(ReflectionHelpers.getField(p2PSenderPresenter, "currentReceiver")); } } \ No newline at end of file diff --git a/p2p-sync/src/test/java/org/smartregister/p2p/presenter/P2pModeSelectPresenterTest.java b/p2p-sync/src/test/java/org/smartregister/p2p/presenter/P2pModeSelectPresenterTest.java deleted file mode 100644 index 80bed88..0000000 --- a/p2p-sync/src/test/java/org/smartregister/p2p/presenter/P2pModeSelectPresenterTest.java +++ /dev/null @@ -1,364 +0,0 @@ -package org.smartregister.p2p.presenter; - -import android.Manifest; -import android.content.DialogInterface; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; -import org.smartregister.p2p.contract.P2pModeSelectContract; -import org.smartregister.p2p.handler.OnActivityRequestPermissionHandler; -import org.smartregister.p2p.sync.IReceiverSyncLifecycleCallback; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by Ephraim Kigamba - ekigamba@ona.io on 08/03/2019 - */ -@RunWith(MockitoJUnitRunner.class) -public class P2pModeSelectPresenterTest { - - @Mock - private P2pModeSelectContract.View view; - @Mock - private P2pModeSelectContract.Interactor interactor; - private P2pModeSelectContract.Presenter presenter; - - @Before - public void setUp() throws Exception { - presenter = new P2pModeSelectPresenter(view, interactor); - } - - @Test - public void onSendButtonClickedShouldCallPrepareDiscovering() { - P2pModeSelectContract.Presenter spiedPresenter = Mockito.spy(presenter); - spiedPresenter.onSendButtonClicked(); - - Mockito.verify(spiedPresenter, Mockito.times(1)) - .prepareForDiscovering(false); - } - - @Test - public void onReceiveButtonClickedShouldCallPrepareForAdvertising() { - P2pModeSelectContract.Presenter spiedPresenter = Mockito.spy(presenter); - - spiedPresenter.onReceiveButtonClicked(); - - Mockito.verify(spiedPresenter, Mockito.times(1)) - .prepareForAdvertising(false); - } - - @Test - public void startAdvertisingModeShouldDisableButtonsWhenAdvertisingIsFalse() { - // The interactor.advertising is false by default - presenter.startAdvertisingMode(); - - Mockito.verify(view, Mockito.times(1)) - .enableSendReceiveButtons(false); - } - - @Test - public void startAdvertisingModeShouldCallNothingWhenAdvertisingIsTrue() { - Mockito.doReturn(true) - .when(interactor) - .isAdvertising(); - - presenter.startAdvertisingMode(); - - Mockito.verify(view, Mockito.times(0)) - .enableSendReceiveButtons(false); - } - - @Test - public void startAdvertisingModeShouldShowProgressDialogBarWhenAdvertisingIsFalse() { - // interactor.advertising is false by default - presenter.startAdvertisingMode(); - - Mockito.verify(view, Mockito.times(1)) - .showReceiveProgressDialog(Mockito.any(P2pModeSelectContract.View.DialogCancelCallback.class)); - } - - @Test - public void startAdvertisingModeShouldCallInteractorAdvertisingWhenAdvertisingIsFalse() { - // interactor.advertising is false by default - presenter.startAdvertisingMode(); - Mockito.verify(interactor, Mockito.times(1)) - .startAdvertising(Mockito.any(IReceiverSyncLifecycleCallback.class)); - } - - @Test - public void cancelDialogShouldCallStopAdvertisingWhenClicked(){ - // interactor.advertising is false by default - Mockito.doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - P2pModeSelectContract.View.DialogCancelCallback dialogCancelCallback = invocation.getArgument(0); - dialogCancelCallback.onCancelClicked(new DialogInterface() { - @Override - public void cancel() { - // Do nothing - } - - @Override - public void dismiss() { - // Do nothing - } - }); - - return null; - } - }).when(view) - .showReceiveProgressDialog(Mockito.any(P2pModeSelectContract.View.DialogCancelCallback.class)); - - - presenter.startAdvertisingMode(); - Mockito.verify(interactor, Mockito.times(1)) - .stopAdvertising(); - } - - @Test - public void cancelDialogShouldCallDialogIDismissWhenClicked(){ - // interactor.advertising is false by default - final DialogInterface dialogInterface = Mockito.mock(DialogInterface.class); - - Mockito.doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - P2pModeSelectContract.View.DialogCancelCallback dialogCancelCallback = invocation.getArgument(0); - dialogCancelCallback.onCancelClicked(dialogInterface); - - return null; - } - }).when(view) - .showReceiveProgressDialog(Mockito.any(P2pModeSelectContract.View.DialogCancelCallback.class)); - - - presenter.startAdvertisingMode(); - Mockito.verify(dialogInterface, Mockito.times(1)) - .dismiss(); - } - - @Test - public void cancelDialogShouldEnableButtonsWhenClicked(){ - // interactor.advertising is false by default - final DialogInterface dialogInterface = Mockito.mock(DialogInterface.class); - - Mockito.doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - P2pModeSelectContract.View.DialogCancelCallback dialogCancelCallback = invocation.getArgument(0); - dialogCancelCallback.onCancelClicked(dialogInterface); - - return null; - } - }).when(view) - .showReceiveProgressDialog(Mockito.any(P2pModeSelectContract.View.DialogCancelCallback.class)); - - - presenter.startAdvertisingMode(); - Mockito.verify(view, Mockito.times(1)) - .enableSendReceiveButtons(true); - } - - @Test - public void prepareAdvertisingShouldRequestPermissionsWhenPermissionsAreNotGranted() { - List unauthorizedPermissions = new ArrayList<>(); - unauthorizedPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION); - - Mockito.doReturn(unauthorizedPermissions) - .when(view) - .getUnauthorisedPermissions(); - - presenter.prepareForAdvertising(false); - - Mockito.verify(view, Mockito.times(1)) - .requestPermissions(unauthorizedPermissions); - Mockito.verify(view, Mockito.times(1)) - .addOnActivityRequestPermissionHandler(Mockito.any(OnActivityRequestPermissionHandler.class)); - } - - @Test - public void prepareAdvertisingShouldCallItselfWhenPermissionsGrantedExplicitlyByUserOnView() { - final ArrayList sensitiveObjects = new ArrayList<>(); - List unauthorizedPermissions = new ArrayList<>(); - unauthorizedPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION); - - Mockito.doReturn(unauthorizedPermissions) - .when(view) - .getUnauthorisedPermissions(); - - Mockito.doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - OnActivityRequestPermissionHandler onActivityRequestPermissionHandler = invocation.getArgument(0); - sensitiveObjects.add(onActivityRequestPermissionHandler); - - onActivityRequestPermissionHandler.handlePermissionResult(new String[]{""}, new int[]{0}); - return null; - } - }).when(view) - .addOnActivityRequestPermissionHandler(Mockito.any(OnActivityRequestPermissionHandler.class)); - - P2pModeSelectContract.Presenter spiedPresenter = Mockito.spy(presenter); - - spiedPresenter.prepareForAdvertising(false); - - Mockito.verify(spiedPresenter, Mockito.times(1)) - .prepareForAdvertising(true); - Mockito.verify(view, Mockito.times(1)) - .removeOnActivityRequestPermissionHandler((OnActivityRequestPermissionHandler) sensitiveObjects.get(0)); - } - - @Test - public void prepareAdvertisingShouldCallStartAdvertisingModeWhenPermissionsAreGrantedAndLocationEnabled() { - List unauthorizedPermissions = new ArrayList<>(); - Mockito.doReturn(unauthorizedPermissions) - .when(view) - .getUnauthorisedPermissions(); - - Mockito.doReturn(true) - .when(view) - .isLocationEnabled(); - - P2pModeSelectContract.Presenter spiedPresenter = Mockito.spy(presenter); - spiedPresenter.prepareForAdvertising(false); - - Mockito.verify(spiedPresenter, Mockito.times(1)) - .startAdvertisingMode(); - } - - @Test - public void prepareAdvertisingShouldRequestLocationEnableWhenPermissionsAreGrantedAndLocationDisabled() { - List unauthorizedPermissions = new ArrayList<>(); - Mockito.doReturn(unauthorizedPermissions) - .when(view) - .getUnauthorisedPermissions(); - - Mockito.doReturn(false) - .when(view) - .isLocationEnabled(); - - presenter.prepareForAdvertising(false); - - Mockito.verify(view, Mockito.times(1)) - .requestEnableLocation(Mockito.any(P2pModeSelectContract.View.OnLocationEnabled.class)); - } - - @Test - public void prepareAdvertisingShouldCallNothingWhenPermissionsAreNotGrantedAndReturnedFromRequestingPermissions() { - List unauthorizedPermissions = new ArrayList<>(); - unauthorizedPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION); - - Mockito.doReturn(unauthorizedPermissions) - .when(view) - .getUnauthorisedPermissions(); - - presenter.prepareForAdvertising(false); - - Mockito.verify(view, Mockito.times(1)) - .requestPermissions(unauthorizedPermissions); - } - - @Test - public void prepareDiscoveringShouldCallStartDiscoveringModeWhenPermissionsGrantedAndLocationEnabled() { - P2pModeSelectContract.Presenter spiedPresenter = Mockito.spy(presenter); - - List unauthorizedPermissions = new ArrayList<>(); - - Mockito.doReturn(unauthorizedPermissions) - .when(view) - .getUnauthorisedPermissions(); - - Mockito.doReturn(true) - .when(view) - .isLocationEnabled(); - - spiedPresenter.prepareForDiscovering(false); - Mockito.verify(spiedPresenter, Mockito.times(1)) - .startDiscoveringMode(); - } - - @Test - public void prepareDiscoveringShouldCallRequestPermissionsWhenPermissionsNotGrantedAndNotReturningFromRequestingPermissions() { - List unauthorizedPermissions = new ArrayList<>(); - unauthorizedPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION); - - Mockito.doReturn(unauthorizedPermissions) - .when(view) - .getUnauthorisedPermissions(); - - presenter.prepareForDiscovering(false); - Mockito.verify(view, Mockito.times(1)) - .requestPermissions(unauthorizedPermissions); - Mockito.verify(view, Mockito.times(1)) - .addOnActivityRequestPermissionHandler(Mockito.any(OnActivityRequestPermissionHandler.class)); - } - - @Test - public void prepareDiscoveringShouldNotCallRequestPermissionsWhenPermissionsNotGrantedAndReturningFromRequestionPermissions() { - List unauthorizedPermissions = new ArrayList<>(); - unauthorizedPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION); - - Mockito.doReturn(unauthorizedPermissions) - .when(view) - .getUnauthorisedPermissions(); - - presenter.prepareForDiscovering(true); - Mockito.verify(view, Mockito.times(0)) - .requestPermissions(unauthorizedPermissions); - } - - @Test - public void prepareDiscoveringShouldRequestEnableLocationWhenPermissionsGrantedAndLocationNotEnabled() { - List unauthorizedPermissions = new ArrayList<>(); - Mockito.doReturn(unauthorizedPermissions) - .when(view) - .getUnauthorisedPermissions(); - - Mockito.doReturn(false) - .when(view) - .isLocationEnabled(); - - presenter.prepareForDiscovering(false); - - Mockito.verify(view, Mockito.times(1)) - .requestEnableLocation(Mockito.any(P2pModeSelectContract.View.OnLocationEnabled.class)); - } - - @Test - public void prepareDiscoveringShouldCallItselfAfterPermissionsGrantedExplicitlyByUserOnView() { - final ArrayList sensitiveObjects = new ArrayList<>(); - List unauthorizedPermissions = new ArrayList<>(); - unauthorizedPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION); - Mockito.doReturn(unauthorizedPermissions) - .when(view) - .getUnauthorisedPermissions(); - - P2pModeSelectContract.Presenter spiedPresenter = Mockito.spy(presenter); - Mockito.doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - OnActivityRequestPermissionHandler onActivityRequestPermissionHandler = invocation.getArgument(0); - sensitiveObjects.add(onActivityRequestPermissionHandler); - onActivityRequestPermissionHandler.handlePermissionResult(new String[] {""}, new int[]{0}); - return null; - } - }).when(view) - .addOnActivityRequestPermissionHandler(Mockito.any(OnActivityRequestPermissionHandler.class)); - - spiedPresenter.prepareForDiscovering(false); - - Mockito.verify(spiedPresenter, Mockito.times(1)) - .prepareForDiscovering(true); - Mockito.verify(view, Mockito.times(1)) - .removeOnActivityRequestPermissionHandler((OnActivityRequestPermissionHandler) sensitiveObjects.get(0)); - } - - -} \ No newline at end of file diff --git a/p2p-sync/src/test/java/org/smartregister/p2p/sync/ReceiverSyncLifecycleCallbackTest.java b/p2p-sync/src/test/java/org/smartregister/p2p/sync/ReceiverSyncLifecycleCallbackTest.java deleted file mode 100644 index c98ab59..0000000 --- a/p2p-sync/src/test/java/org/smartregister/p2p/sync/ReceiverSyncLifecycleCallbackTest.java +++ /dev/null @@ -1,282 +0,0 @@ -package org.smartregister.p2p.sync; - -import android.widget.Toast; - -import com.google.android.gms.nearby.connection.ConnectionInfo; -import com.google.android.gms.nearby.connection.ConnectionResolution; -import com.google.android.gms.nearby.connection.Payload; -import com.google.android.gms.nearby.connection.PayloadCallback; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentMatchers; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.mockito.stubbing.Answer; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.util.ReflectionHelpers; -import org.smartregister.p2p.contract.P2pModeSelectContract; -import org.smartregister.p2p.dialog.QRCodeGeneratorDialog; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -/** - * Created by Ephraim Kigamba - ekigamba@ona.io on 19/03/2019 - */ -@RunWith(RobolectricTestRunner.class) -public class ReceiverSyncLifecycleCallbackTest { - - @Rule - public MockitoRule mockitoRule = MockitoJUnit.rule(); - - @Mock - private P2pModeSelectContract.View view; - @Mock - private P2pModeSelectContract.Presenter presenter; - @Mock - private P2pModeSelectContract.Interactor interactor; - - private ReceiverSyncLifecycleCallback receiverSyncLifecycleCallback; - - @Before - public void setUp() throws Exception { - Mockito.doReturn(RuntimeEnvironment.application) - .when(view) - .getContext(); - - receiverSyncLifecycleCallback = new ReceiverSyncLifecycleCallback(view, presenter, interactor); - } - - @Test - public void onAdvertisingFailedShouldResetUI() { - receiverSyncLifecycleCallback.onAdvertisingFailed(Mockito.mock(Exception.class)); - - Mockito.verify(view, Mockito.times(1)) - .removeReceiveProgressDialog(); - Mockito.verify(view, Mockito.times(1)) - .enableSendReceiveButtons(true); - } - - @Test - public void onConnectionInitiatedShouldDoNothingWhenNoAnotherConnectionIsBeingNegotiated() { - ReflectionHelpers.setField(receiverSyncLifecycleCallback, "currentSender", Mockito.mock(DiscoveredDevice.class)); - assertNotNull(ReflectionHelpers.getField(receiverSyncLifecycleCallback, "currentSender")); - receiverSyncLifecycleCallback.onConnectionInitiated("id", Mockito.mock(ConnectionInfo.class)); - - Mockito.verify(interactor, Mockito.times(0)) - .stopAdvertising(); - - Mockito.verify(view, Mockito.times(0)) - .removeReceiveProgressDialog(); - } - - @Test - public void onConnectionInitiatedShouldStopAdvertisingAndAuthenticateConnectionWhenNoOtherConnectionIsBeingNegotiated() { - ConnectionInfo connectionInfo = Mockito.mock(ConnectionInfo.class); - String authenticationCode = "iowejncCJD"; - String deviceName = "SAMSUNG SM78"; - - Mockito.doReturn(true) - .when(connectionInfo) - .isIncomingConnection(); - - Mockito.doReturn(deviceName) - .when(connectionInfo) - .getEndpointName(); - - Mockito.doReturn(authenticationCode) - .when(connectionInfo) - .getAuthenticationToken(); - - receiverSyncLifecycleCallback.onConnectionInitiated("id", connectionInfo); - assertNotNull(ReflectionHelpers.getField(receiverSyncLifecycleCallback, "currentSender")); - - Mockito.verify(interactor, Mockito.times(1)) - .stopAdvertising(); - - Mockito.verify(view, Mockito.times(1)) - .removeReceiveProgressDialog(); - - Mockito.verify(view, Mockito.times(1)) - .showQRCodeGeneratorDialog(ArgumentMatchers.eq(authenticationCode) - , ArgumentMatchers.eq(deviceName) - , Mockito.any(QRCodeGeneratorDialog.QRCodeAuthenticationCallback.class)); - } - - @Test - public void onConnectionAcceptedShouldRegisterSenderDeviceWithInteractor() { - String endpointId = "id"; - DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); - - Mockito.doReturn(endpointId) - .when(discoveredDevice) - .getEndpointId(); - - ReflectionHelpers.setField(receiverSyncLifecycleCallback, "currentSender", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(receiverSyncLifecycleCallback, "currentSender")); - - - receiverSyncLifecycleCallback.onConnectionAccepted(endpointId, Mockito.mock(ConnectionResolution.class)); - - Mockito.verify(interactor, Mockito.times(1)) - .connectedTo(ArgumentMatchers.eq(endpointId)); - } - - @Test - public void onConnectionRejectedShouldRestartAdvertisingModeAndResetState() { - String endpointId = "id"; - - DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); - - ReflectionHelpers.setField(receiverSyncLifecycleCallback, "currentSender", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(receiverSyncLifecycleCallback, "currentSender")); - - receiverSyncLifecycleCallback.onConnectionRejected(endpointId, Mockito.mock(ConnectionResolution.class)); - - Mockito.verify(presenter, Mockito.times(1)) - .startAdvertisingMode(); - assertNull(ReflectionHelpers.getField(receiverSyncLifecycleCallback, "currentSender")); - } - - @Test - public void onConnectionUnknownErrorShouldRestartAdvertisingAndResetState() { - String endpointId = "id"; - - DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); - - ReflectionHelpers.setField(receiverSyncLifecycleCallback, "currentSender", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(receiverSyncLifecycleCallback, "currentSender")); - - receiverSyncLifecycleCallback.onConnectionUnknownError(endpointId, Mockito.mock(ConnectionResolution.class)); - - Mockito.verify(presenter, Mockito.times(1)) - .startAdvertisingMode(); - assertNull(ReflectionHelpers.getField(receiverSyncLifecycleCallback, "currentSender")); - } - - @Test - public void onConnectionBrokenShouldRestartAdvertisingAndResetState() { - String endpointId = "id"; - - DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); - - ReflectionHelpers.setField(receiverSyncLifecycleCallback, "currentSender", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(receiverSyncLifecycleCallback, "currentSender")); - - receiverSyncLifecycleCallback.onConnectionBroken(endpointId); - - Mockito.verify(presenter, Mockito.times(1)) - .startAdvertisingMode(); - assertNull(ReflectionHelpers.getField(receiverSyncLifecycleCallback, "currentSender")); - } - - @Test - public void onDisconnectedShouldRestartAdvertisingAndResetState() { - String endpointId = "id"; - - DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); - - ReflectionHelpers.setField(receiverSyncLifecycleCallback, "currentSender", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(receiverSyncLifecycleCallback, "currentSender")); - - receiverSyncLifecycleCallback.onDisconnected(endpointId); - - Mockito.verify(presenter, Mockito.times(1)) - .startAdvertisingMode(); - assertNull(ReflectionHelpers.getField(receiverSyncLifecycleCallback, "currentSender")); - } - - @Test - public void onAuthenticationSuccessfulShouldAcceptConnectWhenNegotiatingConnectionWithSender() { - String endpointId = "id"; - DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); - - Mockito.doReturn(endpointId) - .when(discoveredDevice) - .getEndpointId(); - - ReflectionHelpers.setField(receiverSyncLifecycleCallback, "currentSender", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(receiverSyncLifecycleCallback, "currentSender")); - - receiverSyncLifecycleCallback.onAuthenticationSuccessful(); - Mockito.verify(interactor, Mockito.times(1)) - .acceptConnection(ArgumentMatchers.eq(endpointId), Mockito.any(PayloadCallback.class)); - } - - @Test - public void onAuthenticationSuccessfulShouldRegisterCurrentInstanceAsPayloadListener() { - final String endpointId = "id"; - DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); - - Mockito.doReturn(endpointId) - .when(discoveredDevice) - .getEndpointId(); - - ReceiverSyncLifecycleCallback spiedCallback = Mockito.spy(receiverSyncLifecycleCallback); - - ReflectionHelpers.setField(spiedCallback, "currentSender", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(spiedCallback, "currentSender")); - - Mockito.doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - ((PayloadCallback) invocation.getArgument(1)) - .onPayloadReceived(endpointId, Mockito.mock(Payload.class)); - - return null; - } - }) - .when(interactor) - .acceptConnection(ArgumentMatchers.eq(endpointId), Mockito.any(PayloadCallback.class)); - - spiedCallback.onAuthenticationSuccessful(); - Mockito.verify(spiedCallback, Mockito.times(1)) - .onPayloadReceived(ArgumentMatchers.eq(endpointId), Mockito.any(Payload.class)); - } - - @Test - public void onAuthenticationFailedShouldRejectConnectionWhenNegotiatingWithASender() { - final String endpointId = "id"; - DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); - - Mockito.doReturn(endpointId) - .when(discoveredDevice) - .getEndpointId(); - - ReflectionHelpers.setField(receiverSyncLifecycleCallback, "currentSender", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(receiverSyncLifecycleCallback, "currentSender")); - - receiverSyncLifecycleCallback.onAuthenticationFailed(new Exception()); - - Mockito.verify(interactor, Mockito.times(1)) - .rejectConnection(ArgumentMatchers.eq(endpointId)); - Mockito.verify(view, Mockito.times(1)) - .showToast(ArgumentMatchers.eq("Authentication failed! The connection has been rejected") - , ArgumentMatchers.eq(Toast.LENGTH_LONG)); - } - - @Test - public void onAuthenticationCancelledShouldRejectConnectionWhenNegotiatingWithASender() { - final String endpointId = "id"; - DiscoveredDevice discoveredDevice = Mockito.mock(DiscoveredDevice.class); - - Mockito.doReturn(endpointId) - .when(discoveredDevice) - .getEndpointId(); - - ReflectionHelpers.setField(receiverSyncLifecycleCallback, "currentSender", discoveredDevice); - assertNotNull(ReflectionHelpers.getField(receiverSyncLifecycleCallback, "currentSender")); - - receiverSyncLifecycleCallback.onAuthenticationCancelled(""); - - Mockito.verify(interactor, Mockito.times(1)) - .rejectConnection(ArgumentMatchers.eq(endpointId)); - } -} \ No newline at end of file