@@ -945,6 +945,9 @@ public void attach_success_callback() {
945945 }
946946 }
947947
948+ /**
949+ * Spec: RTL4g
950+ */
948951 @ Test
949952 public void attach_success_callback_for_channel_in_failed_state () {
950953 AblyRealtime ably = null ;
@@ -1037,6 +1040,7 @@ public void attach_fail_callback() {
10371040 /**
10381041 * When client detaches from a channel successfully after initialized state,
10391042 * verify attach {@code CompletionListener#onSuccess()} gets called.
1043+ * Spec: RTL5a
10401044 */
10411045 @ Test
10421046 public void detach_success_callback_initialized () {
@@ -1069,6 +1073,9 @@ public void detach_success_callback_initialized() {
10691073 }
10701074 }
10711075
1076+ /**
1077+ * Spec: RTL5j
1078+ */
10721079 @ Test
10731080 public void detach_success_callback_on_suspended_state () {
10741081 AblyRealtime ably = null ;
@@ -1106,6 +1113,9 @@ public void detach_success_callback_on_suspended_state() {
11061113 }
11071114 }
11081115
1116+ /**
1117+ * Spec: RTL5b
1118+ */
11091119 @ Test
11101120 public void detach_failure_callback_on_failed_state () {
11111121 AblyRealtime ably = null ;
@@ -1147,6 +1157,79 @@ public void detach_failure_callback_on_failed_state() {
11471157 }
11481158 }
11491159
1160+ /**
1161+ * When connection is in failed or suspended, set error in callback
1162+ * Spec: RTL5g
1163+ */
1164+ @ Test
1165+ public void detach_fail_callback_for_connection_invalid_state () {
1166+ AblyRealtime ably = null ;
1167+ try {
1168+ ClientOptions opts = createOptions (testVars .keys [0 ].keyStr );
1169+ ably = new AblyRealtime (opts );
1170+ ConnectionWaiter connWaiter = new ConnectionWaiter (ably .connection );
1171+
1172+ /* wait until connected */
1173+ connWaiter .waitFor (ConnectionState .connected );
1174+
1175+ /* create a channel and attach */
1176+ final Channel channel = ably .channels .get ("detach_failure" );
1177+ ChannelWaiter channelWaiter = new ChannelWaiter (channel );
1178+ channel .attach ();
1179+ channelWaiter .waitFor (ChannelState .attached );
1180+
1181+ // Simulate connection closing from outside
1182+ ably .connection .connectionManager .requestState (new ConnectionManager .StateIndication (
1183+ ConnectionState .closing ,
1184+ new ErrorInfo ("Connection is closing" , 80001 )
1185+ ));
1186+ /* wait until connection closing */
1187+ connWaiter .waitFor (ConnectionState .closing );
1188+
1189+ // channel state is ATTACHED despite closing connection state
1190+ assertEquals (ChannelState .attached , channel .state );
1191+
1192+ /* detach */
1193+ Helpers .CompletionWaiter detachWaiter1 = new Helpers .CompletionWaiter ();
1194+ channel .detach (detachWaiter1 );
1195+
1196+ /* Verify onSuccess callback gets called */
1197+ detachWaiter1 .waitFor ();
1198+ assertFalse (detachWaiter1 .success );
1199+ assertNotNull (detachWaiter1 .error );
1200+ assertEquals ("Connection is closing" , detachWaiter1 .error .message );
1201+ assertEquals (80001 , detachWaiter1 .error .code );
1202+
1203+ // Simulate connection failure
1204+ ably .connection .connectionManager .requestState (ConnectionState .failed );
1205+ /* wait until connection failed */
1206+ connWaiter .waitFor (ConnectionState .failed );
1207+
1208+ // Mock channel state to ATTACHED despite failed connection state
1209+ channelWaiter .waitFor (ChannelState .failed );
1210+ channel .state = ChannelState .attached ;
1211+ assertEquals (ChannelState .attached , channel .state );
1212+
1213+ /* detach */
1214+ Helpers .CompletionWaiter detachWaiter2 = new Helpers .CompletionWaiter ();
1215+ channel .detach (detachWaiter2 );
1216+
1217+ /* Verify onSuccess callback gets called */
1218+ detachWaiter2 .waitFor ();
1219+ assertFalse (detachWaiter2 .success );
1220+ assertNotNull (detachWaiter2 .error );
1221+ assertEquals ("Connection failed" , detachWaiter2 .error .message );
1222+ assertEquals (80000 , detachWaiter2 .error .code );
1223+
1224+ } catch (AblyException e ) {
1225+ e .printStackTrace ();
1226+ fail ("init0: Unexpected exception instantiating library" );
1227+ } finally {
1228+ if (ably != null )
1229+ ably .close ();
1230+ }
1231+ }
1232+
11501233 /**
11511234 * When client detaches from a channel successfully after attached state,
11521235 * verify attach {@code CompletionListener#onSuccess()} gets called.
@@ -1184,6 +1267,7 @@ public void detach_success_callback_attached() throws AblyException {
11841267 /**
11851268 * When client detaches from a channel successfully after detaching state,
11861269 * verify attach {@code CompletionListener#onSuccess()} gets called.
1270+ * Spec: RTL5i
11871271 */
11881272 @ Test
11891273 public void detach_success_callback_detaching () throws AblyException {
0 commit comments