From 71975c07202821a921f9dc584604d006cdfe9833 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Wed, 16 Oct 2024 12:55:26 +0530 Subject: [PATCH 1/3] Fixed incorrect spec annotations used for channel message subscribe and related tests --- lib/src/main/java/io/ably/lib/realtime/ChannelBase.java | 2 +- lib/src/main/java/io/ably/lib/types/ChannelOptions.java | 2 +- .../java/io/ably/lib/test/realtime/RealtimeChannelTest.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java b/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java index 9a786a602..ce15010cc 100644 --- a/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java +++ b/lib/src/main/java/io/ably/lib/realtime/ChannelBase.java @@ -695,7 +695,7 @@ public synchronized void unsubscribe() { * Checks if {@link io.ably.lib.types.ChannelOptions#attachOnSubscribe} is true. *

* Defaults to {@code true} when {@link io.ably.lib.realtime.ChannelBase#options} is null. - *

Spec: TB4, RTL7g, RTL7gh, RTP6d, RTP6e

+ *

Spec: TB4, RTL7g, RTL7h, RTP6d, RTP6e

*/ protected boolean attachOnSubscribeEnabled() { return options == null || options.attachOnSubscribe; diff --git a/lib/src/main/java/io/ably/lib/types/ChannelOptions.java b/lib/src/main/java/io/ably/lib/types/ChannelOptions.java index 8ee10faf3..bda871c9b 100644 --- a/lib/src/main/java/io/ably/lib/types/ChannelOptions.java +++ b/lib/src/main/java/io/ably/lib/types/ChannelOptions.java @@ -47,7 +47,7 @@ public class ChannelOptions { * should trigger an implicit attach. *

*

Defaults to {@code true}.

- *

Spec: TB4, RTL7g, RTL7gh, RTP6d, RTP6e

+ *

Spec: TB4, RTL7g, RTL7h, RTP6d, RTP6e

*/ public boolean attachOnSubscribe = true; diff --git a/lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java b/lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java index bdeb11921..3279e8c7b 100644 --- a/lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java +++ b/lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java @@ -396,7 +396,7 @@ public void onMessage(Message message) { /** *

* Validates a client can subscribe to messages without implicit channel attach - * Refer Spec TB4, RTL7g, RTL7gh + * Refer Spec TB4, RTL7g, RTL7h *

* @throws AblyException */ From a0354e5d82f4015809e129bc7b103ec6f8899a38 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Wed, 16 Oct 2024 12:56:57 +0530 Subject: [PATCH 2/3] Fixed presence subscribe when attachOnSubscribe=false, updated tests for the same --- .../java/io/ably/lib/realtime/Presence.java | 21 ++++---- .../test/realtime/RealtimePresenceTest.java | 50 +++++++++++++++++-- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/lib/src/main/java/io/ably/lib/realtime/Presence.java b/lib/src/main/java/io/ably/lib/realtime/Presence.java index 504985e98..9a719db69 100644 --- a/lib/src/main/java/io/ably/lib/realtime/Presence.java +++ b/lib/src/main/java/io/ably/lib/realtime/Presence.java @@ -296,27 +296,26 @@ public void unsubscribe() { eventListeners.clear(); } - - /*** - * internal - * - */ - /** - * Implicitly attach channel on subscribe. Throw exception if channel is in failed state - * @param completionListener - * @throws AblyException + * Implicitly attach channel on subscribe. Throw exception if channel is in failed state. + * @param completionListener Registers listener, gets called when ATTACH operation is a success. + * @throws AblyException Throws exception when channel is in failed state. */ private void implicitAttachOnSubscribe(CompletionListener completionListener) throws AblyException { + // RTP6e if (!channel.attachOnSubscribeEnabled()) { if (completionListener != null) { - completionListener.onSuccess(); + String errorString = String.format(Locale.ROOT, + "Channel %s: attachOnSubscribe=false doesn't expect attach completion callback", channel.name); + Log.e(TAG, errorString); + ErrorInfo errorInfo = new ErrorInfo(errorString, 400,40000); + throw AblyException.fromErrorInfo(errorInfo); } return; } if (channel.state == ChannelState.failed) { String errorString = String.format(Locale.ROOT, "Channel %s: subscribe in FAILED channel state", channel.name); - Log.v(TAG, errorString); + Log.e(TAG, errorString); ErrorInfo errorInfo = new ErrorInfo(errorString, 90001); throw AblyException.fromErrorInfo(errorInfo); } diff --git a/lib/src/test/java/io/ably/lib/test/realtime/RealtimePresenceTest.java b/lib/src/test/java/io/ably/lib/test/realtime/RealtimePresenceTest.java index a13fe235f..f7b99c6c3 100644 --- a/lib/src/test/java/io/ably/lib/test/realtime/RealtimePresenceTest.java +++ b/lib/src/test/java/io/ably/lib/test/realtime/RealtimePresenceTest.java @@ -1,5 +1,6 @@ package io.ably.lib.test.realtime; +import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.emptyCollectionOf; import static org.hamcrest.Matchers.equalTo; @@ -1647,15 +1648,12 @@ public void presence_subscribe_without_implicit_attach() { channel.setOptions(chOpts); List receivedPresenceMsg = Collections.synchronizedList(new ArrayList<>()); - CompletionWaiter completionWaiter = new CompletionWaiter(); /* Check for all subscriptions without ATTACHING state */ - channel.presence.subscribe(m -> receivedPresenceMsg.add(true), completionWaiter); - assertEquals(1, completionWaiter.successCount); + channel.presence.subscribe(m -> receivedPresenceMsg.add(true)); assertEquals(ChannelState.initialized, channel.state); - channel.presence.subscribe(Action.enter, m -> receivedPresenceMsg.add(true), completionWaiter); - assertEquals(2, completionWaiter.successCount); + channel.presence.subscribe(Action.enter, m -> receivedPresenceMsg.add(true)); assertEquals(ChannelState.initialized, channel.state); channel.presence.subscribe(EnumSet.of(Action.enter, Action.leave),m -> receivedPresenceMsg.add(true)); @@ -1686,6 +1684,48 @@ public void presence_subscribe_without_implicit_attach() { } } + /** + *

+ * Validates a client can subscribe to presence without implicit channel attach + * Refer Spec TB4, RTP6d, RTP6e + *

+ * @throws AblyException + */ + @Test + public void presence_subscribe_without_implicit_attach_and_completion_listener_throws_exception() { + String ablyChannel = "subscribe_" + testParams.name; + AblyRealtime ably = null; + try { + ClientOptions option1 = createOptions(testVars.keys[0].keyStr); + option1.clientId = "client1"; + ably = new AblyRealtime(option1); + + /* create a channel and set attachOnSubscribe to false */ + final Channel channel = ably.channels.get(ablyChannel); + ChannelOptions chOpts = new ChannelOptions(); + chOpts.attachOnSubscribe = false; + channel.setOptions(chOpts); + + // When completionWaiter passed with attachOnSubscribe=false, throws exception. + CompletionWaiter completionWaiter = new CompletionWaiter(); + try { + channel.presence.subscribe(m -> {}, completionWaiter); + } catch (AblyException e) { + assertEquals(400, e.errorInfo.statusCode); + assertEquals(40000, e.errorInfo.code); + assertThat(e.errorInfo.message, containsString("attachOnSubscribe=false doesn't expect attach completion callback")); + } + assertEquals(ChannelState.initialized, channel.state); + + } catch (AblyException e) { + e.printStackTrace(); + fail("presence_subscribe_without_implicit_attach: Unexpected exception"); + } finally { + if(ably != null) + ably.close(); + } + } + /** *

* Validates a client sending multiple presence updates when the channel is in the attaching From 43f2eaa2a626be909a5f80fc9f159110c3b0c00c Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Thu, 17 Oct 2024 16:04:56 +0530 Subject: [PATCH 3/3] Removed finally block that closes ably client, instead used try with resources --- .../main/java/io/ably/lib/realtime/Presence.java | 2 +- .../lib/test/realtime/RealtimePresenceTest.java | 14 ++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/lib/src/main/java/io/ably/lib/realtime/Presence.java b/lib/src/main/java/io/ably/lib/realtime/Presence.java index 9a719db69..940b1d077 100644 --- a/lib/src/main/java/io/ably/lib/realtime/Presence.java +++ b/lib/src/main/java/io/ably/lib/realtime/Presence.java @@ -305,7 +305,7 @@ private void implicitAttachOnSubscribe(CompletionListener completionListener) th // RTP6e if (!channel.attachOnSubscribeEnabled()) { if (completionListener != null) { - String errorString = String.format(Locale.ROOT, + String errorString = String.format( "Channel %s: attachOnSubscribe=false doesn't expect attach completion callback", channel.name); Log.e(TAG, errorString); ErrorInfo errorInfo = new ErrorInfo(errorString, 400,40000); diff --git a/lib/src/test/java/io/ably/lib/test/realtime/RealtimePresenceTest.java b/lib/src/test/java/io/ably/lib/test/realtime/RealtimePresenceTest.java index f7b99c6c3..dee3e57d2 100644 --- a/lib/src/test/java/io/ably/lib/test/realtime/RealtimePresenceTest.java +++ b/lib/src/test/java/io/ably/lib/test/realtime/RealtimePresenceTest.java @@ -1692,14 +1692,11 @@ public void presence_subscribe_without_implicit_attach() { * @throws AblyException */ @Test - public void presence_subscribe_without_implicit_attach_and_completion_listener_throws_exception() { + public void presence_subscribe_without_implicit_attach_and_completion_listener_throws_exception() throws AblyException { String ablyChannel = "subscribe_" + testParams.name; - AblyRealtime ably = null; - try { - ClientOptions option1 = createOptions(testVars.keys[0].keyStr); - option1.clientId = "client1"; - ably = new AblyRealtime(option1); - + ClientOptions option1 = createOptions(testVars.keys[0].keyStr); + option1.clientId = "client1"; + try (AblyRealtime ably = new AblyRealtime(option1)) { /* create a channel and set attachOnSubscribe to false */ final Channel channel = ably.channels.get(ablyChannel); ChannelOptions chOpts = new ChannelOptions(); @@ -1720,9 +1717,6 @@ public void presence_subscribe_without_implicit_attach_and_completion_listener_t } catch (AblyException e) { e.printStackTrace(); fail("presence_subscribe_without_implicit_attach: Unexpected exception"); - } finally { - if(ably != null) - ably.close(); } }