diff --git a/lib/src/test/java/io/ably/lib/chat/ChatMessagesTest.java b/lib/src/test/java/io/ably/lib/chat/ChatMessagesTest.java new file mode 100644 index 000000000..ce6195f53 --- /dev/null +++ b/lib/src/test/java/io/ably/lib/chat/ChatMessagesTest.java @@ -0,0 +1,84 @@ +package io.ably.lib.chat; + +import com.google.gson.JsonObject; +import io.ably.lib.realtime.AblyRealtime; +import io.ably.lib.realtime.Channel; +import io.ably.lib.realtime.ChannelState; +import io.ably.lib.test.common.Helpers; +import io.ably.lib.test.common.ParameterizedTest; +import io.ably.lib.types.ClientOptions; +import io.ably.lib.types.Message; +import io.ably.lib.types.MessageAction; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +public class ChatMessagesTest extends ParameterizedTest { + /** + * Connect to the service and attach, then subscribe and unsubscribe + */ + @Test + public void test_room_message_is_published() { + String roomId = "1234"; + String channelName = roomId + "::$chat::$chatMessages"; + AblyRealtime ably = null; + try { + ClientOptions opts = createOptions(testVars.keys[7].keyStr); + opts.clientId = "sandbox-client"; + ably = new AblyRealtime(opts); + ChatRoom room = new ChatRoom(roomId, ably); + + /* create a channel and attach */ + final Channel channel = ably.channels.get(channelName); + channel.attach(); + (new Helpers.ChannelWaiter(channel)).waitFor(ChannelState.attached); + + /* subscribe to messages */ + List receivedMsg = new ArrayList<>(); + channel.subscribe(receivedMsg::add); + + // send message to room + ChatRoom.SendMessageParams params = new ChatRoom.SendMessageParams(); + params.text = "hello there"; + JsonObject sendMessageResult = (JsonObject) room.sendMessage(params); + // check sendMessageResult has 2 fields and are not null + Assert.assertEquals(2, sendMessageResult.entrySet().size()); + String resultSerial = sendMessageResult.get("serial").getAsString(); + Assert.assertFalse(resultSerial.isEmpty()); + String resultCreatedAt = sendMessageResult.get("createdAt").getAsString(); + Assert.assertFalse(resultCreatedAt.isEmpty()); + + Exception err = new Helpers.ConditionalWaiter().wait(() -> !receivedMsg.isEmpty(), 10_000); + Assert.assertNull(err); + + Assert.assertEquals(1, receivedMsg.size()); + Message message = receivedMsg.get(0); + + Assert.assertFalse("Message ID should not be empty", message.id.isEmpty()); + Assert.assertEquals("chat.message", message.name); + Assert.assertEquals("sandbox-client", message.clientId); + + JsonObject data = (JsonObject) message.data; + // has two fields "text" and "metadata" + Assert.assertEquals(2, data.entrySet().size()); + Assert.assertEquals("hello there", data.get("text").getAsString()); + Assert.assertTrue(data.get("metadata").isJsonObject()); + + Assert.assertEquals(resultCreatedAt, message.createdAt.toString()); + Assert.assertEquals(resultSerial, message.serial); + Assert.assertEquals(resultSerial, message.version); + + Assert.assertEquals(MessageAction.MESSAGE_CREATE, message.action); + Assert.assertEquals(resultCreatedAt, message.createdAt.toString()); + + } catch (Exception e) { + e.printStackTrace(); + Assert.fail("init0: Unexpected exception instantiating library"); + } finally { + if(ably != null) + ably.close(); + } + } +} diff --git a/lib/src/test/java/io/ably/lib/chat/ChatRoom.java b/lib/src/test/java/io/ably/lib/chat/ChatRoom.java new file mode 100644 index 000000000..8ae006868 --- /dev/null +++ b/lib/src/test/java/io/ably/lib/chat/ChatRoom.java @@ -0,0 +1,62 @@ +package io.ably.lib.chat; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import io.ably.lib.http.HttpCore; +import io.ably.lib.http.HttpUtils; +import io.ably.lib.rest.AblyRest; +import io.ably.lib.types.AblyException; +import io.ably.lib.types.HttpPaginatedResponse; +import io.ably.lib.types.Param; + +import java.util.Arrays; +import java.util.Map; +import java.util.Optional; + +public class ChatRoom { + private final AblyRest ablyRest; + private final String roomId; + + protected ChatRoom(String roomId, AblyRest ablyRest) { + this.roomId = roomId; + this.ablyRest = ablyRest; + } + + public JsonElement sendMessage(SendMessageParams params) throws Exception { + return makeAuthorizedRequest("/chat/v2/rooms/" + roomId + "/messages", "POST", new Gson().toJsonTree(params)) + .orElseThrow(() -> new Exception("Failed to send message")); + } + + public JsonElement updateMessage(String serial, UpdateMessageParams params) throws Exception { + return makeAuthorizedRequest("/chat/v2/rooms/" + roomId + "/messages/" + serial, "PUT", new Gson().toJsonTree(params)) + .orElseThrow(() -> new Exception("Failed to update message")); + } + + public JsonElement deleteMessage(String serial, DeleteMessageParams params) throws Exception { + return makeAuthorizedRequest("/chat/v2/rooms/" + roomId + "/messages/" + serial + "/delete", "POST", new Gson().toJsonTree(params)) + .orElseThrow(() -> new Exception("Failed to delete message")); + } + + public static class SendMessageParams { + public String text; + public JsonElement metadata; + public Map headers; + } + + public static class UpdateMessageParams { + public SendMessageParams message; + public String description; + public JsonElement metadata; + } + + public static class DeleteMessageParams { + public String description; + public JsonElement metadata; + } + + protected Optional makeAuthorizedRequest(String url, String method, JsonElement body) throws AblyException { + HttpCore.RequestBody httpRequestBody = HttpUtils.requestBodyFromGson(body, ablyRest.options.useBinaryProtocol); + HttpPaginatedResponse response = ablyRest.request(method, url, new Param[] { new Param("v", 3) }, httpRequestBody, null); + return Arrays.stream(response.items()).findFirst(); + } +}