From bace7531070075e5f12fcac9f61eb70b7cc2b16b Mon Sep 17 00:00:00 2001 From: "marcin.cebo" Date: Wed, 23 Oct 2024 14:08:47 +0200 Subject: [PATCH] Added customMessageType to Publish, Signal, Subscribe, History, File. --- .../main/java/com/pubnub/api/java/PubNub.kt | 17 +++- .../api/java/endpoints/FetchMessages.java | 2 + .../api/java/endpoints/pubsub/Publish.java | 2 + .../v2/endpoints/pubsub/PublishBuilder.java | 49 +++++++++++ .../v2/endpoints/pubsub/SignalBuilder.java | 17 +++- .../pubnub/api/java/v2/entities/Channel.kt | 6 +- .../integration/HistoryIntegrationTest.java | 10 ++- .../integration/PublishIntegrationTests.java | 41 +++++++++- .../integration/SignalIntegrationTests.java | 10 ++- .../pubnub/api/integration/util/Utils.java | 9 +++ .../pubnub/internal/java/PubNubForJavaImpl.kt | 5 +- .../java/endpoints/FetchMessagesImpl.java | 4 +- .../internal/java/endpoints/HistoryImpl.java | 2 +- .../java/endpoints/pubsub/PublishImpl.java | 4 +- .../java/endpoints/pubsub/SignalImpl.java | 3 +- .../internal/java/v2/entities/ChannelImpl.kt | 4 +- .../config/ktlint/baseline.xml | 4 +- .../kotlin/com/pubnub/api/PubNub.kt | 3 + .../com/pubnub/api/v2/entities/Channel.kt | 7 +- .../pubnub/test/integration/PublishTest.kt | 4 +- .../kotlin/com/pubnub/api/PubNubImpl.kt | 14 ++-- .../api/endpoints/pubsub/Publish.ios.kt | 4 +- .../pubnub/api/endpoints/pubsub/Signal.ios.kt | 4 +- .../pubnub/internal/entities/ChannelImpl.kt | 5 +- .../kotlin/com/pubnub/api/PubNubImpl.kt | 6 +- .../internal/v2/entities/ChannelImpl.kt | 5 +- .../jvmMain/kotlin/com/pubnub/api/PubNub.kt | 13 ++- .../com/pubnub/api/endpoints/FetchMessages.kt | 1 + .../pubnub/api/endpoints/pubsub/Publish.kt | 1 + .../kotlin/com/pubnub/api/PubNub.nonJvm.kt | 6 +- .../models/consumer/history/PNFetchMessage.kt | 1 + .../consumer/history/PNHistoryResult.kt | 1 + .../models/consumer/pubsub/MessageResult.kt | 1 + .../models/consumer/pubsub/PNMessageResult.kt | 1 + .../models/consumer/pubsub/PNSignalResult.kt | 1 + .../pubsub/files/PNFileEventResult.kt | 1 + .../com/pubnub/api/endpoints/pubsub/Signal.kt | 1 + .../config/ktlint/baseline.xml | 73 ++++++++++++++--- .../api/integration/HistoryIntegrationTest.kt | 8 +- .../MessageActionsIntegrationTest.kt | 2 + .../integration/PublishIntegrationTests.kt | 63 +++++++++++++-- .../api/integration/SignalIntegrationTests.kt | 12 ++- .../kotlin/com/pubnub/internal/PubNubImpl.kt | 11 ++- .../endpoints/FetchMessagesEndpoint.kt | 10 ++- .../endpoints/pubsub/PublishEndpoint.kt | 7 ++ .../endpoints/pubsub/SignalEndpoint.kt | 9 +++ .../models/server/SubscribeMessage.kt | 4 +- .../server/history/ServerFetchMessageItem.kt | 2 + .../internal/v2/entities/ChannelImpl.kt | 9 ++- .../workers/SubscribeMessageProcessor.kt | 10 ++- .../history/FetchMessagesCoreEndpointTest.kt | 64 +++++++++++++++ .../history/HistoryCoreEndpointTest.kt | 4 +- .../legacy/endpoints/pubsub/PublishTest.kt | 75 +++++++++++++++++ .../api/legacy/endpoints/pubsub/SignalTest.kt | 39 ++++----- .../contract/history/state/HistoryState.kt | 7 ++ .../pubnub/contract/history/step/WhenSteps.kt | 81 +++++++++++++++++++ .../com/pubnub/contract/publish/WhenSteps.kt | 23 ++++++ .../com/pubnub/contract/signal/WhenSteps.kt | 23 ++++++ .../com/pubnub/contract/step/KeysetStep.kt | 16 ++++ .../com/pubnub/contract/step/ThenSteps.kt | 7 ++ .../eventEngine/step/EventEngineSteps.kt | 29 +++++++ .../suite/history/v2/HistoryMetaTestSuite.kt | 2 +- .../v3/FetchMessagesMetaActionsTestSuite.kt | 2 + .../workers/SubscribeMessageProcessorTest.kt | 30 +++++++ 64 files changed, 789 insertions(+), 102 deletions(-) create mode 100644 pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/history/state/HistoryState.kt create mode 100644 pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/history/step/WhenSteps.kt create mode 100644 pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/publish/WhenSteps.kt create mode 100644 pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/signal/WhenSteps.kt diff --git a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/PubNub.kt b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/PubNub.kt index 18ff6532b..7f14c4bae 100644 --- a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/PubNub.kt +++ b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/PubNub.kt @@ -57,6 +57,7 @@ import com.pubnub.api.java.v2.PNConfiguration import com.pubnub.api.java.v2.callbacks.EventEmitter import com.pubnub.api.java.v2.callbacks.StatusEmitter import com.pubnub.api.java.v2.endpoints.pubsub.PublishBuilder +import com.pubnub.api.java.v2.endpoints.pubsub.SignalBuilder import com.pubnub.api.java.v2.entities.Channel import com.pubnub.api.java.v2.entities.ChannelGroup import com.pubnub.api.java.v2.entities.ChannelMetadata @@ -183,6 +184,10 @@ interface PubNub : EventEmitter, StatusEmitter { * if more than 100 messages meet the timetoken values. * */ + @Deprecated( + level = DeprecationLevel.WARNING, + message = "Use fetchMessages() instead", + ) fun history(): History /** @@ -319,6 +324,11 @@ interface PubNub : EventEmitter, StatusEmitter { * The message argument can contain any JSON serializable data, including: Objects, Arrays, Integers and Strings. * Data should not contain special Java/Kotlin classes or functions as these will not serialize. * String content can include any single-byte or multi-byte UTF-8 character. + * + * @param message The payload + * @param channel The channel to publish message to. + * + * @return [PublishBuilder] */ fun publish(message: Any, channel: String): PublishBuilder @@ -360,8 +370,13 @@ interface PubNub : EventEmitter, StatusEmitter { * By default, signals are limited to a message payload size of 30 bytes. * This limit applies only to the payload, and not to the URI or headers. * If you require a larger payload size, please [contact support](mailto:support@pubnub.com). + * + * @param message The payload + * @param channel The channel to signal message to. + * + * @return [SignalBuilder] */ - fun signal(message: Any, channel: String): com.pubnub.api.endpoints.pubsub.Signal + fun signal(message: Any, channel: String): SignalBuilder /** * Send a signal to all subscribers of a channel. diff --git a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/endpoints/FetchMessages.java b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/endpoints/FetchMessages.java index a577a20c4..bded0ec68 100644 --- a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/endpoints/FetchMessages.java +++ b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/endpoints/FetchMessages.java @@ -18,4 +18,6 @@ public interface FetchMessages extends Endpoint { FetchMessages includeMessageType(boolean includeMessageType); FetchMessages includeUUID(boolean includeUUID); + + FetchMessages includeCustomMessageType(boolean includeCustomMessageType); } diff --git a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/endpoints/pubsub/Publish.java b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/endpoints/pubsub/Publish.java index cbd0fafec..fcb9f5e66 100644 --- a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/endpoints/pubsub/Publish.java +++ b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/endpoints/pubsub/Publish.java @@ -17,4 +17,6 @@ public interface Publish extends Endpoint { Publish replicate(boolean replicate); Publish ttl(Integer ttl); + + Publish customMessageType(String type); } diff --git a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/endpoints/pubsub/PublishBuilder.java b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/endpoints/pubsub/PublishBuilder.java index 92c13dac2..4fb3670ea 100644 --- a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/endpoints/pubsub/PublishBuilder.java +++ b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/endpoints/pubsub/PublishBuilder.java @@ -3,14 +3,63 @@ import com.pubnub.api.java.endpoints.Endpoint; import com.pubnub.api.models.consumer.PNPublishResult; +/** + * Interface representing a builder for configuring a publish operation. + * This interface extends {@link Endpoint} to provide a fluent API for setting various parameters + * for the publish request. + */ public interface PublishBuilder extends Endpoint { + /** + * Specifies whether the message should be stored in the history of the channel. + * + * @param shouldStore Boolean indicating whether to store the message (true) or not (false). If not specified, then the history configuration of the key is used. + * @return The current instance of {@code PublishBuilder} for method chaining. + */ PublishBuilder shouldStore(Boolean shouldStore); + /** + * Configures the publish request to use the POST HTTP method instead of GET. + * + * @param usePOST Boolean indicating whether to use POST (true) or GET (false) for the request. Default is `false` + * @return The current instance of {@code PublishBuilder} for method chaining. + */ PublishBuilder usePOST(boolean usePOST); + /** + * Sets the metadata to be sent along with the message. + * Metadata can be any custom object. + * + * @param meta Metadata object which can be used with the filtering ability. + * @return The current instance of {@code PublishBuilder} for method chaining. + */ PublishBuilder meta(Object meta); + + /** + * Specifies whether the message should be replicated across datacenters. + * + * @param replicate Boolean indicating whether to replicate the message (true) or not (false). Default is true. + * @return The current instance of {@code PublishBuilder} for method chaining. + */ PublishBuilder replicate(boolean replicate); + /** + * Sets the time-to-live (TTL) in Message Persistence. + * If shouldStore = true, and ttl = 0, the message is stored with no expiry time. + * If shouldStore = true and ttl = X (X is an Integer value), the message is stored with an expiry time of X hours. + * If shouldStore = false, the ttl parameter is ignored. + * If ttl is not specified, then expiration of the message defaults back to the expiry value for the key. + * + * @param ttl The TTL value in minutes for the message. + * @return The current instance of {@code PublishBuilder} for method chaining. + */ PublishBuilder ttl(Integer ttl); + + /** + * Specifies a custom message type for the message. + * + * @param customMessageType The custom message type as a string. + * @return The current instance of {@code PublishBuilder} for method chaining. + */ + PublishBuilder customMessageType(String customMessageType); } diff --git a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/endpoints/pubsub/SignalBuilder.java b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/endpoints/pubsub/SignalBuilder.java index 321ef9edd..962d09e91 100644 --- a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/endpoints/pubsub/SignalBuilder.java +++ b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/endpoints/pubsub/SignalBuilder.java @@ -1,6 +1,19 @@ package com.pubnub.api.java.v2.endpoints.pubsub; -import com.pubnub.api.java.endpoints.pubsub.Signal; +import com.pubnub.api.java.endpoints.Endpoint; +import com.pubnub.api.models.consumer.PNPublishResult; -public interface SignalBuilder extends Signal { +/** + * Interface representing a builder for configuring a signal operation. + * This interface extends {@link Endpoint} to provide a fluent API for setting parameters + * for the signal request. + */ +public interface SignalBuilder extends Endpoint { + /** + * Specifies a custom message type for the signal. + * + * @param customMessageType The custom message type as a string. + * @return The current instance of {@code SignalBuilder} for method chaining. + */ + SignalBuilder customMessageType(String customMessageType); } diff --git a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/entities/Channel.kt b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/entities/Channel.kt index 12055d8cf..5e2c44ca5 100644 --- a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/entities/Channel.kt +++ b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/entities/Channel.kt @@ -1,7 +1,7 @@ package com.pubnub.api.java.v2.entities -import com.pubnub.api.endpoints.pubsub.Signal import com.pubnub.api.java.v2.endpoints.pubsub.PublishBuilder +import com.pubnub.api.java.v2.endpoints.pubsub.SignalBuilder import com.pubnub.api.java.v2.subscriptions.Subscription import com.pubnub.api.v2.subscriptions.SubscriptionOptions @@ -90,6 +90,7 @@ interface Channel : Subscribable { * - If `shouldStore = false`, the `ttl` parameter is ignored. * - If ttl isn't specified, then expiration of the message defaults * back to the expiry value for the key. + * @param customMessageType The custom type associated with the message. */ fun publish(message: Any): PublishBuilder @@ -101,8 +102,9 @@ interface Channel : Subscribable { * If you require a larger payload size, please [contact support](mailto:support@pubnub.com). * * @param message The payload which will be serialized and sent. + * @param customMessageType The custom type associated with the message. */ - fun signal(message: Any): Signal + fun signal(message: Any): SignalBuilder /** * Send a message to PubNub Functions Event Handlers. diff --git a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/HistoryIntegrationTest.java b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/HistoryIntegrationTest.java index fcfbd9d4b..4d1619c9e 100644 --- a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/HistoryIntegrationTest.java +++ b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/HistoryIntegrationTest.java @@ -121,12 +121,14 @@ public void testHistorySingleChannel_Meta_Timetoken() throws PubNubException { @Test public void testFetchSingleChannel() throws PubNubException { final String expectedChannelName = random(); + final String customMessageType = "myType_" + random(); - publishMixed(pubNub, 10, expectedChannelName); + publishMixed(pubNub, 10, expectedChannelName, customMessageType); final PNFetchMessagesResult fetchMessagesResult = pubNub.fetchMessages() .channels(Collections.singletonList(expectedChannelName)) .maximumPerChannel(25) + .includeCustomMessageType(true) .sync(); pause(3); @@ -137,6 +139,7 @@ public void testFetchSingleChannel() throws PubNubException { assertNotNull(messageItem.getTimetoken()); assertNull(messageItem.getMeta()); assertNull(messageItem.getActions()); + assertEquals(customMessageType, messageItem.getCustomMessageType()); } } @@ -168,8 +171,9 @@ public void testFetchSingleChannel_Meta() throws PubNubException { @Test public void testFetchSingleChannel_Actions() throws PubNubException { final String expectedChannelName = random(); + final String customMessageType = "myType_" + random(); - final List results = publishMixed(pubNub, 120, expectedChannelName); + final List results = publishMixed(pubNub, 120, expectedChannelName, customMessageType); pubNub.addMessageAction() .channel(expectedChannelName) @@ -184,6 +188,7 @@ public void testFetchSingleChannel_Actions() throws PubNubException { .maximumPerChannel(25) .includeMessageActions(true) .includeMeta(false) + .includeCustomMessageType(true) .sync(); assert fetchMessagesResult != null; @@ -196,6 +201,7 @@ public void testFetchSingleChannel_Actions() throws PubNubException { } else { assertTrue(messageItem.getActions().isEmpty()); } + assertEquals(customMessageType, messageItem.getCustomMessageType()); } } diff --git a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/PublishIntegrationTests.java b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/PublishIntegrationTests.java index b79524f62..3e061d096 100644 --- a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/PublishIntegrationTests.java +++ b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/PublishIntegrationTests.java @@ -12,6 +12,7 @@ import com.pubnub.api.java.callbacks.SubscribeCallback; import com.pubnub.api.java.v2.PNConfiguration; import com.pubnub.api.java.v2.PNConfigurationOverride; +import com.pubnub.api.java.v2.callbacks.StatusListener; import com.pubnub.api.java.v2.entities.Channel; import com.pubnub.api.java.v2.subscriptions.Subscription; import com.pubnub.api.models.consumer.PNPublishResult; @@ -31,6 +32,11 @@ import org.junit.Test; import java.util.Collections; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -58,8 +64,9 @@ public void testPublishMessage() throws PubNubException { final AtomicBoolean success = new AtomicBoolean(); final String expectedChannel = randomChannel(); final JsonObject messagePayload = generateMessage(pubNub); + final String customMessageType = "myType"; - pubNub.publish(messagePayload, expectedChannel).shouldStore(true).usePOST(true).async((result) -> { + pubNub.publish(messagePayload, expectedChannel).shouldStore(true).usePOST(true).customMessageType(customMessageType).async((result) -> { assertFalse(result.isFailure()); success.set(true); }); @@ -70,6 +77,7 @@ public void testPublishMessage() throws PubNubException { pubNub.publish() .message(messagePayload) .channel(expectedChannel) + .customMessageType(customMessageType) .async((result) -> { assertFalse(result.isFailure()); success.set(true); @@ -702,4 +710,35 @@ public void message(@NotNull PubNub pubnub, @NotNull PNMessageResult pnMessageRe .with() .untilAtomic(count, IsEqual.equalTo(2)); } + + @Test + public void testPublishMessageWithCustomMessageType() throws InterruptedException, ExecutionException, TimeoutException, PubNubException { + String expectedChannelName = randomChannel(); + Channel channel = pubNub.channel(expectedChannelName); + String expectedCustomMessageType = "thisIsType"; + CountDownLatch connected = new CountDownLatch(1); + CompletableFuture receivedMessageFuture = new CompletableFuture(); + + Subscription subscription = channel.subscription(); + subscription.setOnMessage(pnMessageResult -> receivedMessageFuture.complete(pnMessageResult)); + pubNub.addListener(new StatusListener() { + @Override + public void status(@NotNull PubNub pubnub, @NotNull PNStatus status) { + if (status.getCategory() == PNStatusCategory.PNConnectedCategory && + status.getAffectedChannels().contains(expectedChannelName) + ) { + connected.countDown(); + } + } + }); + + subscription.subscribe(); + assertTrue(connected.await(10, TimeUnit.SECONDS)); + + channel.publish("message").customMessageType(expectedCustomMessageType).sync(); + + PNMessageResult message = (PNMessageResult) receivedMessageFuture.get(10, TimeUnit.SECONDS); + + assertEquals(expectedCustomMessageType, message.getCustomMessageType()); + } } diff --git a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/SignalIntegrationTests.java b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/SignalIntegrationTests.java index 07ec64262..4ad3af1cd 100644 --- a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/SignalIntegrationTests.java +++ b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/SignalIntegrationTests.java @@ -56,8 +56,9 @@ public void testPublishSignalMessageAsync() { public void testPublishSignalMessageSync() throws PubNubException { final String expectedChannel = randomChannel(); final String expectedPayload = RandomGenerator.newValue(5); + final String customMessageType = "mytype"; - final PNPublishResult signalResult = pubNub.signal(expectedPayload, expectedChannel).sync(); + final PNPublishResult signalResult = pubNub.signal(expectedPayload, expectedChannel).customMessageType(customMessageType).sync(); assertNotNull(signalResult); } @@ -68,6 +69,7 @@ public void testReceiveSignalMessage() { final String expectedChannel = randomChannel(); final String expectedPayload = RandomGenerator.newValue(5); + final String expectedCustomMessageType = "myCustomType"; final com.pubnub.api.java.PubNub observerClient = getPubNub(); @@ -78,9 +80,8 @@ public void testReceiveSignalMessage() { public void status(@NotNull com.pubnub.api.java.PubNub pubnub, @NotNull PNStatus status) { if (status.getCategory() == PNStatusCategory.PNConnectedCategory) { if (status.getAffectedChannels().contains(expectedChannel)) { - pubNub.signal() - .message(expectedPayload) - .channel(expectedChannel) + pubNub.signal(expectedPayload, expectedChannel) + .customMessageType(expectedCustomMessageType) .async((result) -> { assertFalse(result.isFailure()); assertNotNull(result); @@ -94,6 +95,7 @@ public void signal(@NotNull com.pubnub.api.java.PubNub pubnub, @NotNull PNSignal assertEquals(pubNub.getConfiguration().getUserId().getValue(), signal.getPublisher()); assertEquals(expectedChannel, signal.getChannel()); assertEquals(expectedPayload, new Gson().fromJson(signal.getMessage(), String.class)); + assertEquals(expectedCustomMessageType, signal.getCustomMessageType()); success.set(true); } }); diff --git a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/util/Utils.java b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/util/Utils.java index 510b12d5a..c8e185e7c 100644 --- a/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/util/Utils.java +++ b/pubnub-gson/pubnub-gson-impl/src/integrationTest/java/com/pubnub/api/integration/util/Utils.java @@ -63,12 +63,21 @@ public static String randomChannel() { // } public static List publishMixed(PubNub pubnub, int count, String channel) { + String customMessageType = null; + return publishMixed(pubnub, count, channel, customMessageType); + } + + public static List publishMixed(PubNub pubnub, int count, String channel, String customMessageType) { final List list = new ArrayList<>(); for (int i = 0; i < count; i++) { final Publish publishBuilder = pubnub.publish() .channel(channel) .message(String.valueOf(i).concat("_msg")) .shouldStore(true); + if(customMessageType != null){ + publishBuilder.customMessageType(customMessageType); + } + if (i % 2 == 0) { publishBuilder.meta(generateMap()); } else if (i % 3 == 0) { diff --git a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/PubNubForJavaImpl.kt b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/PubNubForJavaImpl.kt index 099af69c5..1dbd6e9d2 100644 --- a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/PubNubForJavaImpl.kt +++ b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/PubNubForJavaImpl.kt @@ -57,6 +57,7 @@ import com.pubnub.api.java.v2.PNConfiguration import com.pubnub.api.java.v2.callbacks.EventListener import com.pubnub.api.java.v2.callbacks.StatusListener import com.pubnub.api.java.v2.endpoints.pubsub.PublishBuilder +import com.pubnub.api.java.v2.endpoints.pubsub.SignalBuilder import com.pubnub.internal.PubNubImpl import com.pubnub.internal.java.builder.PresenceBuilderImpl import com.pubnub.internal.java.builder.SubscribeBuilderImpl @@ -218,8 +219,8 @@ open class PubNubForJavaImpl(configuration: PNConfiguration) : return SignalImpl(this) } - override fun signal(message: Any, channel: String): com.pubnub.api.endpoints.pubsub.Signal { - return super.signal(channel, message) + override fun signal(message: Any, channel: String): SignalBuilder { + return SignalImpl(this).message(message).channel(channel) as SignalBuilder } override fun listChannelsForChannelGroup(): AllChannelsChannelGroup { diff --git a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/FetchMessagesImpl.java b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/FetchMessagesImpl.java index a82bf9319..254a96c00 100644 --- a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/FetchMessagesImpl.java +++ b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/FetchMessagesImpl.java @@ -35,6 +35,7 @@ public class FetchMessagesImpl extends PassthroughEndpoint createRemoteAction() { includeUUID, includeMeta, includeMessageActions, - includeMessageType + includeMessageType, + includeCustomMessageType ); } diff --git a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/HistoryImpl.java b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/HistoryImpl.java index 9d1147460..304b0c318 100644 --- a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/HistoryImpl.java +++ b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/HistoryImpl.java @@ -29,7 +29,7 @@ public HistoryImpl(PubNub pubnub) { @Override @NotNull protected Endpoint createRemoteAction() { - return pubnub.history(channel, start, end, count, reverse, includeTimetoken, includeMeta); + return pubnub.history(channel, start, end, count, reverse, includeTimetoken, includeMeta, false); } @Override diff --git a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/pubsub/PublishImpl.java b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/pubsub/PublishImpl.java index 8b9062c56..976d005d4 100644 --- a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/pubsub/PublishImpl.java +++ b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/pubsub/PublishImpl.java @@ -23,6 +23,7 @@ public class PublishImpl extends PassthroughEndpoint implements private Object meta; private boolean replicate; private Integer ttl; + private String customMessageType; public PublishImpl(PubNub pubnub) { super(pubnub); @@ -39,7 +40,8 @@ protected Endpoint createRemoteAction() { shouldStore, usePOST, replicate, - ttl + ttl, + customMessageType ); } diff --git a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/pubsub/SignalImpl.java b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/pubsub/SignalImpl.java index b7030eb59..e48eb8fd9 100644 --- a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/pubsub/SignalImpl.java +++ b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/pubsub/SignalImpl.java @@ -18,6 +18,7 @@ public class SignalImpl extends PassthroughEndpoint implements private Object message; private String channel; + private String customMessageType; public SignalImpl(PubNub pubnub) { super(pubnub); @@ -26,7 +27,7 @@ public SignalImpl(PubNub pubnub) { @Override @NotNull protected Endpoint createRemoteAction() { - return pubnub.signal(channel, message); + return pubnub.signal(channel, message, customMessageType); } @Override diff --git a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/v2/entities/ChannelImpl.kt b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/v2/entities/ChannelImpl.kt index e16b2138b..f9ab72f85 100644 --- a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/v2/entities/ChannelImpl.kt +++ b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/v2/entities/ChannelImpl.kt @@ -1,7 +1,7 @@ package com.pubnub.internal.java.v2.entities -import com.pubnub.api.endpoints.pubsub.Signal import com.pubnub.api.java.v2.endpoints.pubsub.PublishBuilder +import com.pubnub.api.java.v2.endpoints.pubsub.SignalBuilder import com.pubnub.api.v2.subscriptions.EmptyOptions import com.pubnub.api.v2.subscriptions.SubscriptionOptions import com.pubnub.internal.java.PubNubForJavaImpl @@ -23,7 +23,7 @@ class ChannelImpl(private val pubnub: PubNubForJavaImpl, channelName: ChannelNam return pubnub.publish(message, name) } - override fun signal(message: Any): Signal { + override fun signal(message: Any): SignalBuilder { return pubnub.signal(message, name) } diff --git a/pubnub-kotlin/pubnub-kotlin-api/config/ktlint/baseline.xml b/pubnub-kotlin/pubnub-kotlin-api/config/ktlint/baseline.xml index 050a1e3d8..70bca35fe 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/config/ktlint/baseline.xml +++ b/pubnub-kotlin/pubnub-kotlin-api/config/ktlint/baseline.xml @@ -75,7 +75,7 @@ - - + + diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/commonMain/kotlin/com/pubnub/api/PubNub.kt b/pubnub-kotlin/pubnub-kotlin-api/src/commonMain/kotlin/com/pubnub/api/PubNub.kt index 9cc4de4e1..81ebb09cf 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/commonMain/kotlin/com/pubnub/api/PubNub.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/commonMain/kotlin/com/pubnub/api/PubNub.kt @@ -93,6 +93,7 @@ expect interface PubNub { usePost: Boolean = false, replicate: Boolean = true, ttl: Int? = null, + customMessageType: String? = null, ): Publish fun fire( @@ -105,6 +106,7 @@ expect interface PubNub { fun signal( channel: String, message: Any, + customMessageType: String? = null, ): Signal fun getSubscribedChannels(): List @@ -148,6 +150,7 @@ expect interface PubNub { includeMeta: Boolean = false, includeMessageActions: Boolean = false, includeMessageType: Boolean = true, + includeCustomMessageType: Boolean = false ): FetchMessages fun deleteMessages( diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/commonMain/kotlin/com/pubnub/api/v2/entities/Channel.kt b/pubnub-kotlin/pubnub-kotlin-api/src/commonMain/kotlin/com/pubnub/api/v2/entities/Channel.kt index 82762f387..81e477d27 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/commonMain/kotlin/com/pubnub/api/v2/entities/Channel.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/commonMain/kotlin/com/pubnub/api/v2/entities/Channel.kt @@ -83,6 +83,7 @@ interface Channel : Subscribable { * - If `shouldStore = false`, the `ttl` parameter is ignored. * - If ttl isn't specified, then expiration of the message defaults * back to the expiry value for the key. + * @param customMessageType The custom type associated with the message. */ fun publish( message: Any, @@ -90,7 +91,8 @@ interface Channel : Subscribable { shouldStore: Boolean = true, usePost: Boolean = false, replicate: Boolean = true, - ttl: Int? = null + ttl: Int? = null, + customMessageType: String? = null ): Publish /** @@ -101,8 +103,9 @@ interface Channel : Subscribable { * If you require a larger payload size, please [contact support](mailto:support@pubnub.com). * * @param message The payload which will be serialized and sent. + * @param customMessageType The custom type associated with the message. */ - fun signal(message: Any): Signal + fun signal(message: Any, customMessageType: String? = null): Signal /** * Send a message to PubNub Functions Event Handlers. diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/PublishTest.kt b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/PublishTest.kt index 495e90ebb..8ece7e07b 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/PublishTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/PublishTest.kt @@ -32,14 +32,14 @@ class PublishTest : BaseIntegrationTest() { @Test fun can_publish_message_string() = runTest { - val result = pubnub.publish(channel, "some message").await() + val result = pubnub.publish(channel = channel, message = "some message", customMessageType = "myCustomType").await() assertTrue { result.timetoken > 0 } } @Test fun can_signal() = runTest { - val result = pubnub.signal(channel, "some message").await() + val result = pubnub.signal(channel = channel, message = "some message", customMessageType = "myCustomType").await() assertTrue { result.timetoken > 0 } } diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/iosMain/kotlin/com/pubnub/api/PubNubImpl.kt b/pubnub-kotlin/pubnub-kotlin-api/src/iosMain/kotlin/com/pubnub/api/PubNubImpl.kt index 65815b093..d46d63c75 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/iosMain/kotlin/com/pubnub/api/PubNubImpl.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/iosMain/kotlin/com/pubnub/api/PubNubImpl.kt @@ -195,7 +195,8 @@ class PubNubImpl(private val pubNubObjC: KMPPubNub) : PubNub { shouldStore: Boolean?, usePost: Boolean, replicate: Boolean, - ttl: Int? + ttl: Int?, + customMessageType: String?, ): Publish { return PublishImpl( pubnub = pubNubObjC, @@ -203,7 +204,8 @@ class PubNubImpl(private val pubNubObjC: KMPPubNub) : PubNub { message = message, meta = meta, shouldStore = shouldStore, - ttl = ttl + ttl = ttl, + customMessageType = customMessageType ) } @@ -215,15 +217,17 @@ class PubNubImpl(private val pubNubObjC: KMPPubNub) : PubNub { message = message, meta = meta, shouldStore = false, - ttl = 0 + ttl = 0, + customMessageType = null ) } - override fun signal(channel: String, message: Any): Signal { + override fun signal(channel: String, message: Any, customMessageType: String?): Signal { return SignalImpl( pubnub = pubNubObjC, channel = channel, - message = message + message = message, + customMessageType = customMessageType ) } diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/iosMain/kotlin/com/pubnub/api/endpoints/pubsub/Publish.ios.kt b/pubnub-kotlin/pubnub-kotlin-api/src/iosMain/kotlin/com/pubnub/api/endpoints/pubsub/Publish.ios.kt index 468d91acd..dde9772bd 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/iosMain/kotlin/com/pubnub/api/endpoints/pubsub/Publish.ios.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/iosMain/kotlin/com/pubnub/api/endpoints/pubsub/Publish.ios.kt @@ -23,7 +23,8 @@ class PublishImpl( private val message: Any, private val meta: Any?, private val shouldStore: Boolean?, - private val ttl: Int? + private val ttl: Int?, + private val customMessageType: String? ) : Publish { override fun async(callback: Consumer>) { pubnub.publishWithChannel( @@ -32,6 +33,7 @@ class PublishImpl( meta = meta, shouldStore = shouldStore?.let { NSNumber(bool = it) }, ttl = ttl?.let { NSNumber(it) }, +// customMessageType = customMessageType, // todo, ask Kuba onSuccess = callback.onSuccessHandler { PNPublishResult(it.toLong()) }, onFailure = callback.onFailureHandler() ) diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/iosMain/kotlin/com/pubnub/api/endpoints/pubsub/Signal.ios.kt b/pubnub-kotlin/pubnub-kotlin-api/src/iosMain/kotlin/com/pubnub/api/endpoints/pubsub/Signal.ios.kt index 2ee512318..eb889bf36 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/iosMain/kotlin/com/pubnub/api/endpoints/pubsub/Signal.ios.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/iosMain/kotlin/com/pubnub/api/endpoints/pubsub/Signal.ios.kt @@ -13,12 +13,14 @@ import kotlinx.cinterop.ExperimentalForeignApi class SignalImpl( private val pubnub: KMPPubNub, private val channel: String, - private val message: Any + private val message: Any, + private val customMessageType: String?, ) : Signal { override fun async(callback: Consumer>) { pubnub.signalWithChannel( channel = channel, message = message, +// customeMessageType = customMessageType, //todo, ask Kuba onSuccess = callback.onSuccessHandler { PNPublishResult(it.toLong()) }, onFailure = callback.onFailureHandler() ) diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/iosMain/kotlin/com/pubnub/internal/entities/ChannelImpl.kt b/pubnub-kotlin/pubnub-kotlin-api/src/iosMain/kotlin/com/pubnub/internal/entities/ChannelImpl.kt index 59fe410f5..d15225810 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/iosMain/kotlin/com/pubnub/internal/entities/ChannelImpl.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/iosMain/kotlin/com/pubnub/internal/entities/ChannelImpl.kt @@ -24,12 +24,13 @@ class ChannelImpl( shouldStore: Boolean, usePost: Boolean, replicate: Boolean, - ttl: Int? + ttl: Int?, + customMessageType: String? ): Publish { TODO("Not yet implemented") } - override fun signal(message: Any): Signal { + override fun signal(message: Any, customMessageType: String?): Signal { TODO("Not yet implemented") } diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/jsMain/kotlin/com/pubnub/api/PubNubImpl.kt b/pubnub-kotlin/pubnub-kotlin-api/src/jsMain/kotlin/com/pubnub/api/PubNubImpl.kt index 475fea430..6c68bf6ba 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/jsMain/kotlin/com/pubnub/api/PubNubImpl.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/jsMain/kotlin/com/pubnub/api/PubNubImpl.kt @@ -173,7 +173,8 @@ class PubNubImpl(private val jsPubNub: PubNubJs) : PubNub { shouldStore: Boolean?, usePost: Boolean, replicate: Boolean, - ttl: Int? + ttl: Int?, + customMessageType: String?, ): Publish { return PublishImpl( jsPubNub, @@ -200,12 +201,13 @@ class PubNubImpl(private val jsPubNub: PubNubJs) : PubNub { ) } - override fun signal(channel: String, message: Any): Signal { + override fun signal(channel: String, message: Any, customMessageType: String?): Signal { return SignalImpl( jsPubNub, createJsObject { this.message = message.adjustCollectionTypes() this.channel = channel +// this.customMessageType = customMessageType // todo } ) } diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/jsMain/kotlin/com/pubnub/internal/v2/entities/ChannelImpl.kt b/pubnub-kotlin/pubnub-kotlin-api/src/jsMain/kotlin/com/pubnub/internal/v2/entities/ChannelImpl.kt index 689c958bf..8753bad6c 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/jsMain/kotlin/com/pubnub/internal/v2/entities/ChannelImpl.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/jsMain/kotlin/com/pubnub/internal/v2/entities/ChannelImpl.kt @@ -20,12 +20,13 @@ class ChannelImpl(private val jsChannel: dynamic) : Channel { shouldStore: Boolean, usePost: Boolean, replicate: Boolean, - ttl: Int? + ttl: Int?, + customMessageType: String?, ): Publish { TODO("Not yet implemented") } - override fun signal(message: Any): Signal { + override fun signal(message: Any, customMessageType: String?): Signal { TODO("Not yet implemented") } diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/jvmMain/kotlin/com/pubnub/api/PubNub.kt b/pubnub-kotlin/pubnub-kotlin-api/src/jvmMain/kotlin/com/pubnub/api/PubNub.kt index 7873534d7..208ae463d 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/jvmMain/kotlin/com/pubnub/api/PubNub.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/jvmMain/kotlin/com/pubnub/api/PubNub.kt @@ -380,6 +380,7 @@ actual interface PubNub : StatusEmitter, EventEmitter { * - If `shouldStore = false`, the `ttl` parameter is ignored. * - If ttl isn't specified, then expiration of the message defaults * back to the expiry value for the key. + * @param customMessageType The custom type associated with the message. */ actual fun publish( channel: String, @@ -389,6 +390,7 @@ actual interface PubNub : StatusEmitter, EventEmitter { usePost: Boolean, replicate: Boolean, ttl: Int?, + customMessageType: String?, ): Publish /** @@ -463,10 +465,12 @@ actual interface PubNub : StatusEmitter, EventEmitter { * * @param channel The channel which the signal will be sent to. * @param message The payload which will be serialized and sent. + * @param customMessageType The custom type associated with the message. */ actual fun signal( channel: String, message: Any, + customMessageType: String?, ): Signal /** @@ -590,6 +594,10 @@ actual interface PubNub : StatusEmitter, EventEmitter { * @param includeMeta Whether to include message metadata in response. * Defaults to `false`. */ + @Deprecated( + level = DeprecationLevel.WARNING, + message = "Use fetchMessages(List, PNBoundedPage, Boolean, Boolean, Boolean, Boolean, Boolean) instead", + ) fun history( channel: String, start: Long? = null, @@ -645,7 +653,7 @@ actual interface PubNub : StatusEmitter, EventEmitter { "com.pubnub.api.models.consumer.PNBoundedPage", ), level = DeprecationLevel.WARNING, - message = "Use fetchMessages(String, PNBoundedPage, Boolean, Boolean, Boolean) instead", + message = "Use fetchMessages(List, PNBoundedPage, Boolean, Boolean, Boolean, Boolean, Boolean) instead", ) fun fetchMessages( channels: List, @@ -655,6 +663,7 @@ actual interface PubNub : StatusEmitter, EventEmitter { includeMeta: Boolean = false, includeMessageActions: Boolean = false, includeMessageType: Boolean = true, + includeCustomMessageType: Boolean = false ): FetchMessages /** @@ -691,6 +700,7 @@ actual interface PubNub : StatusEmitter, EventEmitter { * Defaults to `false`. * @param includeMessageType Whether to include message type in response. * Defaults to `false`. + * @param includeCustomMessageType Whether to include custom message type in response. Default to `false` */ actual fun fetchMessages( channels: List, @@ -699,6 +709,7 @@ actual interface PubNub : StatusEmitter, EventEmitter { includeMeta: Boolean, includeMessageActions: Boolean, includeMessageType: Boolean, + includeCustomMessageType: Boolean ): FetchMessages /** diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/jvmMain/kotlin/com/pubnub/api/endpoints/FetchMessages.kt b/pubnub-kotlin/pubnub-kotlin-api/src/jvmMain/kotlin/com/pubnub/api/endpoints/FetchMessages.kt index 461e0478f..62042ae4c 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/jvmMain/kotlin/com/pubnub/api/endpoints/FetchMessages.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/jvmMain/kotlin/com/pubnub/api/endpoints/FetchMessages.kt @@ -14,4 +14,5 @@ actual interface FetchMessages : Endpoint { val includeMeta: Boolean val includeMessageActions: Boolean val includeMessageType: Boolean + val includeCustomMessageType: Boolean } diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/jvmMain/kotlin/com/pubnub/api/endpoints/pubsub/Publish.kt b/pubnub-kotlin/pubnub-kotlin-api/src/jvmMain/kotlin/com/pubnub/api/endpoints/pubsub/Publish.kt index adc729da5..aeb6676c2 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/jvmMain/kotlin/com/pubnub/api/endpoints/pubsub/Publish.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/jvmMain/kotlin/com/pubnub/api/endpoints/pubsub/Publish.kt @@ -14,4 +14,5 @@ actual interface Publish : Endpoint { val usePost: Boolean val replicate: Boolean val ttl: Int? + val customMessageType: String? } diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/nonJvm/kotlin/com/pubnub/api/PubNub.nonJvm.kt b/pubnub-kotlin/pubnub-kotlin-api/src/nonJvm/kotlin/com/pubnub/api/PubNub.nonJvm.kt index d1e949d57..7eb05ef16 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/nonJvm/kotlin/com/pubnub/api/PubNub.nonJvm.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/nonJvm/kotlin/com/pubnub/api/PubNub.nonJvm.kt @@ -95,7 +95,7 @@ actual interface PubNub { usePost: Boolean ): Publish - actual fun signal(channel: String, message: Any): Signal + actual fun signal(channel: String, message: Any, customMessageType: String?): Signal actual fun getSubscribedChannels(): List @@ -137,7 +137,8 @@ actual interface PubNub { includeUUID: Boolean, includeMeta: Boolean, includeMessageActions: Boolean, - includeMessageType: Boolean + includeMessageType: Boolean, + includeCustomMessageType: Boolean ): FetchMessages actual fun deleteMessages( @@ -445,5 +446,6 @@ actual interface PubNub { usePost: Boolean, replicate: Boolean, ttl: Int?, + customMessageType: String? ): Publish } diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/history/PNFetchMessage.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/history/PNFetchMessage.kt index 2874ba2f0..6970b1b84 100644 --- a/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/history/PNFetchMessage.kt +++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/history/PNFetchMessage.kt @@ -42,6 +42,7 @@ data class PNFetchMessageItem( val actions: Map>>? = null, val messageType: HistoryMessageType?, val error: PubNubError? = null, + val customMessageType: String? = null ) { // for compatibility with legacy Java SDK class Action(uuid: String, actionTimetoken: Long) : diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/history/PNHistoryResult.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/history/PNHistoryResult.kt index aa0f1b512..bddd74889 100644 --- a/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/history/PNHistoryResult.kt +++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/history/PNHistoryResult.kt @@ -36,4 +36,5 @@ data class PNHistoryItemResult( val timetoken: Long? = null, val meta: JsonElement? = null, val error: PubNubError? = null, + val customMessageType: String? = null ) diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/pubsub/MessageResult.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/pubsub/MessageResult.kt index 1bb614d2b..aaeca33f5 100644 --- a/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/pubsub/MessageResult.kt +++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/pubsub/MessageResult.kt @@ -7,4 +7,5 @@ import com.pubnub.api.JsonElement */ interface MessageResult : PubSubResult { val message: JsonElement + val customMessageType: String? } diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/pubsub/PNMessageResult.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/pubsub/PNMessageResult.kt index 3a42c0c2f..cc216ff5f 100644 --- a/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/pubsub/PNMessageResult.kt +++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/pubsub/PNMessageResult.kt @@ -9,6 +9,7 @@ import com.pubnub.api.PubNubError class PNMessageResult( private val basePubSubResult: PubSubResult, override val message: JsonElement, + override val customMessageType: String? = null, val error: PubNubError? = null, ) : MessageResult, PubSubResult by basePubSubResult { override fun equals(other: Any?): Boolean { diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/pubsub/PNSignalResult.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/pubsub/PNSignalResult.kt index 90362ad42..b878489de 100644 --- a/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/pubsub/PNSignalResult.kt +++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/pubsub/PNSignalResult.kt @@ -8,4 +8,5 @@ import com.pubnub.api.JsonElement data class PNSignalResult( private val basePubSubResult: PubSubResult, override val message: JsonElement, + override val customMessageType: String? = null, ) : MessageResult, PubSubResult by basePubSubResult diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/pubsub/files/PNFileEventResult.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/pubsub/files/PNFileEventResult.kt index 0af2c12a7..c087db532 100644 --- a/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/pubsub/files/PNFileEventResult.kt +++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/models/consumer/pubsub/files/PNFileEventResult.kt @@ -15,6 +15,7 @@ class PNFileEventResult( val jsonMessage: JsonElement, override val subscription: String? = null, val error: PubNubError? = null, + val customMessageType: String? = null ) : PNEvent { override fun equals(other: Any?): Boolean { if (this === other) { diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/endpoints/pubsub/Signal.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/endpoints/pubsub/Signal.kt index 688958801..85db5d5e4 100644 --- a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/endpoints/pubsub/Signal.kt +++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/endpoints/pubsub/Signal.kt @@ -9,4 +9,5 @@ import com.pubnub.api.models.consumer.PNPublishResult actual interface Signal : Endpoint { val channel: String val message: Any + val customMessageType: String? } diff --git a/pubnub-kotlin/pubnub-kotlin-impl/config/ktlint/baseline.xml b/pubnub-kotlin/pubnub-kotlin-impl/config/ktlint/baseline.xml index f50dd5040..9302ac124 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/config/ktlint/baseline.xml +++ b/pubnub-kotlin/pubnub-kotlin-impl/config/ktlint/baseline.xml @@ -1,5 +1,10 @@ + + + + + @@ -12,9 +17,6 @@ - - - @@ -72,6 +74,23 @@ + + + + + + + + + + + + + + + + + @@ -118,6 +137,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -127,14 +171,25 @@ + + + + + + + + - - - - - - + + + + + + + + + diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/HistoryIntegrationTest.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/HistoryIntegrationTest.kt index 8439ce8be..dabb065aa 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/HistoryIntegrationTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/HistoryIntegrationTest.kt @@ -13,6 +13,7 @@ import com.pubnub.api.models.consumer.message_actions.PNMessageAction import com.pubnub.test.CommonUtils import com.pubnub.test.CommonUtils.emoji import com.pubnub.test.CommonUtils.randomChannel +import com.pubnub.test.CommonUtils.randomNumeric import org.awaitility.kotlin.await import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.aMapWithSize @@ -94,8 +95,8 @@ class HistoryIntegrationTest : BaseIntegrationTest() { historyResult = pubNubWithCrypto.history( channel = channel, - includeMeta = true, includeTimetoken = true, + includeMeta = true, ).sync() assertNotNull(historyResult) @@ -122,6 +123,7 @@ class HistoryIntegrationTest : BaseIntegrationTest() { val expectedMessage = CommonUtils.generatePayload() val expectedAction = "reaction" val expectedActionValue = emoji() + val expectedCustomMessageType = "customType_${randomNumeric()}" val result = pubnub.publish( @@ -130,6 +132,7 @@ class HistoryIntegrationTest : BaseIntegrationTest() { meta = expectedMeta, shouldStore = true, ttl = 60, + customMessageType = expectedCustomMessageType ).sync() val actionResult = @@ -157,6 +160,7 @@ class HistoryIntegrationTest : BaseIntegrationTest() { includeMessageType = true, includeUUID = true, channels = listOf(channel), + includeCustomMessageType = true ).sync() assertNotNull(fetchResult) assertThat(fetchResult?.channels, aMapWithSize(not(0))) @@ -182,6 +186,7 @@ class HistoryIntegrationTest : BaseIntegrationTest() { ), ), ), + customMessageType = expectedCustomMessageType ) val expectedChannelsResponse: Map> = @@ -202,6 +207,7 @@ class HistoryIntegrationTest : BaseIntegrationTest() { includeMessageType = true, includeUUID = true, channels = listOf(channel), + includeCustomMessageType = true ).sync() assertEquals( diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/MessageActionsIntegrationTest.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/MessageActionsIntegrationTest.kt index 21dfe7fb0..ba0bb48c5 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/MessageActionsIntegrationTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/MessageActionsIntegrationTest.kt @@ -380,6 +380,7 @@ class MessageActionsIntegrationTest : BaseIntegrationTest() { val fetchMessagesResultWithActions: PNFetchMessagesResult = pubnub.fetchMessages( channels = Collections.singletonList(expectedChannel), + page = PNBoundedPage(limit = 25), includeMeta = true, includeMessageActions = true, ).sync() @@ -423,6 +424,7 @@ class MessageActionsIntegrationTest : BaseIntegrationTest() { val fetchMessagesResultNoActions: PNFetchMessagesResult = pubnub.fetchMessages( channels = listOf(expectedChannel), + page = PNBoundedPage(limit = 25), ).sync() fetchMessagesResultNoActions.channels.forEach { (_: String?, pnFetchMessageItems: List) -> pnFetchMessageItems.forEach( diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PublishIntegrationTests.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PublishIntegrationTests.kt index b664a0e61..33eac6f5e 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PublishIntegrationTests.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PublishIntegrationTests.kt @@ -8,10 +8,13 @@ import com.pubnub.api.callbacks.SubscribeCallback import com.pubnub.api.crypto.CryptoModule import com.pubnub.api.enums.PNStatusCategory import com.pubnub.api.models.consumer.PNBoundedPage +import com.pubnub.api.models.consumer.PNPublishResult import com.pubnub.api.models.consumer.PNStatus import com.pubnub.api.models.consumer.pubsub.PNMessageResult import com.pubnub.api.v2.PNConfigurationOverride import com.pubnub.api.v2.callbacks.EventListener +import com.pubnub.api.v2.callbacks.Result +import com.pubnub.api.v2.callbacks.StatusListener import com.pubnub.api.v2.callbacks.getOrThrow import com.pubnub.api.v2.entities.Channel import com.pubnub.api.v2.subscriptions.SubscriptionCursor @@ -39,6 +42,8 @@ import org.junit.Assert.assertFalse import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Test +import java.util.concurrent.CompletableFuture +import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicInteger @@ -57,6 +62,7 @@ class PublishIntegrationTests : BaseIntegrationTest() { pubnub.publish( channel = expectedChannel, message = generatePayload(), + customMessageType = "myType" ).await { result -> assertFalse(result.isFailure) assertTrue(result.getOrThrow().timetoken > 0) @@ -111,8 +117,8 @@ class PublishIntegrationTests : BaseIntegrationTest() { } pubnub.history( - count = 1, channel = expectedChannel, + count = 1, ).asyncRetry { result -> assertFalse(result.isFailure) assertEquals(0, result.getOrThrow().messages.size) @@ -365,7 +371,8 @@ class PublishIntegrationTests : BaseIntegrationTest() { override fun status( pubnub: PubNub, pnStatus: PNStatus, - ) {} + ) { + } override fun message( pubnub: PubNub, @@ -397,7 +404,8 @@ class PublishIntegrationTests : BaseIntegrationTest() { override fun status( pubnub: PubNub, pnStatus: PNStatus, - ) {} + ) { + } override fun message( pubnub: PubNub, @@ -487,7 +495,8 @@ class PublishIntegrationTests : BaseIntegrationTest() { override fun status( pubnub: PubNub, pnStatus: PNStatus, - ) {} + ) { + } override fun message( pubnub: PubNub, @@ -523,7 +532,8 @@ class PublishIntegrationTests : BaseIntegrationTest() { override fun status( pubnub: PubNub, pnStatus: PNStatus, - ) {} + ) { + } override fun message( pubnub: PubNub, @@ -566,7 +576,8 @@ class PublishIntegrationTests : BaseIntegrationTest() { override fun status( pubnub: PubNub, pnStatus: PNStatus, - ) {} + ) { + } override fun message( pubnub: PubNub, @@ -831,7 +842,8 @@ class PublishIntegrationTests : BaseIntegrationTest() { channel.publish(message = "My message").sync() channel.signal(message = "My signal").sync() - channel.fire(message = "My Fire").sync() // fire will not be delivered to listener only to PubNub Functions Event Handlers + channel.fire(message = "My Fire") + .sync() // fire will not be delivered to listener only to PubNub Functions Event Handlers Awaitility.await() .atMost(DEFAULT_LISTEN_DURATION.toLong(), TimeUnit.SECONDS) @@ -840,4 +852,41 @@ class PublishIntegrationTests : BaseIntegrationTest() { .atMost(DEFAULT_LISTEN_DURATION.toLong(), TimeUnit.SECONDS) .untilAtomic(signalReceived, Matchers.equalTo(true)) } + + @Test + fun testPublishMessageWithCustomMessageType() { + val expectedChannelName = randomChannel() + val channel = pubnub.channel(expectedChannelName) + val expectedCustomMessageType = "thisIsType" + val connected = CountDownLatch(1) + val receivedMessageFuture = CompletableFuture() + + val subscription = channel.subscription() + subscription.onMessage = { pnMessageResult: PNMessageResult -> + receivedMessageFuture.complete(pnMessageResult) + } + pubnub.addListener(object : StatusListener { + override fun status(pubnub: PubNub, status: PNStatus) { + if (status.category == PNStatusCategory.PNConnectedCategory && + status.affectedChannels.contains(expectedChannelName) + ) { + connected.countDown() + } + } + }) + + subscription.subscribe() + assertTrue(connected.await(10, TimeUnit.SECONDS)) + + channel.publish( + message = generatePayload(), + customMessageType = expectedCustomMessageType + ).await { resutl: Result -> + assertTrue(resutl.isSuccess) + } + + val message: PNMessageResult = receivedMessageFuture.get(10, TimeUnit.SECONDS) + + assertEquals(expectedCustomMessageType, message.customMessageType) + } } diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/SignalIntegrationTests.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/SignalIntegrationTests.kt index c5672adfc..a2dcb8886 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/SignalIntegrationTests.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/SignalIntegrationTests.kt @@ -16,17 +16,20 @@ import org.junit.Test class SignalIntegrationTests : BaseIntegrationTest() { lateinit var expectedChannel: String lateinit var expectedPayload: String + lateinit var expectedCustomMessageType: String override fun onBefore() { expectedChannel = randomChannel() expectedPayload = randomValue(5) + expectedCustomMessageType = randomValue(5) } @Test fun testPublishSignalMessageAsync() { pubnub.signal( - message = expectedPayload, channel = expectedChannel, + message = expectedPayload, + customMessageType = expectedCustomMessageType, ).await { result -> assertFalse(result.isFailure) assertTrue(result.getOrThrow().timetoken > 0) @@ -36,8 +39,9 @@ class SignalIntegrationTests : BaseIntegrationTest() { @Test fun testPublishSignalMessageSync() { pubnub.signal( - message = expectedPayload, channel = expectedChannel, + message = expectedPayload, + customMessageType = expectedCustomMessageType, ).sync() } @@ -47,13 +51,15 @@ class SignalIntegrationTests : BaseIntegrationTest() { pubnub.test { subscribe(expectedChannel) observerClient.signal( - message = expectedPayload, channel = expectedChannel, + message = expectedPayload, + customMessageType = expectedCustomMessageType, ).sync() val pnSignalResult = nextEvent() assertEquals(observerClient.configuration.userId.value, pnSignalResult.publisher) assertEquals(expectedChannel, pnSignalResult.channel) assertEquals(expectedPayload, Gson().fromJson(pnSignalResult.message, String::class.java)) + assertEquals(expectedCustomMessageType, pnSignalResult.customMessageType) } } diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt index 2f81350a8..48a767d7f 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt @@ -334,6 +334,7 @@ open class PubNubImpl( usePost: Boolean, replicate: Boolean, ttl: Int?, + customMessageType: String?, ): Publish = PublishEndpoint( pubnub = this, @@ -344,6 +345,7 @@ open class PubNubImpl( usePost = usePost, replicate = replicate, ttl = ttl, + customMessageType = customMessageType ) override fun fire(channel: String, message: Any, meta: Any?, usePost: Boolean): Publish = publish( @@ -370,7 +372,8 @@ open class PubNubImpl( override fun signal( channel: String, message: Any, - ): Signal = SignalEndpoint(pubnub = this, channel = channel, message = message) + customMessageType: String?, + ): Signal = SignalEndpoint(pubnub = this, channel = channel, message = message, customMessageType = customMessageType) override fun addPushNotificationsOnChannels( pushType: PNPushType, @@ -464,6 +467,7 @@ open class PubNubImpl( includeMeta: Boolean, includeMessageActions: Boolean, includeMessageType: Boolean, + includeCustomMessageType: Boolean ): FetchMessages { return FetchMessagesEndpoint( pubnub = this, @@ -473,6 +477,7 @@ open class PubNubImpl( includeMeta = includeMeta, includeMessageActions = includeMessageActions, includeMessageType = includeMessageType, + includeCustomMessageType = includeCustomMessageType ) } @@ -990,13 +995,15 @@ open class PubNubImpl( includeMeta: Boolean, includeMessageActions: Boolean, includeMessageType: Boolean, + includeCustomMessageType: Boolean ): FetchMessages = fetchMessages( channels = channels, page = PNBoundedPage(start = start, end = end, limit = maximumPerChannel), includeUUID = true, includeMeta = includeMeta, includeMessageActions = includeMessageActions, - includeMessageType = includeMessageType + includeMessageType = includeMessageType, + includeCustomMessageType = includeCustomMessageType ) @Deprecated( diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/FetchMessagesEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/FetchMessagesEndpoint.kt index 9681b7371..8fbf6627c 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/FetchMessagesEndpoint.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/FetchMessagesEndpoint.kt @@ -15,6 +15,7 @@ import com.pubnub.internal.extension.limit import com.pubnub.internal.extension.nonPositiveToNull import com.pubnub.internal.extension.tryDecryptMessage import com.pubnub.internal.models.server.FetchMessagesEnvelope +import com.pubnub.internal.models.server.history.ServerFetchMessageItem import com.pubnub.internal.toCsv import retrofit2.Call import retrofit2.Response @@ -31,6 +32,7 @@ class FetchMessagesEndpoint internal constructor( override val includeMeta: Boolean, override val includeMessageActions: Boolean, override val includeMessageType: Boolean, + override val includeCustomMessageType: Boolean ) : EndpointCore(pubnub), FetchMessages { internal companion object { private const val SINGLE_CHANNEL_DEFAULT_MESSAGES = 100 @@ -40,6 +42,8 @@ class FetchMessagesEndpoint internal constructor( private const val DEFAULT_MESSAGES_WITH_ACTIONS = 25 private const val MAX_MESSAGES_WITH_ACTIONS = 25 internal const val INCLUDE_MESSAGE_TYPE_QUERY_PARAM = "include_message_type" + private const val INCLUDE_CUSTOM_MESSAGE_TYPE = "include_custom_message_type" + internal fun effectiveMax( maximumPerChannel: Int?, @@ -95,7 +99,7 @@ class FetchMessagesEndpoint internal constructor( val body = input.body()!! val channelsMap = body.channels.mapValues { (_, value) -> - value.map { serverMessageItem -> + value.map { serverMessageItem: ServerFetchMessageItem -> val (newMessage, error) = serverMessageItem.message.tryDecryptMessage( configuration.cryptoModule, @@ -119,6 +123,7 @@ class FetchMessagesEndpoint internal constructor( } else { null }, + customMessageType = serverMessageItem.customMessageType, error = error, ) } @@ -147,5 +152,8 @@ class FetchMessagesEndpoint internal constructor( if (includeMeta) { queryParams["include_meta"] = "true" } + if(includeCustomMessageType){ // todo is includeCustomMessageType optional? + queryParams[INCLUDE_CUSTOM_MESSAGE_TYPE] = includeCustomMessageType.toString() + } } } diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/PublishEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/PublishEndpoint.kt index c1a6a9ab3..af0332df5 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/PublishEndpoint.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/PublishEndpoint.kt @@ -27,7 +27,12 @@ class PublishEndpoint internal constructor( override val usePost: Boolean = false, override val replicate: Boolean = true, override val ttl: Int? = null, + override val customMessageType: String? = null ) : EndpointCore, PNPublishResult>(pubnub), Publish { + companion object { + private const val CUSTOM_MESSAGE_TYPE_QUERY_PARAM = "custom_message_type" + } + override fun validateParams() { super.validateParams() if (channel.isBlank()) { @@ -93,6 +98,8 @@ class PublishEndpoint internal constructor( queryParams["norep"] = true.valueString } + customMessageType?.run { queryParams[CUSTOM_MESSAGE_TYPE_QUERY_PARAM] = this } + queryParams["seqn"] = pubnub.publishSequenceManager.nextSequence().toString() } // endregion diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/SignalEndpoint.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/SignalEndpoint.kt index 823c49b84..d65d5a6ec 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/SignalEndpoint.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/endpoints/pubsub/SignalEndpoint.kt @@ -18,7 +18,12 @@ class SignalEndpoint internal constructor( pubnub: PubNubImpl, override val channel: String, override val message: Any, + override val customMessageType: String? = null ) : EndpointCore, PNPublishResult>(pubnub), Signal { + companion object { + private const val CUSTOM_MESSAGE_TYPE_QUERY_PARAM = "custom_message_type" + } + override fun validateParams() { super.validateParams() if (channel.isBlank()) { @@ -29,6 +34,10 @@ class SignalEndpoint internal constructor( override fun getAffectedChannels() = listOf(channel) override fun doWork(queryParams: HashMap): Call> { + customMessageType?.let { customMessageTypeNotNull -> + queryParams[CUSTOM_MESSAGE_TYPE_QUERY_PARAM] = customMessageTypeNotNull + } + return retrofitManager.signalService.signal( pubKey = configuration.publishKey, subKey = configuration.subscribeKey, diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/models/server/SubscribeMessage.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/models/server/SubscribeMessage.kt index 8caa8e381..037094a4a 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/models/server/SubscribeMessage.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/models/server/SubscribeMessage.kt @@ -5,7 +5,7 @@ import com.google.gson.annotations.SerializedName import com.pubnub.internal.workers.SubscribeMessageProcessor.Companion.TYPE_FILES import com.pubnub.internal.workers.SubscribeMessageProcessor.Companion.TYPE_MESSAGE -class SubscribeMessage( +data class SubscribeMessage( @SerializedName("a") internal val shard: String?, @SerializedName("b") @@ -28,6 +28,8 @@ class SubscribeMessage( internal val userMetadata: JsonElement?, @SerializedName("e") internal val type: Int?, + @SerializedName("cmt") + internal val customMessageType: String?, ) { fun supportsEncryption() = type in arrayOf(null, TYPE_MESSAGE, TYPE_FILES) } diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/models/server/history/ServerFetchMessageItem.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/models/server/history/ServerFetchMessageItem.kt index 7cd8468d0..7811bd505 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/models/server/history/ServerFetchMessageItem.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/models/server/history/ServerFetchMessageItem.kt @@ -12,4 +12,6 @@ data class ServerFetchMessageItem( val actions: Map>>? = null, @SerializedName("message_type") val messageType: Int?, + @SerializedName("custom_message_type") + val customMessageType: String? ) diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/v2/entities/ChannelImpl.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/v2/entities/ChannelImpl.kt index b1889522c..ad22f9e59 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/v2/entities/ChannelImpl.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/v2/entities/ChannelImpl.kt @@ -77,13 +77,14 @@ open class ChannelImpl(val pubNubImpl: PubNubImpl, val channelName: ChannelName) shouldStore: Boolean, usePost: Boolean, replicate: Boolean, - ttl: Int? + ttl: Int?, + customMessageType: String? ): Publish { - return pubNubImpl.publish(channelName.id, message, meta, shouldStore, usePost, replicate, ttl) + return pubNubImpl.publish(channelName.id, message, meta, shouldStore, usePost, replicate, ttl, customMessageType) } - override fun signal(message: Any): Signal { - return pubNubImpl.signal(channelName.id, message) + override fun signal(message: Any, customMessageType: String?): Signal { + return pubNubImpl.signal(channelName.id, message, customMessageType) } override fun fire(message: Any, meta: Any?, usePost: Boolean, ttl: Int?): Publish { diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/workers/SubscribeMessageProcessor.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/workers/SubscribeMessageProcessor.kt index 18ded7546..dd3021eef 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/workers/SubscribeMessageProcessor.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/workers/SubscribeMessageProcessor.kt @@ -95,6 +95,7 @@ internal class SubscribeMessageProcessor( if (extractedMessage == null) { log.debug("unable to parse payload on #processIncomingMessages") } + val customMessageType = message.customMessageType val result = BasePubSubResult( @@ -107,15 +108,15 @@ internal class SubscribeMessageProcessor( return when (message.type) { null -> { - PNMessageResult(result, extractedMessage!!, error) + PNMessageResult(result, extractedMessage!!, customMessageType, error) } TYPE_MESSAGE -> { - PNMessageResult(result, extractedMessage!!, error) + PNMessageResult(result, extractedMessage!!, customMessageType, error) } TYPE_SIGNAL -> { - PNSignalResult(result, extractedMessage!!) + PNSignalResult(result, extractedMessage!!, customMessageType) } TYPE_OBJECT -> { @@ -167,6 +168,7 @@ internal class SubscribeMessageProcessor( fileUploadNotification.message?.let { pubnub.mapper.toJsonTree(it) } ?: JsonNull.INSTANCE, error = error, + customMessageType = customMessageType, ) } @@ -193,7 +195,7 @@ internal class SubscribeMessageProcessor( ) val queryParams = ArrayList() val authToken = - if (pubnub.tokenManager.getToken() != null){ + if (pubnub.tokenManager.getToken() != null) { pubnub.tokenManager.getToken() } else if (pubnub.configuration.authKey.isValid()) { pubnub.configuration.authKey diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/endpoints/history/FetchMessagesCoreEndpointTest.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/endpoints/history/FetchMessagesCoreEndpointTest.kt index c3b5f10cb..2294fac28 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/endpoints/history/FetchMessagesCoreEndpointTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/endpoints/history/FetchMessagesCoreEndpointTest.kt @@ -7,6 +7,8 @@ import com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor import com.github.tomakehurst.wiremock.client.WireMock.stubFor import com.github.tomakehurst.wiremock.client.WireMock.urlMatching import com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo +import com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching +import com.github.tomakehurst.wiremock.matching.EqualToPattern import com.pubnub.api.crypto.CryptoModule import com.pubnub.api.legacy.BaseTest import com.pubnub.api.models.consumer.PNBoundedPage @@ -452,6 +454,7 @@ class FetchMessagesCoreEndpointTest : BaseTest() { pubnub.fetchMessages( channels = listOf(channel), + page = PNBoundedPage(limit = 25), includeMessageType = true, ).sync() @@ -477,6 +480,7 @@ class FetchMessagesCoreEndpointTest : BaseTest() { pubnub.fetchMessages( channels = listOf(channel), + page = PNBoundedPage(limit = 25), ).sync() val requests = findAll(getRequestedFor(urlMatching("/.*"))) @@ -502,6 +506,7 @@ class FetchMessagesCoreEndpointTest : BaseTest() { val response = pubnub.fetchMessages( channels = listOf(channel), + page = PNBoundedPage(limit = 25), includeMessageType = true, ).sync() @@ -511,6 +516,39 @@ class FetchMessagesCoreEndpointTest : BaseTest() { ) } + @Test + fun testCustomMessageTypesAreProperlyDeserialized() { + val customMessageType01 = "myCustomType01" + val customMessageType02 = "myCustomType02" + stubFor( + get( + urlPathMatching("/v3/history/sub-key/mySubscribeKey/channel/$channel.*") + ).withQueryParam("include_custom_message_type", EqualToPattern("true")) + .willReturn( + aResponse().withBody( + responseWithMessagesForChannelWithCustomMessageType(channel, customMessageType01, customMessageType02), + ) + ) + ) + + val response = + pubnub.fetchMessages( + channels = listOf(channel), + page = PNBoundedPage(limit = 25), + includeMessageType = true, + includeCustomMessageType = true + ).sync() + + assertThat( + response.channels.values.flatMap { items -> items.map { it.messageType } }, + contains(HistoryMessageType.Message, HistoryMessageType.File), + ) + assertThat( + response.channels.values.flatMap { items -> items.map { it.customMessageType } }, + contains(customMessageType01, customMessageType02), + ) + } + private fun randomInt(max: Int): Int = nextInt(max) + 1 private fun responseWithOneMessageForChannel(channel: String): String { @@ -554,4 +592,30 @@ class FetchMessagesCoreEndpointTest : BaseTest() { } """.trimIndent() } + + private fun responseWithMessagesForChannelWithCustomMessageType(channel: String, customMessageType01: String, customMessageType02: String): String { + return """ + { + "status": 200, + "error": false, + "error_message": "", + "channels": { + "$channel": [ + { + "message": "thisIsMessage1", + "timetoken": "14797423056306675", + "message_type": 0, + "custom_message_type":"myCustomType01" + }, + { + "message": "thisIsMessage2", + "timetoken": "14797423056306676", + "message_type": 4, + "custom_message_type":"myCustomType02" + } + ] + } + } + """.trimIndent() + } } diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/endpoints/history/HistoryCoreEndpointTest.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/endpoints/history/HistoryCoreEndpointTest.kt index 76c843094..79d0654ae 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/endpoints/history/HistoryCoreEndpointTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/endpoints/history/HistoryCoreEndpointTest.kt @@ -468,10 +468,10 @@ class HistoryCoreEndpointTest : BaseTest() { val result = pubnub.history( channel = "niceChannel", - count = 5, - reverse = true, start = 1L, end = 2L, + count = 5, + reverse = true, includeTimetoken = true, ).sync() diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/endpoints/pubsub/PublishTest.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/endpoints/pubsub/PublishTest.kt index a7ef671cc..bdd70e204 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/endpoints/pubsub/PublishTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/endpoints/pubsub/PublishTest.kt @@ -11,12 +11,17 @@ import com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor import com.github.tomakehurst.wiremock.client.WireMock.stubFor import com.github.tomakehurst.wiremock.client.WireMock.urlMatching import com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo +import com.pubnub.api.PubNub import com.pubnub.api.PubNubError import com.pubnub.api.PubNubException +import com.pubnub.api.callbacks.SubscribeCallback import com.pubnub.api.crypto.CryptoModule import com.pubnub.api.legacy.BaseTest +import com.pubnub.api.models.consumer.PNStatus +import com.pubnub.api.models.consumer.pubsub.PNMessageResult import com.pubnub.test.CommonUtils.assertPnException import com.pubnub.test.CommonUtils.failTest +import com.pubnub.test.listen import org.awaitility.Awaitility import org.hamcrest.core.IsEqual import org.json.JSONArray @@ -26,6 +31,7 @@ import org.junit.Assert.assertFalse import org.junit.Test import java.nio.charset.Charset import java.util.concurrent.TimeUnit +import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicInteger class PublishTest : BaseTest() { @@ -59,6 +65,7 @@ class PublishTest : BaseTest() { channel = "coolChannel", message = "hi", replicate = false, + customMessageType = "myCustomType" ).sync() val requests = findAll(getRequestedFor(urlMatching("/.*"))) @@ -97,6 +104,7 @@ class PublishTest : BaseTest() { channel = "coolChannel", message = "hi", replicate = false, + customMessageType = "myCustomType" ).sync() val requests = findAll(getRequestedFor(urlMatching("/.*"))) @@ -537,4 +545,71 @@ class PublishTest : BaseTest() { assertEquals("0", requests[0].queryParameter("store").firstValue()) assertFalse(requests[0].queryParameter("ttl").isPresent) } + + @Test + fun testPublishSuccessReceive() { + val channelName = "coolChannel" + val message = "hello" + val uuid = "uuid" + val customMessageType = "myCustomMessageType" + stubFor( + get(urlMatching("/v2/subscribe/mySubscribeKey/coolChannel/0.*")) + .willReturn( + aResponse().withBody( + """ + { + "m": [ + { + "c": "$channelName", + "f": "0", + "i": "$uuid", + "d": "$message", + "e": 0, + "p": { + "t": 1000, + "r": 1 + }, + "k": "mySubscribeKey", + "b": "$channelName", + "cmt" : "$customMessageType" + } + ], + "t": { + "r": "56", + "t": 1000 + } + } + """.trimIndent(), + ), + ), + ) + + val success = AtomicBoolean() + + pubnub.addListener( + object : SubscribeCallback() { + override fun message( + pubnub: PubNub, + pnMessageResult: PNMessageResult, + ) { + assertEquals(channelName, pnMessageResult.channel) + assertEquals(message, pnMessageResult.message.asString) + assertEquals(uuid, pnMessageResult.publisher) + assertEquals(customMessageType, pnMessageResult.customMessageType) + success.set(true) + } + + override fun status( + pubnub: PubNub, + pnStatus: PNStatus, + ) {} + }, + ) + + pubnub.subscribe( + channels = listOf("coolChannel"), + ) + + success.listen() + } } diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/endpoints/pubsub/SignalTest.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/endpoints/pubsub/SignalTest.kt index 35e34a551..650d65c2e 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/endpoints/pubsub/SignalTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/api/legacy/endpoints/pubsub/SignalTest.kt @@ -12,10 +12,7 @@ import com.pubnub.api.PubNubException import com.pubnub.api.callbacks.SubscribeCallback import com.pubnub.api.legacy.BaseTest import com.pubnub.api.models.consumer.PNStatus -import com.pubnub.api.models.consumer.pubsub.PNMessageResult -import com.pubnub.api.models.consumer.pubsub.PNPresenceEventResult import com.pubnub.api.models.consumer.pubsub.PNSignalResult -import com.pubnub.api.models.consumer.pubsub.message_actions.PNMessageActionResult import com.pubnub.test.CommonUtils.assertPnException import com.pubnub.test.listen import okhttp3.HttpUrl.Companion.toHttpUrlOrNull @@ -102,6 +99,10 @@ class SignalTest : BaseTest() { @Test fun testSignalSuccessReceive() { + val channelName = "coolChannel" + val message = "hello" + val uuid = "uuid" + val customMessageType = "myCustomMessageType" stubFor( get(urlMatching("/v2/subscribe/mySubscribeKey/coolChannel/0.*")) .willReturn( @@ -110,17 +111,18 @@ class SignalTest : BaseTest() { { "m": [ { - "c": "coolChannel", + "c": "$channelName", "f": "0", - "i": "uuid", - "d": "hello", + "i": "$uuid", + "d": "$message", "e": 1, "p": { "t": 1000, "r": 1 }, "k": "mySubscribeKey", - "b": "coolChannel" + "b": "$channelName", + "cmt" : "$customMessageType" } ], "t": { @@ -141,9 +143,10 @@ class SignalTest : BaseTest() { pubnub: PubNub, pnSignalResult: PNSignalResult, ) { - assertEquals("coolChannel", pnSignalResult.channel) - assertEquals("hello", pnSignalResult.message.asString) - assertEquals("uuid", pnSignalResult.publisher) + assertEquals(channelName, pnSignalResult.channel) + assertEquals(message, pnSignalResult.message.asString) + assertEquals(uuid, pnSignalResult.publisher) + assertEquals(customMessageType, pnSignalResult.customMessageType) success.set(true) } @@ -151,21 +154,6 @@ class SignalTest : BaseTest() { pubnub: PubNub, pnStatus: PNStatus, ) {} - - override fun message( - pubnub: PubNub, - pnMessageResult: PNMessageResult, - ) {} - - override fun presence( - pubnub: PubNub, - pnPresenceEventResult: PNPresenceEventResult, - ) {} - - override fun messageAction( - pubnub: PubNub, - pnMessageActionResult: PNMessageActionResult, - ) {} }, ) @@ -182,6 +170,7 @@ class SignalTest : BaseTest() { pubnub.signal( channel = " ", message = UUID.randomUUID().toString(), + customMessageType = "myType" ).sync() throw RuntimeException() } catch (e: PubNubException) { diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/history/state/HistoryState.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/history/state/HistoryState.kt new file mode 100644 index 000000000..bb76eedae --- /dev/null +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/history/state/HistoryState.kt @@ -0,0 +1,7 @@ +package com.pubnub.contract.history.state + +import com.pubnub.api.models.consumer.history.PNFetchMessagesResult + +class HistoryState { + var messages: PNFetchMessagesResult? = null +} \ No newline at end of file diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/history/step/WhenSteps.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/history/step/WhenSteps.kt new file mode 100644 index 000000000..fb34bc87f --- /dev/null +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/history/step/WhenSteps.kt @@ -0,0 +1,81 @@ +package com.pubnub.contract.history.step + +import com.pubnub.api.PubNubException +import com.pubnub.api.models.consumer.history.HistoryMessageType +import com.pubnub.contract.history.state.HistoryState +import com.pubnub.contract.state.World +import io.cucumber.java.en.Then +import io.cucumber.java.en.When +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.contains + +class WhenSteps(private val world: World, private val historyState: HistoryState) { + + @When("I fetch message history for {string} channel") + fun i_fetch_message_history_for_channel(channelName: String) { + try { + historyState.messages = world.pubnub.fetchMessages( + channels = listOf(channelName), + includeCustomMessageType = true + ).sync() + world.responseStatus = 200 + } catch (ex: PubNubException) { + world.responseStatus = ex.statusCode + world.pnException = ex + } + } + + @When("I fetch message history with include_custom_message_type set to false for {string} channel") //todo fix it + fun i_fetch_message_history_with_includeCustomMessageType_set_to_false_for_channel(channelName: String) { + try { + historyState.messages = world.pubnub.fetchMessages( + channels = listOf(channelName), + includeCustomMessageType = false + ).sync() + world.responseStatus = 200 + } catch (ex: PubNubException) { + world.responseStatus = ex.statusCode + world.pnException = ex + } + } + + @Then("history response contains messages without customMessageType") + fun history_response_contains_messages_without_customMessageType(){ + val customMessageTypesInResponse: List = + historyState.messages!!.channels.values.flatMap { message -> message.map { it.customMessageType } } + println() + } + + + @Then("history response contains messages with {string} and {string} message types") + fun history_response_contains_messages_with_message_type( + messageTypeOfFirstMessage: String, + messageTypeOfSecondMessage: String + ) { + val historyMessageTypesInResponse: List = + historyState.messages!!.channels.values.flatMap { message -> message.map { it.messageType } } + + assertThat( + historyMessageTypesInResponse, + contains( + HistoryMessageType.of(messageTypeOfFirstMessage.toInt()), + HistoryMessageType.of(messageTypeOfSecondMessage.toInt()) + ) + ) + } + + @Then("history response contains messages with {string} and {string} types") + fun history_response_contains_messages_with_customMessageType( + customMessageTypeOfFirstMessage: String, + customMessageTypeOfSecondMessage: String + ) { + val customMessageTypesInResponse: List = + historyState.messages!!.channels.values.flatMap { message -> message.map { it.customMessageType } } + + assertThat( + customMessageTypesInResponse, + contains(customMessageTypeOfFirstMessage, customMessageTypeOfSecondMessage), + ) + } + +} \ No newline at end of file diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/publish/WhenSteps.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/publish/WhenSteps.kt new file mode 100644 index 000000000..dca54a34e --- /dev/null +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/publish/WhenSteps.kt @@ -0,0 +1,23 @@ +package com.pubnub.contract.publish + +import com.pubnub.api.PubNubException +import com.pubnub.contract.state.World +import io.cucumber.java.en.When + +class WhenSteps(private val world: World) { + @When("I publish message with {string} customMessageType") + fun i_publish_message_with_custom_message_type(customMessageType: String){ + try { + world.pubnub.publish( + channel = "whatever", + message = "whatever", + customMessageType = customMessageType + ).sync().let { + world.responseStatus = 200 + } + } catch (ex: PubNubException){ + world.responseStatus = ex.statusCode + world.pnException = ex + } + } +} \ No newline at end of file diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/signal/WhenSteps.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/signal/WhenSteps.kt new file mode 100644 index 000000000..fce474f9a --- /dev/null +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/signal/WhenSteps.kt @@ -0,0 +1,23 @@ +package com.pubnub.contract.signal + +import com.pubnub.api.PubNubException +import com.pubnub.contract.state.World +import io.cucumber.java.en.When + +class WhenSteps(private val world: World) { + @When("I send a signal with {string} customMessageType") + fun i_send_signal_with_custom_message_type(customMessageType: String) { + try { + world.pubnub.signal( + channel = "whatever", + message = "whatever", + customMessageType = customMessageType + ).sync().let { + world.responseStatus = 200 + } + } catch (ex: PubNubException) { + world.responseStatus = ex.statusCode + world.pnException = ex + } + } +} \ No newline at end of file diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/step/KeysetStep.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/step/KeysetStep.kt index e22e21465..7f243b30c 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/step/KeysetStep.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/step/KeysetStep.kt @@ -47,4 +47,20 @@ class KeysetStep(private val world: World) { fun the_demo_keyset_with_Presence_EE_enabled() { the_demo_keyset_with_event_engine_enabled() } + + @Given("the demo keyset") + fun the_demo_keyset() { + MatcherAssert.assertThat(ContractTestConfig.pubKey, Matchers.notNullValue()) + MatcherAssert.assertThat(ContractTestConfig.subKey, Matchers.notNullValue()) + + world.configuration.apply { + subscribeKey = ContractTestConfig.subKey + publishKey = ContractTestConfig.pubKey + } + } + + @Given("the demo keyset with enabled storage") + fun the_demo_keyset_with_enabled_storage(){ + the_demo_keyset() + } } diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/step/ThenSteps.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/step/ThenSteps.kt index b06d54586..af5ee4e6d 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/step/ThenSteps.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/step/ThenSteps.kt @@ -4,6 +4,7 @@ import com.pubnub.contract.state.World import io.cucumber.java.en.Then import org.json.JSONObject import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull import org.junit.Assert.assertTrue @@ -15,6 +16,12 @@ class ThenSteps(private val world: World) { ) fun an_error_is_returned() { assertNotNull(world.pnException) + assertNotEquals(200, world.responseStatus) + } + + @Then("I receive an error response") + fun i_receive_an_error_response(){ + an_error_is_returned() } @Then("the result is successful") diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/subscribe/eventEngine/step/EventEngineSteps.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/subscribe/eventEngine/step/EventEngineSteps.kt index c74890edb..7590df1b3 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/subscribe/eventEngine/step/EventEngineSteps.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/contract/subscribe/eventEngine/step/EventEngineSteps.kt @@ -19,6 +19,8 @@ import org.awaitility.kotlin.await import org.hamcrest.CoreMatchers import org.hamcrest.MatcherAssert import org.hamcrest.Matchers +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue import java.util.concurrent.TimeUnit import kotlin.time.Duration.Companion.milliseconds @@ -45,6 +47,7 @@ class EventEngineSteps(private val state: EventEngineState) { pubnub: PubNub, pnMessageResult: PNMessageResult, ) { + println("-=message: ${pnMessageResult.customMessageType}") state.messagesList.add(pnMessageResult) } @@ -88,6 +91,11 @@ class EventEngineSteps(private val state: EventEngineState) { state.pubnub.subscribe(channels = listOf(state.channelName)) } + @When("I subscribe to {string} channel") + fun i_subscribe_to_channel(channelId: String){ + i_subscribe() + } + @When("I subscribe with timetoken {long}") fun i_subscribe_with_timetoken(timetoken: Long) { state.pubnub.addListener( @@ -156,6 +164,27 @@ class EventEngineSteps(private val state: EventEngineState) { state.messagesList.map { it::class.java }, CoreMatchers.hasItems(PNMessageResult::class.java), ) + println("-=size: ${state.messagesList.size}") + } + } + + @Then("I receive 2 messages in my subscribe response") + fun i_receive_2_messages_in_my_subscribe_response(){ + println("-=I receive 2 messages in my subscribe ") + await.pollInterval(50, TimeUnit.MILLISECONDS).atMost(2, TimeUnit.SECONDS).untilAsserted { + MatcherAssert.assertThat( + state.messagesList.size, Matchers.`is`(2) + ) + } + } + + @Then("response contains messages with {string} and {string} types") + fun response_contains_messages_with_customMessageType(customMessageType01: String, customMessageType02: String){ + await.pollInterval(50, TimeUnit.MILLISECONDS).atMost(500, TimeUnit.MILLISECONDS).untilAsserted { + val messageList = state.messagesList as List + val customMessageTypeList = messageList.map { message -> message.customMessageType }.toList() + assertTrue(customMessageTypeList.contains(customMessageType01)) + assertTrue(customMessageTypeList.contains(customMessageType02)) } } diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/internal/suite/history/v2/HistoryMetaTestSuite.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/internal/suite/history/v2/HistoryMetaTestSuite.kt index b9625a7cd..ce1cf2ec8 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/internal/suite/history/v2/HistoryMetaTestSuite.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/internal/suite/history/v2/HistoryMetaTestSuite.kt @@ -22,8 +22,8 @@ class HistoryMetaTestSuite : com.pubnub.internal.suite.CoreEndpointTestSuite Unit = { }, @@ -197,4 +212,19 @@ class SubscribeMessageProcessorTest( private fun fileMessage(messageJson: String) = """{"a":"0","f":0,"e":4,"i":"client-52774e6f-2f4e-4915-aefd-e8bb75cd2e7d","p":{"t":"16632349939765880","r":43},"k":"sub-c-4b1dbfef-2fa9-495f-a316-2b634063083d","c":"ch_1663234993171_F4FC4F460F","u":"This is meta","d":{"message":$messageJson,"file":{"id":"30ce0095-3c50-4cdc-a626-bf402d233731","name":"fileNamech_1663234993171_F4FC4F460F.txt"}}}""" + + private fun subscribeMessage() = SubscribeMessage( + shard = "4", + flags = "0", + publishMetaData = PublishMetaData(16710463855524468, 21), + channel = "testChannel", + type = null, + customMessageType = null, + subscriptionMatch = null, + issuingClientId = null, + subscribeKey = "demo", + originationMetadata = null, + payload = JsonPrimitive("message"), + userMetadata = null + ) }