2727import org .junit .Before ;
2828import org .junit .Rule ;
2929import org .junit .Test ;
30+ import org .junit .rules .TestName ;
3031import org .junit .runner .RunWith ;
3132import org .restcomm .android .sdk .RCConnection ;
3233import org .restcomm .android .sdk .RCConnectionListener ;
8182 * linearly so that they are easy to read and extend. So even though we could potentially keep Awaitility out and just use a single thread for testing and API
8283 * by adding more logic in the callback, the whole thing would become a mess as we'd have to keep state all over the place
8384 *
84- * Adding/Extending an integration Test
85+ * Adding/Extending an Integration Test
8586 *
8687 * Each integration test needs to do the following (please check deviceInitialize_Valid() test case for more details):
8788 * - Bind to the RCDevice Android Service and wait until it is connected using Awaitility condition variable (i.e. serviceConnected; there is a separate condition variable for each
@@ -149,13 +150,15 @@ public class IntegrationTests extends BroadcastReceiver implements RCDeviceListe
149150 static private final String REST_PORT = "443" ; // "8443";
150151 static private final String REST_RESTCOMM_ACCOUNT_SID = BuildConfig .TEST_RESTCOMM_ACCOUNT_SID ;
151152 static private final String REST_RESTCOMM_AUTH_TOKEN = BuildConfig .TEST_RESTCOMM_AUTH_TOKEN ;
153+ static private final String MESSAGE_TEXT = "Hello there for Android IT" ;
152154
153155
154156
155157 // Condition variables. Even though its a bit messy I'm keeping different for each state, to make sure we 're not messing the states
156158 private boolean deviceInitialized , deviceReleased , serviceConnected , connectionConnected , connectionDisconnected , deviceStartedListening ,
157159 deviceStoppedListening , deviceConnectivityUpdated , connectionConnecting , connectionDigitSent , connectionCancelled ,
158- connectionDeclined , connectionError , connectionLocalVideo , connectionRemoteVideo , messageAcked , connectionArrived ;
160+ connectionDeclined , connectionError , connectionLocalVideo , connectionRemoteVideo , messageAcked , connectionArrived ,
161+ messageArrived ;
159162
160163 private RCDevice .RCDeviceBinder binder ;
161164
@@ -165,6 +168,9 @@ public class IntegrationTests extends BroadcastReceiver implements RCDeviceListe
165168 public GrantPermissionRule mRuntimePermissionRule = GrantPermissionRule .grant (Manifest .permission .RECORD_AUDIO , Manifest .permission .USE_SIP ,
166169 Manifest .permission .CAMERA , Manifest .permission .WRITE_EXTERNAL_STORAGE );
167170
171+ @ Rule
172+ public TestName name = new TestName ();
173+
168174 //@Rule
169175 //public UiThreadTestRule uiThreadTestRule = new UiThreadTestRule();
170176
@@ -201,8 +207,11 @@ public void beforeAction()
201207 connectionRemoteVideo = false ;
202208 messageAcked = false ;
203209 connectionArrived = false ;
210+ messageArrived = false ;
204211
205- IntentFilter filter = new IntentFilter (RCDevice .ACTION_INCOMING_CALL );
212+ IntentFilter filter = new IntentFilter ();
213+ filter .addAction (RCDevice .ACTION_INCOMING_CALL );
214+ filter .addAction (RCDevice .ACTION_INCOMING_MESSAGE );
206215
207216 // register for connectivity related events
208217 InstrumentationRegistry .getTargetContext ().registerReceiver (this , filter ); //, null, new Handler(Looper.myLooper()));
@@ -211,6 +220,7 @@ public void beforeAction()
211220 @ After
212221 public void afterAction ()
213222 {
223+ //Log.e(TAG, "TC Name: " + name.getMethodName());
214224 InstrumentationRegistry .getTargetContext ().unregisterReceiver (this );
215225 }
216226
@@ -279,7 +289,7 @@ public void run() {
279289
280290 await ().atMost (SIGNALING_TIMEOUT , TimeUnit .SECONDS ).until (fieldIn (this ).ofType (boolean .class ).andWithName ("deviceReleased" ), equalTo (true ));
281291 assertThat (((RCDevice )context .get ("device" )).getState ()).isEqualTo (RCDevice .DeviceState .OFFLINE );
282- assertThat (context .get ("status-code" )).isEqualTo (0 );
292+ assertThat (context .get ("status-code" )).isEqualTo (1 );
283293
284294 // Even though we don't use a HandlerThread now and use the Main Looper thread that is separate from the testing thread, let's keep this
285295 // code in case we want to change the threading logic later
@@ -931,6 +941,83 @@ public void run() {
931941 InstrumentationRegistry .getTargetContext ().unbindService (this );
932942 }
933943
944+ @ Test (timeout = TC_TIMEOUT )
945+ public void deviceReceiveMessage_Valid () throws InterruptedException , JSONException
946+ {
947+ InstrumentationRegistry .getTargetContext ().bindService (new Intent (InstrumentationRegistry .getTargetContext (), RCDevice .class ), this , Context .BIND_AUTO_CREATE );
948+
949+ await ().atMost (SIGNALING_TIMEOUT , TimeUnit .SECONDS ).until (fieldIn (this ).ofType (boolean .class ).andWithName ("serviceConnected" ), equalTo (true ));
950+
951+ // Get the reference to the service, or you can call public methods on the binder directly.
952+ final RCDevice device = binder .getService ();
953+
954+ Handler clientHandler = new Handler (Looper .getMainLooper ());
955+
956+ clientHandler .post (new Runnable () {
957+ @ Override
958+ public void run () {
959+ HashMap <String , Object > params = new HashMap <String , Object >();
960+ params .put (RCDevice .ParameterKeys .INTENT_INCOMING_CALL , new Intent (RCDevice .ACTION_INCOMING_CALL , null , InstrumentationRegistry .getTargetContext (), IntegrationTests .class ));
961+ params .put (RCDevice .ParameterKeys .INTENT_INCOMING_MESSAGE , new Intent (RCDevice .ACTION_INCOMING_MESSAGE , null , InstrumentationRegistry .getTargetContext (), IntegrationTests .class ));
962+ params .put (RCDevice .ParameterKeys .SIGNALING_DOMAIN , SERVER_HOST + ":" + SERVER_PORT );
963+ params .put (RCDevice .ParameterKeys .SIGNALING_USERNAME , CLIENT_NAME );
964+ params .put (RCDevice .ParameterKeys .SIGNALING_PASSWORD , CLIENT_PASSWORD );
965+ params .put (RCDevice .ParameterKeys .MEDIA_ICE_URL , ICE_URL );
966+ params .put (RCDevice .ParameterKeys .MEDIA_ICE_USERNAME , ICE_USERNAME );
967+ params .put (RCDevice .ParameterKeys .MEDIA_ICE_PASSWORD , ICE_PASSWORD );
968+ params .put (RCDevice .ParameterKeys .MEDIA_ICE_DOMAIN , ICE_DOMAIN );
969+ params .put (RCDevice .ParameterKeys .MEDIA_TURN_ENABLED , true );
970+ params .put (RCDevice .ParameterKeys .SIGNALING_SECURE_ENABLED , false );
971+ params .put (RCDevice .ParameterKeys .DEBUG_JAIN_DISABLE_CERTIFICATE_VERIFICATION , true );
972+ params .put (RCDevice .ParameterKeys .DEBUG_USE_BROADCASTS_FOR_EVENTS , true );
973+
974+ device .setLogLevel (Log .VERBOSE );
975+
976+ try {
977+ device .initialize (InstrumentationRegistry .getTargetContext (), params , IntegrationTests .this );
978+ } catch (RCException e ) {
979+ Log .e (TAG , "RCDevice Initialization Error: " + e .errorText );
980+ }
981+ }
982+ });
983+ await ().atMost (SIGNALING_TIMEOUT , TimeUnit .SECONDS ).until (fieldIn (this ).ofType (boolean .class ).andWithName ("deviceInitialized" ), equalTo (true ));
984+ assertThat (((RCDevice )context .get ("device" )).getState ()).isEqualTo (RCDevice .DeviceState .READY );
985+ assertThat (context .get ("status-code" )).isEqualTo (0 );
986+
987+ // Now that we are registered, prepare and do REST request towards Restcomm, so that it initialized a call towards us
988+ RequestParams params = new RequestParams ();
989+ params .put ("From" , REST_ORIGINATOR );
990+ params .put ("To" , "client:" + CLIENT_NAME );
991+ params .put ("Url" , "https://" + SERVER_HOST + ":" + REST_PORT + "/restcomm/demos/hello-world.xml" );
992+ params .put ("Body" , MESSAGE_TEXT );
993+ String url = "https://" + REST_RESTCOMM_ACCOUNT_SID + ":" + REST_RESTCOMM_AUTH_TOKEN +
994+ "@" + SERVER_HOST + ":" + REST_PORT + "/restcomm/2012-04-24/Accounts/" + REST_RESTCOMM_ACCOUNT_SID +
995+ "/SMS/Messages" ;
996+
997+ doRestRequest (url , params );
998+
999+ // wait for incoming call from Restcomm, triggered by REST call above
1000+ await ().atMost (REST_TIMEOUT , TimeUnit .SECONDS ).until (fieldIn (this ).ofType (boolean .class ).andWithName ("messageArrived" ), equalTo (true ));
1001+ //assertThat(((String)context.get("message-peer"))).isEqualTo("");
1002+ assertThat (((String )context .get ("message-text" ))).isEqualTo (MESSAGE_TEXT );
1003+
1004+ clientHandler .post (new Runnable () {
1005+ @ Override
1006+ public void run () {
1007+ device .release ();
1008+ }
1009+ });
1010+
1011+ await ().atMost (SIGNALING_TIMEOUT , TimeUnit .SECONDS ).until (fieldIn (this ).ofType (boolean .class ).andWithName ("deviceReleased" ), equalTo (true ));
1012+ assertThat (((RCDevice )context .get ("device" )).getState ()).isEqualTo (RCDevice .DeviceState .OFFLINE );
1013+ assertThat (context .get ("status-code" )).isEqualTo (0 );
1014+
1015+ assertThat (deviceReleased ).isTrue ();
1016+
1017+ InstrumentationRegistry .getTargetContext ().unbindService (this );
1018+ }
1019+
1020+
9341021 /**
9351022 *
9361023 *
@@ -1185,6 +1272,13 @@ public void onReceive(Context context, Intent intent)
11851272 if (intent .getAction ().equals (RCDevice .ACTION_INCOMING_CALL )) {
11861273 connectionArrived = true ;
11871274 }
1275+ if (intent .getAction ().equals (RCDevice .ACTION_INCOMING_MESSAGE )) {
1276+ this .context .clear ();
1277+ this .context .put ("message-peer" , intent .getStringExtra (RCDevice .EXTRA_DID ));
1278+ this .context .put ("message-text" , intent .getStringExtra (RCDevice .EXTRA_MESSAGE_TEXT ));
1279+
1280+ messageArrived = true ;
1281+ }
11881282 }
11891283
11901284
@@ -1231,15 +1325,14 @@ public String verifyMediaStats(String jsonStats) throws JSONException
12311325 }
12321326 */
12331327 } else {
1328+ // For calls originating at RC/MS we cannot verify much because MS currently doesn't support RTCP XR reports,
1329+ // hence getStats() doesn't return anything meaningful. Hence, commenting out for now:
12341330 // ssrc receive stream
1331+ /*
12351332 int bytesReceived = values.getInt("bytesReceived");
12361333 int packetsLost = values.getInt("packetsLost");
12371334 Log.i(TAG, "verifyMediaStats(): bytesReceived: " + bytesReceived);
12381335 Log.i(TAG, "verifyMediaStats(): packetsLost: " + packetsLost);
1239- if (values .getString ("mediaType" ).equals ("audio" )) {
1240- Log .i (TAG , "verifyMediaStats(): audioOutputLevel: " + values .getInt ("audioOutputLevel" ));
1241- }
1242-
12431336 if (bytesReceived <= 0) {
12441337 Log.e(TAG, "Error: bytesReceived: " + bytesReceived);
12451338 return "error: bytes received: " + bytesReceived;
@@ -1248,6 +1341,11 @@ public String verifyMediaStats(String jsonStats) throws JSONException
12481341 Log.e(TAG, "Error: packetsLost: " + packetsLost);
12491342 return "error: packets lost: " + packetsLost;
12501343 }
1344+
1345+ if (values.getString("mediaType").equals("audio")) {
1346+ Log.i(TAG, "verifyMediaStats(): audioOutputLevel: " + values.getInt("audioOutputLevel"));
1347+ }
1348+ */
12511349 }
12521350 }
12531351 }
0 commit comments