diff --git a/src/main/java/com/pusher/client/channel/impl/PresenceChannelImpl.java b/src/main/java/com/pusher/client/channel/impl/PresenceChannelImpl.java index f34f0826..230adc88 100644 --- a/src/main/java/com/pusher/client/channel/impl/PresenceChannelImpl.java +++ b/src/main/java/com/pusher/client/channel/impl/PresenceChannelImpl.java @@ -1,6 +1,7 @@ package com.pusher.client.channel.impl; import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; import com.google.gson.annotations.SerializedName; import com.pusher.client.AuthorizationFailureException; import com.pusher.client.Authorizer; @@ -65,35 +66,10 @@ else if (event.equals(MEMBER_REMOVED_EVENT)) { } @Override - @SuppressWarnings("rawtypes") public String toSubscribeMessage() { - - final String authResponse = getAuthResponse(); - - try { - final Map authResponseMap = GSON.fromJson(authResponse, Map.class); - final String authKey = (String)authResponseMap.get("auth"); - final Object channelData = authResponseMap.get("channel_data"); - - storeMyUserId(channelData); - - final Map jsonObject = new LinkedHashMap(); - jsonObject.put("event", "pusher:subscribe"); - - final Map dataMap = new LinkedHashMap(); - dataMap.put("channel", name); - dataMap.put("auth", authKey); - dataMap.put("channel_data", channelData); - - jsonObject.put("data", dataMap); - - final String json = GSON.toJson(jsonObject); - - return json; - } - catch (final Exception e) { - throw new AuthorizationFailureException("Unable to parse response from Authorizer: " + authResponse, e); - } + String msg = super.toSubscribeMessage(); + myUserID = extractUserIdFromChannelData(channelData); + return msg; } @Override @@ -187,9 +163,24 @@ private static PresenceData extractPresenceDataFrom(final String message) { } @SuppressWarnings("rawtypes") - private void storeMyUserId(final Object channelData) { - final Map channelDataMap = GSON.fromJson((String)channelData, Map.class); - myUserID = String.valueOf(channelDataMap.get("user_id")); + private String extractUserIdFromChannelData(final String channelData) { + final Map channelDataMap; + try { + channelDataMap = GSON.fromJson((String)channelData, Map.class); + } catch (final JsonSyntaxException e) { + throw new AuthorizationFailureException("Invalid response from Authorizer: unable to parse channel_data object: " + channelData, e); + } + Object maybeUserId; + try { + maybeUserId = channelDataMap.get("user_id"); + } catch (final NullPointerException e) { + throw new AuthorizationFailureException("Invalid response from Authorizer: no user_id key in channel_data object: " + channelData); + } + if (maybeUserId == null) { + throw new AuthorizationFailureException("Invalid response from Authorizer: no user_id key in channel_data object: " + channelData); + } + // user_id can be a string or an integer in the Channels websocket protocol + return String.valueOf(maybeUserId); } private class MemberData { diff --git a/src/main/java/com/pusher/client/channel/impl/PrivateChannelImpl.java b/src/main/java/com/pusher/client/channel/impl/PrivateChannelImpl.java index 3737c8d7..5260fdf6 100644 --- a/src/main/java/com/pusher/client/channel/impl/PrivateChannelImpl.java +++ b/src/main/java/com/pusher/client/channel/impl/PrivateChannelImpl.java @@ -23,6 +23,8 @@ public class PrivateChannelImpl extends ChannelImpl implements PrivateChannel { private final InternalConnection connection; private final Authorizer authorizer; + protected String channelData; + public PrivateChannelImpl(final InternalConnection connection, final String channelName, final Authorizer authorizer, final Factory factory) { super(channelName, factory); @@ -90,6 +92,7 @@ public String toSubscribeMessage() { try { final Map authResponseMap = GSON.fromJson(authResponse, Map.class); final String authKey = (String)authResponseMap.get("auth"); + channelData = (String)authResponseMap.get("channel_data"); final Map jsonObject = new LinkedHashMap(); jsonObject.put("event", "pusher:subscribe"); @@ -97,6 +100,9 @@ public String toSubscribeMessage() { final Map dataMap = new LinkedHashMap(); dataMap.put("channel", name); dataMap.put("auth", authKey); + if (channelData != null) { + dataMap.put("channel_data", channelData); + } jsonObject.put("data", dataMap); diff --git a/src/test/java/com/pusher/client/channel/impl/PresenceChannelImplTest.java b/src/test/java/com/pusher/client/channel/impl/PresenceChannelImplTest.java index 0c47f737..177e7367 100644 --- a/src/test/java/com/pusher/client/channel/impl/PresenceChannelImplTest.java +++ b/src/test/java/com/pusher/client/channel/impl/PresenceChannelImplTest.java @@ -27,7 +27,7 @@ @RunWith(MockitoJUnitRunner.class) public class PresenceChannelImplTest extends PrivateChannelImplTest { - private static final String AUTH_RESPONSE = "\"auth\":\"a87fe72c6f36272aa4b1:f9db294eae7\",\"channel_data\":\"{\\\"user_id\\\":\\\"51169fc47abac\\\",\\\"user_info\\\":{\\\"name\\\":\\\"Phil Leggetter\\\",\\\"twitter_id\\\":\\\"@leggetter\\\"}}\""; + private static final String AUTH_RESPONSE = "\"auth\":\"a87fe72c6f36272aa4b1:f9db294eae7\",\"channel_data\":\"{\\\"user_id\\\":\\\"5116a4519575b\\\",\\\"user_info\\\":{\\\"name\\\":\\\"Phil Leggetter\\\",\\\"twitter_id\\\":\\\"@leggetter\\\"}}\""; private static final String AUTH_RESPONSE_NUMERIC_ID = "\"auth\":\"a87fe72c6f36272aa4b1:f9db294eae7\",\"channel_data\":\"{\\\"user_id\\\":51169,\\\"user_info\\\":{\\\"name\\\":\\\"Phil Leggetter\\\",\\\"twitter_id\\\":\\\"@leggetter\\\"}}\""; private static final String USER_ID = "5116a4519575b"; @@ -60,6 +60,14 @@ public void testReturnsCorrectSubscribeMessageWhenNumericId() { + AUTH_RESPONSE_NUMERIC_ID + "}}", message); } + @Test + public void testStoresCorrectUser() { + channel.toSubscribeMessage(); + channel.onMessage("pusher_internal:subscription_succeeded", + "{\"event\":\"pusher_internal:subscription_succeeded\",\"data\":\"{\\\"presence\\\":{\\\"count\\\":1,\\\"ids\\\":[\\\"5116a4519575b\\\"],\\\"hash\\\":{\\\"5116a4519575b\\\":{\\\"name\\\":\\\"Phil Leggetter\\\",\\\"twitter_id\\\":\\\"@leggetter\\\"}}}}\",\"channel\":\"presence-myChannel\"}"); + assertEquals(USER_ID, ((PresenceChannelImpl)channel).getMe().getId()); + } + @Override @Test public void testIsSubscribedMethod(){ diff --git a/src/test/java/com/pusher/client/channel/impl/PrivateChannelImplTest.java b/src/test/java/com/pusher/client/channel/impl/PrivateChannelImplTest.java index f3dda768..1bf0e6e7 100644 --- a/src/test/java/com/pusher/client/channel/impl/PrivateChannelImplTest.java +++ b/src/test/java/com/pusher/client/channel/impl/PrivateChannelImplTest.java @@ -21,7 +21,8 @@ @RunWith(MockitoJUnitRunner.class) public class PrivateChannelImplTest extends ChannelImplTest { - private static final String AUTH_TOKEN = "\"auth\":\"a87fe72c6f36272aa4b1:41dce43734b18bb\""; + private static final String AUTH_RESPONSE = "\"auth\":\"a87fe72c6f36272aa4b1:41dce43734b18bb\""; + private static final String AUTH_RESPONSE_WITH_CHANNEL_DATA = "\"auth\":\"a87fe72c6f36272aa4b1:41dce43734b18bb\",\"channel_data\":\"{\\\"user_id\\\":\\\"51169fc47abac\\\"}\""; @Mock protected InternalConnection mockConnection; @@ -32,7 +33,7 @@ public class PrivateChannelImplTest extends ChannelImplTest { @Before public void setUp() { super.setUp(); - when(mockAuthorizer.authorize(eq(getChannelName()), anyString())).thenReturn("{" + AUTH_TOKEN + "}"); + when(mockAuthorizer.authorize(eq(getChannelName()), anyString())).thenReturn("{" + AUTH_RESPONSE + "}"); } @Test @@ -72,7 +73,16 @@ public void testPrivateChannelName() { @Test @Override public void testReturnsCorrectSubscribeMessage() { - assertEquals("{\"event\":\"pusher:subscribe\",\"data\":{\"channel\":\"" + getChannelName() + "\"," + AUTH_TOKEN + assertEquals("{\"event\":\"pusher:subscribe\",\"data\":{\"channel\":\"" + getChannelName() + "\"," + AUTH_RESPONSE + + "}}", channel.toSubscribeMessage()); + } + + @Test + public void testReturnsCorrectSubscribeMessageWithChannelData() { + when(mockAuthorizer.authorize(eq(getChannelName()), anyString())).thenReturn( + "{" + AUTH_RESPONSE_WITH_CHANNEL_DATA + "}"); + + assertEquals("{\"event\":\"pusher:subscribe\",\"data\":{\"channel\":\"" + getChannelName() + "\"," + AUTH_RESPONSE_WITH_CHANNEL_DATA + "}}", channel.toSubscribeMessage()); }