diff --git a/slack-base/src/main/java/com/hubspot/slack/client/methods/params/assistant/SetThreadStatusParamsIF.java b/slack-base/src/main/java/com/hubspot/slack/client/methods/params/assistant/SetThreadStatusParamsIF.java index fe986005..1746fbac 100644 --- a/slack-base/src/main/java/com/hubspot/slack/client/methods/params/assistant/SetThreadStatusParamsIF.java +++ b/slack-base/src/main/java/com/hubspot/slack/client/methods/params/assistant/SetThreadStatusParamsIF.java @@ -1,15 +1,22 @@ package com.hubspot.slack.client.methods.params.assistant; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.databind.annotation.JsonNaming; import com.hubspot.immutables.style.HubSpotStyle; +import com.hubspot.immutables.validation.ImmutableConditions; import com.hubspot.slack.client.methods.interceptor.HasChannel; +import java.util.List; +import java.util.Optional; import org.immutables.value.Value; @Value.Immutable @HubSpotStyle +@JsonInclude(JsonInclude.Include.NON_ABSENT) @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) public interface SetThreadStatusParamsIF extends HasChannel { + int MAX_LOADING_MESSAGES = 10; + @Value.Derived default String getChannel() { return getChannelId(); @@ -18,4 +25,30 @@ default String getChannel() { String getStatus(); String getThreadTs(); + + @JsonInclude(JsonInclude.Include.NON_EMPTY) + List getLoadingMessages(); + + Optional getIconEmoji(); + + Optional getIconUrl(); + + Optional getUsername(); + + @Value.Check + default void checkLoadingMessagesWithinLimit() { + ImmutableConditions.checkValid( + getLoadingMessages().size() <= MAX_LOADING_MESSAGES, + "loadingMessages cannot contain more than %s messages", + MAX_LOADING_MESSAGES + ); + } + + @Value.Check + default void checkIconNotBothPresent() { + ImmutableConditions.checkValid( + !(getIconEmoji().isPresent() && getIconUrl().isPresent()), + "Only one of iconEmoji or iconUrl may be set" + ); + } } diff --git a/slack-base/src/test/java/com/hubspot/slack/client/methods/params/assistant/SetThreadStatusParamsValidationTest.java b/slack-base/src/test/java/com/hubspot/slack/client/methods/params/assistant/SetThreadStatusParamsValidationTest.java new file mode 100644 index 00000000..305b9566 --- /dev/null +++ b/slack-base/src/test/java/com/hubspot/slack/client/methods/params/assistant/SetThreadStatusParamsValidationTest.java @@ -0,0 +1,102 @@ +package com.hubspot.slack.client.methods.params.assistant; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import com.hubspot.immutables.validation.InvalidImmutableStateException; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import org.junit.Test; + +public class SetThreadStatusParamsValidationTest { + + private static final String CHANNEL_ID = "C123"; + private static final String THREAD_TS = "1234.5678"; + private static final String STATUS = "is thinking..."; + + @Test + public void itBuildsWithoutLoadingMessages() { + assertThatCode(() -> + SetThreadStatusParams + .builder() + .setChannelId(CHANNEL_ID) + .setThreadTs(THREAD_TS) + .setStatus(STATUS) + .build() + ) + .doesNotThrowAnyException(); + } + + @Test + public void itBuildsWithMaxLoadingMessages() { + assertThatCode(() -> + SetThreadStatusParams + .builder() + .setChannelId(CHANNEL_ID) + .setThreadTs(THREAD_TS) + .setStatus(STATUS) + .addAllLoadingMessages( + loadingMessages(SetThreadStatusParams.MAX_LOADING_MESSAGES) + ) + .build() + ) + .doesNotThrowAnyException(); + } + + @Test + public void itFailsToBuildWithTooManyLoadingMessages() { + assertThatThrownBy(() -> + SetThreadStatusParams + .builder() + .setChannelId(CHANNEL_ID) + .setThreadTs(THREAD_TS) + .setStatus(STATUS) + .addAllLoadingMessages( + loadingMessages(SetThreadStatusParams.MAX_LOADING_MESSAGES + 1) + ) + .build() + ) + .isInstanceOf(InvalidImmutableStateException.class) + .hasMessageContaining("loadingMessages"); + } + + @Test + public void itBuildsWithOptionalFields() { + assertThatCode(() -> + SetThreadStatusParams + .builder() + .setChannelId(CHANNEL_ID) + .setThreadTs(THREAD_TS) + .setStatus(STATUS) + .setIconEmoji(Optional.of(":robot_face:")) + .setUsername(Optional.of("My Bot")) + .build() + ) + .doesNotThrowAnyException(); + } + + @Test + public void itFailsToBuildWithBothIconEmojiAndIconUrl() { + assertThatThrownBy(() -> + SetThreadStatusParams + .builder() + .setChannelId(CHANNEL_ID) + .setThreadTs(THREAD_TS) + .setStatus(STATUS) + .setIconEmoji(Optional.of(":robot_face:")) + .setIconUrl(Optional.of("https://example.com/icon.png")) + .build() + ) + .isInstanceOf(InvalidImmutableStateException.class) + .hasMessageContaining("iconEmoji") + .hasMessageContaining("iconUrl"); + } + + private static Iterable loadingMessages(int count) { + return IntStream + .range(0, count) + .mapToObj(i -> "message " + i) + .collect(Collectors.toList()); + } +}