diff --git a/block-kit/README.md b/block-kit/README.md index 3cd3768..08c29bd 100644 --- a/block-kit/README.md +++ b/block-kit/README.md @@ -20,3 +20,38 @@ Read the [docs](https://docs.slack.dev/block-kit/) to learn concepts behind thes - **[Section](https://docs.slack.dev/reference/block-kit/blocks/section-block)**: Displays text, possibly alongside elements. [Implementation](./src/main/java/blocks/Section.java). - **[Video](https://docs.slack.dev/reference/block-kit/blocks/video-block)**: Displays an embedded video player. [Implementation](./src/main/java/blocks/Video.java). +### Block elements + +- **[Broadcast](https://docs.slack.dev/reference/block-kit/block-elements/broadcast-element)**: Displays a broadcast mention such as here, channel, or everyone. [Implementation](./src/main/java/elements/Broadcast.java). +- **[Button](https://docs.slack.dev/reference/block-kit/block-elements/button-element)**: Allows users a direct path to performing basic actions. [Implementation](./src/main/java/elements/Button.java). +- **[Channel](https://docs.slack.dev/reference/block-kit/block-elements/channel-element)**: Renders as a mention of a channel. [Implementation](./src/main/java/elements/Channel.java). +- **[Color](https://docs.slack.dev/reference/block-kit/block-elements/color-element)**: Displays a color swatch from a hex value. [Implementation](./src/main/java/elements/Color.java). +- **[Date](https://docs.slack.dev/reference/block-kit/block-elements/date-element)**: Displays a formatted, localized date. [Implementation](./src/main/java/elements/Date.java). +- **[Date picker](https://docs.slack.dev/reference/block-kit/block-elements/date-picker-element)**: Allows users to select a date from a calendar style UI. [Implementation](./src/main/java/elements/DatePicker.java). +- **[Datetime picker](https://docs.slack.dev/reference/block-kit/block-elements/datetime-picker-element)**: Allows users to select both a date and a time of day. [Implementation](./src/main/java/elements/DatetimePicker.java). +- **[Email input](https://docs.slack.dev/reference/block-kit/block-elements/email-input-element)**: Allows user to enter an email into a single-line field. [Implementation](./src/main/java/elements/EmailInput.java). +- **[Emoji](https://docs.slack.dev/reference/block-kit/block-elements/emoji-element)**: Displays an emoji. [Implementation](./src/main/java/elements/Emoji.java). +- **[Feedback buttons](https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element)**: Buttons to indicate positive or negative feedback. [Implementation](./src/main/java/elements/FeedbackButtons.java). +- **[File input](https://docs.slack.dev/reference/block-kit/block-elements/file-input-element)**: Allows user to upload files. [Implementation](./src/main/java/elements/FileInput.java). +- **[Icon button](https://docs.slack.dev/reference/block-kit/block-elements/icon-button-element)**: An icon button to perform actions. [Implementation](./src/main/java/elements/IconButton.java). +- **[Image](https://docs.slack.dev/reference/block-kit/block-elements/image-element)**: Displays an image as part of a larger block of content. [Implementation](./src/main/java/elements/Image.java). +- **[Link](https://docs.slack.dev/reference/block-kit/block-elements/link-element)**: Displays a hyperlink. [Implementation](./src/main/java/elements/Link.java). +- **[Multi-select menu](https://docs.slack.dev/reference/block-kit/block-elements/multi-select-menu-element)**: Allows users to select multiple items from a list of options. [Implementation](./src/main/java/elements/MultiSelectMenu.java). +- **[Number input](https://docs.slack.dev/reference/block-kit/block-elements/number-input-element)**: Allows user to enter a number into a single-line field. [Implementation](./src/main/java/elements/NumberInput.java). +- **[Overflow menu](https://docs.slack.dev/reference/block-kit/block-elements/overflow-menu-element)**: Allows users to press a button to view a list of options. [Implementation](./src/main/java/elements/OverflowMenu.java). +- **[Plain-text input](https://docs.slack.dev/reference/block-kit/block-elements/plain-text-input-element)**: Allows users to enter freeform text data into a single-line or multi-line field. [Implementation](./src/main/java/elements/PlainTextInput.java). +- **[Radio button group](https://docs.slack.dev/reference/block-kit/block-elements/radio-button-group-element)**: Allows users to choose one item from a list of possible options. [Implementation](./src/main/java/elements/RadioButtons.java). +- **[Rich text input](https://docs.slack.dev/reference/block-kit/block-elements/rich-text-input-element)**: Allows users to enter formatted text in a WYSIWYG composer, offering the same messaging writing experience as in Slack. [Implementation](./src/main/java/elements/RichTextInput.java). +- **[Rich text list](https://docs.slack.dev/reference/block-kit/block-elements/rich-text-list-element)**: Displays a list of rich text items. [Implementation](./src/main/java/elements/RichTextList.java). +- **[Rich text preformatted](https://docs.slack.dev/reference/block-kit/block-elements/rich-text-preformatted-element)**: Displays a preformatted rich text element. [Implementation](./src/main/java/elements/RichTextPreformatted.java). +- **[Rich text quote](https://docs.slack.dev/reference/block-kit/block-elements/rich-text-quote-element)**: Displays a rich text quote block. [Implementation](./src/main/java/elements/RichTextQuote.java). +- **[Rich text section](https://docs.slack.dev/reference/block-kit/block-elements/rich-text-section-element)**: A section element that holds rich text elements. [Implementation](./src/main/java/elements/RichTextSection.java). +- **[Select menu](https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element)**: Allows users to choose an option from a drop down menu. [Implementation](./src/main/java/elements/SelectMenu.java). +- **[Team](https://docs.slack.dev/reference/block-kit/block-elements/team-element)**: Renders as a mention of a workspace or team. [Implementation](./src/main/java/elements/Team.java). +- **[Text](https://docs.slack.dev/reference/block-kit/block-elements/text-element)**: Displays text, optionally with styling. [Implementation](./src/main/java/elements/Text.java). +- **[Time picker](https://docs.slack.dev/reference/block-kit/block-elements/time-picker-element)**: Allows users to enter numerical data into a single-line field. [Implementation](./src/main/java/elements/TimePicker.java). +- **[URL input](https://docs.slack.dev/reference/block-kit/block-elements/url-input-element)**: Allows user to enter a URL into a single-line field. [Implementation](./src/main/java/elements/UrlInput.java). +- **[User](https://docs.slack.dev/reference/block-kit/block-elements/user-element)**: Renders as a mention of a user. [Implementation](./src/main/java/elements/User.java). +- **[Usergroup](https://docs.slack.dev/reference/block-kit/block-elements/usergroup-element)**: Renders as a mention of a user group. [Implementation](./src/main/java/elements/UserGroup.java). +- **[Workflow button](https://docs.slack.dev/reference/block-kit/block-elements/workflow-button-element)**: Allows users to run a link trigger with customizable inputs. [Implementation](./src/main/java/elements/WorkflowButton.java). + diff --git a/block-kit/src/main/java/elements/Broadcast.java b/block-kit/src/main/java/elements/Broadcast.java new file mode 100644 index 0000000..ad57011 --- /dev/null +++ b/block-kit/src/main/java/elements/Broadcast.java @@ -0,0 +1,24 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Displays a broadcast mention such as here, channel, or everyone. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/broadcast-element/} + */ +public class Broadcast { + /** + * A rich text block with a broadcast mention in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Broadcast.builder() + .range("everyone") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/Button.java b/block-kit/src/main/java/elements/Button.java new file mode 100644 index 0000000..563d91d --- /dev/null +++ b/block-kit/src/main/java/elements/Button.java @@ -0,0 +1,62 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.markdownText; +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.LayoutBlock; +import com.slack.api.model.block.element.BlockElements; +import com.slack.api.model.block.element.ButtonElement; +import java.util.List; + +/** + * Allows users a direct path to performing basic actions. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/button-element/} + */ +public class Button { + /** + * A regular interactive button. + */ + public static ButtonElement example01() { + ButtonElement element = BlockElements.button( + b -> b.text(plainText("Click Me")).value("click_me_123").actionId("button")); + return element; + } + + /** + * A button with a primary style attribute. + */ + public static ButtonElement example02() { + ButtonElement element = BlockElements.button(b -> + b.text(plainText("Save")).style("primary").value("click_me_123").actionId("button")); + return element; + } + + /** + * A link button. + */ + public static ButtonElement example03() { + ButtonElement element = + BlockElements.button(b -> b.text(plainText("Link Button")).url("https://docs.slack.dev/block-kit")); + return element; + } + + /** + * The button element used inside either the section or actions block. + */ + public static List example05() { + List blocks = List.of( + Blocks.section(s -> s.text(markdownText("This is a section block with a button.")) + .accessory(BlockElements.button(b -> b.text(plainText("Click Me")) + .value("click_me_123") + .actionId("button")))), + Blocks.actions(a -> a.blockId("actionblock789") + .elements(List.of( + BlockElements.button(b -> b.text(plainText("Primary Button")) + .style("primary") + .value("click_me_456")), + BlockElements.button(b -> + b.text(plainText("Link Button")).url("https://api.slack.com/block-kit")))))); + return blocks; + } +} diff --git a/block-kit/src/main/java/elements/Channel.java b/block-kit/src/main/java/elements/Channel.java new file mode 100644 index 0000000..d91e74f --- /dev/null +++ b/block-kit/src/main/java/elements/Channel.java @@ -0,0 +1,24 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Renders as a mention of a channel. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/channel-element/} + */ +public class Channel { + /** + * A rich text block with a channel mention in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Channel.builder() + .channelId("C123ABC456") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/Color.java b/block-kit/src/main/java/elements/Color.java new file mode 100644 index 0000000..1bb5a23 --- /dev/null +++ b/block-kit/src/main/java/elements/Color.java @@ -0,0 +1,23 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Displays a color swatch from a hex value. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/color-element/} + */ +public class Color { + /** + * A rich text block with a color element in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of( + RichTextSectionElement.Color.builder().value("#F405B3").build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/Date.java b/block-kit/src/main/java/elements/Date.java new file mode 100644 index 0000000..7c3c9f5 --- /dev/null +++ b/block-kit/src/main/java/elements/Date.java @@ -0,0 +1,26 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Displays a formatted, localized date. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/date-element/} + */ +public class Date { + /** + * A rich text block with a date element in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Date.builder() + .timestamp(1720710212) + .format("{date_num} at {time}") + .fallback("timey") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/DatePicker.java b/block-kit/src/main/java/elements/DatePicker.java new file mode 100644 index 0000000..be415d6 --- /dev/null +++ b/block-kit/src/main/java/elements/DatePicker.java @@ -0,0 +1,26 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.markdownText; +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.model.block.element.BlockElements; + +/** + * Allows users to select a date from a calendar style UI. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/date-picker-element/} + */ +public class DatePicker { + /** + * A section block with a date picker accessory. + */ + public static SectionBlock example01() { + SectionBlock block = Blocks.section(s -> s.blockId("section1234") + .text(markdownText("Pick a date for the deadline.")) + .accessory(BlockElements.datePicker(d -> d.actionId("datepicker123") + .initialDate("1990-04-28") + .placeholder(plainText("Select a date"))))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/DatetimePicker.java b/block-kit/src/main/java/elements/DatetimePicker.java new file mode 100644 index 0000000..6019075 --- /dev/null +++ b/block-kit/src/main/java/elements/DatetimePicker.java @@ -0,0 +1,24 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.InputBlock; +import com.slack.api.model.block.element.BlockElements; + +/** + * Allows users to select both a date and a time of day. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/datetime-picker-element/} + */ +public class DatetimePicker { + /** + * An input block with a datetime picker element. + */ + public static InputBlock example01() { + InputBlock block = + Blocks.input(i -> i.element(BlockElements.datetimePicker(d -> d.actionId("datetimepicker-action"))) + .hint(plainText(pt -> pt.text("This is some hint text").emoji(true))) + .label(plainText(pt -> pt.text("Start date").emoji(true)))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/EmailInput.java b/block-kit/src/main/java/elements/EmailInput.java new file mode 100644 index 0000000..0b1ae85 --- /dev/null +++ b/block-kit/src/main/java/elements/EmailInput.java @@ -0,0 +1,24 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.InputBlock; +import com.slack.api.model.block.element.BlockElements; + +/** + * Allows user to enter an email into a single-line field. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/email-input-element/} + */ +public class EmailInput { + /** + * An input block with an email input element. + */ + public static InputBlock example01() { + InputBlock block = Blocks.input(i -> i.blockId("input123") + .label(plainText("Email Address")) + .element(BlockElements.emailTextInput( + e -> e.actionId("email_text_input-action").placeholder(plainText("Enter an email"))))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/Emoji.java b/block-kit/src/main/java/elements/Emoji.java new file mode 100644 index 0000000..2ce758b --- /dev/null +++ b/block-kit/src/main/java/elements/Emoji.java @@ -0,0 +1,33 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Displays an emoji. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/emoji-element/} + */ +public class Emoji { + /** + * A rich text block with emoji elements in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of( + RichTextSectionElement.Emoji.builder() + .name("basketball") + .build(), + RichTextSectionElement.Text.builder().text(" ").build(), + RichTextSectionElement.Emoji.builder() + .name("snowboarder") + .build(), + RichTextSectionElement.Text.builder().text(" ").build(), + RichTextSectionElement.Emoji.builder() + .name("checkered_flag") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/FeedbackButtons.java b/block-kit/src/main/java/elements/FeedbackButtons.java new file mode 100644 index 0000000..d071533 --- /dev/null +++ b/block-kit/src/main/java/elements/FeedbackButtons.java @@ -0,0 +1,34 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.ContextActionsBlock; +import com.slack.api.model.block.composition.FeedbackButtonObject; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * Buttons to indicate positive or negative feedback. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element/} + */ +public class FeedbackButtons { + /** + * A context actions block with feedback buttons. + */ + public static ContextActionsBlock example01() { + ContextActionsBlock block = + Blocks.contextActions(List.of(BlockElements.feedbackButtons(fb -> fb.actionId("feedback_buttons_1") + .positiveButton(FeedbackButtonObject.builder() + .text(plainText("Good")) + .value("positive_feedback") + .accessibilityLabel("Mark this response as good") + .build()) + .negativeButton(FeedbackButtonObject.builder() + .text(plainText("Bad")) + .value("negative_feedback") + .accessibilityLabel("Mark this response as bad") + .build())))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/FileInput.java b/block-kit/src/main/java/elements/FileInput.java new file mode 100644 index 0000000..e4e9ff6 --- /dev/null +++ b/block-kit/src/main/java/elements/FileInput.java @@ -0,0 +1,32 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.element.BlockElements; +import com.slack.api.model.view.View; +import com.slack.api.model.view.Views; +import java.util.List; + +/** + * Allows user to upload files. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/file-input-element/} + */ +public class FileInput { + /** + * A modal view with a file input element hosted in an input block. + */ + public static View example01() { + View view = Views.view(v -> v.type("modal") + .title(Views.viewTitle(t -> t.type("plain_text").text("My App").emoji(true))) + .submit(Views.viewSubmit( + s -> s.type("plain_text").text("Submit").emoji(true))) + .close(Views.viewClose(c -> c.type("plain_text").text("Cancel").emoji(true))) + .blocks(List.of(Blocks.input(i -> i.blockId("input_block_id") + .label(plainText("Upload Files")) + .element(BlockElements.fileInput(f -> f.actionId("file_input_action_id_1") + .filetypes(List.of("jpg", "png")) + .maxFiles(5))))))); + return view; + } +} diff --git a/block-kit/src/main/java/elements/IconButton.java b/block-kit/src/main/java/elements/IconButton.java new file mode 100644 index 0000000..055f8bb --- /dev/null +++ b/block-kit/src/main/java/elements/IconButton.java @@ -0,0 +1,25 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.ContextActionsBlock; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * An icon button to perform actions. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/icon-button-element/} + */ +public class IconButton { + /** + * A context actions block with an icon button. + */ + public static ContextActionsBlock example01() { + ContextActionsBlock block = Blocks.contextActions(List.of(BlockElements.iconButton(ib -> ib.icon("trash") + .text(plainText("Delete")) + .actionId("delete_button") + .value("delete_item")))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/Image.java b/block-kit/src/main/java/elements/Image.java new file mode 100644 index 0000000..723f1e3 --- /dev/null +++ b/block-kit/src/main/java/elements/Image.java @@ -0,0 +1,51 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.markdownText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.model.block.composition.SlackFileObject; +import com.slack.api.model.block.element.BlockElements; + +/** + * Displays an image as part of a larger block of content. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/image-element/} + */ +public class Image { + /** + * A section block with an image accessory using image_url. + */ + public static SectionBlock example01() { + SectionBlock block = Blocks.section(s -> s.blockId("section567") + .text(markdownText("This is a section block with an accessory image.")) + .accessory(BlockElements.image( + i -> i.imageUrl("https://pbs.twimg.com/profile_images/625633822235693056/lNGUneLX_400x400.jpg") + .altText("cute cat")))); + return block; + } + + /** + * An image block using slack_file with a url. + */ + public static SectionBlock example02() { + SectionBlock block = Blocks.section(s -> s.blockId("section567") + .text(markdownText("This is a section block with an accessory image.")) + .accessory(BlockElements.image(i -> i.slackFile(SlackFileObject.builder() + .url("https://files.slack.com/files-pri/T0123456-F0123456/xyz.png") + .build()) + .altText("Slack file object.")))); + return block; + } + + /** + * An image block using slack_file with a id. + */ + public static SectionBlock example03() { + SectionBlock block = Blocks.section(s -> s.blockId("section567") + .text(markdownText("This is a section block with an accessory image.")) + .accessory(BlockElements.image(i -> i.slackFile( + SlackFileObject.builder().id("F01234567").build()) + .altText("Slack file object.")))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/Link.java b/block-kit/src/main/java/elements/Link.java new file mode 100644 index 0000000..7c1f0e2 --- /dev/null +++ b/block-kit/src/main/java/elements/Link.java @@ -0,0 +1,24 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Displays a hyperlink. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/link-element/} + */ +public class Link { + /** + * A rich text block with a link element in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Link.builder() + .url("https://docs.slack.dev") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/MultiSelectMenu.java b/block-kit/src/main/java/elements/MultiSelectMenu.java new file mode 100644 index 0000000..048d570 --- /dev/null +++ b/block-kit/src/main/java/elements/MultiSelectMenu.java @@ -0,0 +1,85 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.markdownText; +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.model.block.composition.OptionObject; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * Allows users to select multiple items from a list of options. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/multi-select-menu-element/} + */ +public class MultiSelectMenu { + /** + * A section block containing a static multi-select menu. + */ + public static SectionBlock example01() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick items from the list")) + .accessory(BlockElements.multiStaticSelect(m -> m.actionId("text1234") + .placeholder(plainText("Select items")) + .options(List.of( + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-0") + .build(), + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-1") + .build(), + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-2") + .build()))))); + return block; + } + + /** + * A multi-select menu in a section block with an external data source. + */ + public static SectionBlock example02() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick items from the list")) + .accessory(BlockElements.multiExternalSelect(m -> m.actionId("text1234") + .placeholder(plainText("Select items")) + .minQueryLength(3)))); + return block; + } + + /** + * A multi-select menu in a section block showing a list of users. + */ + public static SectionBlock example03() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick users from the list")) + .accessory(BlockElements.multiUsersSelect( + m -> m.actionId("text1234").placeholder(plainText("Select users"))))); + return block; + } + + /** + * A multi-select menu in a section block showing a list of conversations. + */ + public static SectionBlock example04() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick conversations from the list")) + .accessory(BlockElements.multiConversationsSelect( + m -> m.actionId("text1234").placeholder(plainText("Select conversations"))))); + return block; + } + + /** + * A multi-select menu in a section block showing a list of channels. + */ + public static SectionBlock example05() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick channels from the list")) + .accessory(BlockElements.multiChannelsSelect( + m -> m.actionId("text1234").placeholder(plainText("Select channels"))))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/NumberInput.java b/block-kit/src/main/java/elements/NumberInput.java new file mode 100644 index 0000000..6beda5e --- /dev/null +++ b/block-kit/src/main/java/elements/NumberInput.java @@ -0,0 +1,23 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.InputBlock; +import com.slack.api.model.block.element.BlockElements; + +/** + * Allows user to enter a number into a single-line field. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/number-input-element/} + */ +public class NumberInput { + /** + * An input block with a number input element. + */ + public static InputBlock example01() { + InputBlock block = Blocks.input(i -> i.element( + BlockElements.numberInput(n -> n.decimalAllowed(false).actionId("number_input-action"))) + .label(plainText(pt -> pt.text("Label").emoji(true)))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/OverflowMenu.java b/block-kit/src/main/java/elements/OverflowMenu.java new file mode 100644 index 0000000..82edc31 --- /dev/null +++ b/block-kit/src/main/java/elements/OverflowMenu.java @@ -0,0 +1,47 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.markdownText; +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.model.block.composition.OptionObject; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * Allows users to press a button to view a list of options. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/overflow-menu-element/} + */ +public class OverflowMenu { + /** + * A section block with an overflow menu accessory. + */ + public static SectionBlock example01() { + SectionBlock block = Blocks.section(s -> s.blockId("section 890") + .text(markdownText("This is a section block with an overflow menu.")) + .accessory(BlockElements.overflowMenu(o -> o.actionId("overflow") + .options(List.of( + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-0") + .build(), + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-1") + .build(), + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-2") + .build(), + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-3") + .build(), + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-4") + .build()))))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/PlainTextInput.java b/block-kit/src/main/java/elements/PlainTextInput.java new file mode 100644 index 0000000..ffe0fba --- /dev/null +++ b/block-kit/src/main/java/elements/PlainTextInput.java @@ -0,0 +1,23 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.InputBlock; +import com.slack.api.model.block.element.BlockElements; + +/** + * Allows users to enter freeform text data into a single-line or multi-line field. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/plain-text-input-element/} + */ +public class PlainTextInput { + /** + * An input block with a plain-text input element. + */ + public static InputBlock example01() { + InputBlock block = + Blocks.input(i -> i.element(BlockElements.plainTextInput(pt -> pt.actionId("plain_text_input-action"))) + .label(plainText(l -> l.text("Label").emoji(true)))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/RadioButtons.java b/block-kit/src/main/java/elements/RadioButtons.java new file mode 100644 index 0000000..7737774 --- /dev/null +++ b/block-kit/src/main/java/elements/RadioButtons.java @@ -0,0 +1,37 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.model.block.composition.OptionObject; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * Allows users to choose one item from a list of possible options. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/radio-button-group-element/} + */ +public class RadioButtons { + /** + * A section block with a radio buttons accessory. + */ + public static SectionBlock example01() { + SectionBlock block = Blocks.section(s -> s.text(plainText("Check out these rad radio buttons")) + .accessory(BlockElements.radioButtons(r -> r.actionId("this_is_an_action_id") + .initialOption(OptionObject.builder() + .value("A1") + .text(plainText("Radio 1")) + .build()) + .options(List.of( + OptionObject.builder() + .value("A1") + .text(plainText("Radio 1")) + .build(), + OptionObject.builder() + .value("A2") + .text(plainText("Radio 2")) + .build()))))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/RichTextInput.java b/block-kit/src/main/java/elements/RichTextInput.java new file mode 100644 index 0000000..557164c --- /dev/null +++ b/block-kit/src/main/java/elements/RichTextInput.java @@ -0,0 +1,32 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.composition.DispatchActionConfig; +import com.slack.api.model.block.element.BlockElements; +import com.slack.api.model.view.View; +import com.slack.api.model.view.Views; +import java.util.List; + +/** + * Allows users to enter formatted text in a WYSIWYG composer, offering the same messaging writing experience as in + * Slack. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/rich-text-input-element/} + */ +public class RichTextInput { + /** + * A home view with an input block containing a rich text input element. + */ + public static View example01() { + View view = Views.view(v -> v.type("home").blocks(List.of(Blocks.input(i -> i.element( + BlockElements.richTextInput(rt -> rt.actionId("rich_text_input-action") + .dispatchActionConfig(DispatchActionConfig.builder() + .triggerActionsOn(List.of("on_character_entered")) + .build()) + .focusOnLoad(true) + .placeholder(plainText("Enter text")))) + .label(plainText(l -> l.text("Label").emoji(true))))))); + return view; + } +} diff --git a/block-kit/src/main/java/elements/RichTextList.java b/block-kit/src/main/java/elements/RichTextList.java new file mode 100644 index 0000000..d9f16d1 --- /dev/null +++ b/block-kit/src/main/java/elements/RichTextList.java @@ -0,0 +1,99 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextListElement; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Displays a list of rich text items. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/rich-text-list-element/} + */ +public class RichTextList { + /** + * A rich text block with a bulleted list. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.blockId("block1") + .elements(List.of( + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("My favorite Slack features (in no particular order):") + .build())) + .build(), + RichTextListElement.builder() + .style("bullet") + .indent(0) + .border(1) + .elements(List.of( + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Huddles") + .build())) + .build(), + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Canvas") + .build())) + .build(), + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Developing with Block Kit") + .build())) + .build())) + .build()))); + return block; + } + + /** + * A rich text block with nested bulleted lists using indent. + */ + public static RichTextBlock example02() { + RichTextBlock block = Blocks.richText(rt -> rt.blockId("block1") + .elements(List.of( + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Breakfast foods I enjoy:") + .build())) + .build(), + RichTextListElement.builder() + .style("bullet") + .elements(List.of( + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Hashbrowns") + .build())) + .build(), + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Eggs") + .build())) + .build())) + .build(), + RichTextListElement.builder() + .style("bullet") + .indent(1) + .elements(List.of( + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Scrambled") + .build())) + .build(), + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Over easy") + .build())) + .build())) + .build(), + RichTextListElement.builder() + .style("bullet") + .elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Pancakes, extra syrup") + .build())) + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/RichTextPreformatted.java b/block-kit/src/main/java/elements/RichTextPreformatted.java new file mode 100644 index 0000000..0699403 --- /dev/null +++ b/block-kit/src/main/java/elements/RichTextPreformatted.java @@ -0,0 +1,27 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextPreformattedElement; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Displays a preformatted rich text element. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/rich-text-preformatted-element/} + */ +public class RichTextPreformatted { + /** + * A rich text block with a preformatted code section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextPreformattedElement.builder() + .border(0) + .elements(List.of(RichTextSectionElement.Text.builder() + .text( + "{\n \"object\": {\n \"description\": \"this is an example of a json object\"\n }\n}") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/RichTextQuote.java b/block-kit/src/main/java/elements/RichTextQuote.java new file mode 100644 index 0000000..7d7492d --- /dev/null +++ b/block-kit/src/main/java/elements/RichTextQuote.java @@ -0,0 +1,32 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextQuoteElement; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Displays a rich text quote block. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/rich-text-quote-element/} + */ +public class RichTextQuote { + /** + * A rich text block with a quote followed by a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.blockId("Vrzsu") + .elements(List.of( + RichTextQuoteElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("What we need is good examples in our documentation.") + .build())) + .build(), + RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Yes - I completely agree, Luke!") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/RichTextSection.java b/block-kit/src/main/java/elements/RichTextSection.java new file mode 100644 index 0000000..91f91e2 --- /dev/null +++ b/block-kit/src/main/java/elements/RichTextSection.java @@ -0,0 +1,56 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import com.slack.api.model.block.element.RichTextSectionElement.TextStyle; +import java.util.List; + +/** + * A section element that holds rich text elements. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/rich-text-section-element/} + */ +public class RichTextSection { + /** + * Rich text blocks showing basic, bold, italic, and strikethrough text sections. + */ + public static List example01() { + List blocks = List.of( + Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Text.builder() + .text("Hello there, I am a basic rich text block!") + .build())) + .build()))), + Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of( + RichTextSectionElement.Text.builder() + .text("Hello there, ") + .build(), + RichTextSectionElement.Text.builder() + .text("I am a bold rich text block!") + .style(TextStyle.builder().bold(true).build()) + .build())) + .build()))), + Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of( + RichTextSectionElement.Text.builder() + .text("Hello there, ") + .build(), + RichTextSectionElement.Text.builder() + .text("I am an italic rich text block!") + .style(TextStyle.builder().italic(true).build()) + .build())) + .build()))), + Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of( + RichTextSectionElement.Text.builder() + .text("Hello there, ") + .build(), + RichTextSectionElement.Text.builder() + .text("I am a strikethrough rich text block!") + .style(TextStyle.builder().strike(true).build()) + .build())) + .build())))); + return blocks; + } +} diff --git a/block-kit/src/main/java/elements/SelectMenu.java b/block-kit/src/main/java/elements/SelectMenu.java new file mode 100644 index 0000000..cae91e4 --- /dev/null +++ b/block-kit/src/main/java/elements/SelectMenu.java @@ -0,0 +1,85 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.markdownText; +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.model.block.composition.OptionObject; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * Allows users to choose an option from a drop down menu. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element/} + */ +public class SelectMenu { + /** + * A section block with a static select menu accessory. + */ + public static SectionBlock example01() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick an item from the dropdown list")) + .accessory(BlockElements.staticSelect(m -> m.actionId("text1234") + .placeholder(plainText("Select an item")) + .options(List.of( + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-0") + .build(), + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-1") + .build(), + OptionObject.builder() + .text(plainText("*this is plain_text text*")) + .value("value-2") + .build()))))); + return block; + } + + /** + * A section block with an external select menu accessory. + */ + public static SectionBlock example02() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick an item from the dropdown list")) + .accessory(BlockElements.externalSelect(m -> m.actionId("text1234") + .placeholder(plainText("Select an item")) + .minQueryLength(3)))); + return block; + } + + /** + * A section block with a users select menu accessory. + */ + public static SectionBlock example03() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick a user from the dropdown list")) + .accessory(BlockElements.usersSelect( + m -> m.actionId("text1234").placeholder(plainText("Select an item"))))); + return block; + } + + /** + * A section block with a conversations select menu accessory. + */ + public static SectionBlock example04() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick a conversation from the dropdown list")) + .accessory(BlockElements.conversationsSelect( + m -> m.actionId("text1234").placeholder(plainText("Select an item"))))); + return block; + } + + /** + * A section block with a channels select menu accessory. + */ + public static SectionBlock example05() { + SectionBlock block = Blocks.section(s -> s.blockId("section678") + .text(markdownText("Pick a channel from the dropdown list")) + .accessory(BlockElements.channelsSelect( + m -> m.actionId("text1234").placeholder(plainText("Select an item"))))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/Team.java b/block-kit/src/main/java/elements/Team.java new file mode 100644 index 0000000..e14d090 --- /dev/null +++ b/block-kit/src/main/java/elements/Team.java @@ -0,0 +1,24 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Renders as a mention of a workspace or team. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/team-element/} + */ +public class Team { + /** + * A rich text block with a team mention in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.Team.builder() + .teamId("T123ABC456") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/Text.java b/block-kit/src/main/java/elements/Text.java new file mode 100644 index 0000000..851e0eb --- /dev/null +++ b/block-kit/src/main/java/elements/Text.java @@ -0,0 +1,30 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import com.slack.api.model.block.element.RichTextSectionElement.TextStyle; +import java.util.List; + +/** + * Displays text, optionally with styling. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/text-element/} + */ +public class Text { + /** + * A rich text block with plain and bold text elements in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of( + RichTextSectionElement.Text.builder() + .text("Hello there, ") + .build(), + RichTextSectionElement.Text.builder() + .text("I am a bold rich text block!") + .style(TextStyle.builder().bold(true).build()) + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/TimePicker.java b/block-kit/src/main/java/elements/TimePicker.java new file mode 100644 index 0000000..be058c7 --- /dev/null +++ b/block-kit/src/main/java/elements/TimePicker.java @@ -0,0 +1,27 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.markdownText; +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.model.block.element.BlockElements; + +/** + * Allows users to enter numerical data into a single-line field. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/time-picker-element/} + */ +public class TimePicker { + /** + * A section block with a time picker accessory. + */ + public static SectionBlock example01() { + SectionBlock block = Blocks.section(s -> s.blockId("section1234") + .text(markdownText("Pick a date for the deadline.")) + .accessory(BlockElements.timePicker(t -> t.timezone("America/Los_Angeles") + .actionId("timepicker123") + .initialTime("11:40") + .placeholder(plainText("Select a time"))))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/UrlInput.java b/block-kit/src/main/java/elements/UrlInput.java new file mode 100644 index 0000000..cbdeef4 --- /dev/null +++ b/block-kit/src/main/java/elements/UrlInput.java @@ -0,0 +1,23 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.InputBlock; +import com.slack.api.model.block.element.BlockElements; + +/** + * Allows user to enter a URL into a single-line field. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/url-input-element/} + */ +public class UrlInput { + /** + * An input block with a URL input element. + */ + public static InputBlock example01() { + InputBlock block = + Blocks.input(i -> i.element(BlockElements.urlTextInput(u -> u.actionId("url_text_input-action"))) + .label(plainText(pt -> pt.text("Label").emoji(true)))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/User.java b/block-kit/src/main/java/elements/User.java new file mode 100644 index 0000000..690e0ca --- /dev/null +++ b/block-kit/src/main/java/elements/User.java @@ -0,0 +1,24 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Renders as a mention of a user. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/user-element/} + */ +public class User { + /** + * A rich text block with a user mention in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.User.builder() + .userId("U123ABC456") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/UserGroup.java b/block-kit/src/main/java/elements/UserGroup.java new file mode 100644 index 0000000..d5dcd51 --- /dev/null +++ b/block-kit/src/main/java/elements/UserGroup.java @@ -0,0 +1,24 @@ +package elements; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.model.block.element.RichTextSectionElement; +import java.util.List; + +/** + * Renders as a mention of a user group. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/usergroup-element/} + */ +public class UserGroup { + /** + * A rich text block with a user group mention in a section. + */ + public static RichTextBlock example01() { + RichTextBlock block = Blocks.richText(rt -> rt.elements(List.of(RichTextSectionElement.builder() + .elements(List.of(RichTextSectionElement.UserGroup.builder() + .usergroupId("G123ABC456") + .build())) + .build()))); + return block; + } +} diff --git a/block-kit/src/main/java/elements/WorkflowButton.java b/block-kit/src/main/java/elements/WorkflowButton.java new file mode 100644 index 0000000..6a3c192 --- /dev/null +++ b/block-kit/src/main/java/elements/WorkflowButton.java @@ -0,0 +1,41 @@ +package elements; + +import static com.slack.api.model.block.composition.BlockCompositions.markdownText; +import static com.slack.api.model.block.composition.BlockCompositions.plainText; + +import com.slack.api.model.block.Blocks; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.model.block.composition.WorkflowObject; +import com.slack.api.model.block.element.BlockElements; +import java.util.List; + +/** + * Allows users to run a link trigger with customizable inputs. + * {@link https://docs.slack.dev/reference/block-kit/block-elements/workflow-button-element/} + */ +public class WorkflowButton { + /** + * A section block containing a workflow button element. + */ + public static SectionBlock example01() { + SectionBlock block = + Blocks.section(s -> s.text(markdownText("A message *with some bold text* and _some italicized text_.")) + .accessory(BlockElements.workflowButton(w -> w.text(plainText("Run Workflow")) + .actionId("workflowbutton123") + .workflow(WorkflowObject.builder() + .trigger(WorkflowObject.Trigger.builder() + .url("https://slack.com/shortcuts/Ft0123ABC456/xyz...zyx") + .customizableInputParameters(List.of( + WorkflowObject.Trigger.InputParameter.builder() + .name("input_parameter_a") + .value("Value for input param A") + .build(), + WorkflowObject.Trigger.InputParameter.builder() + .name("input_parameter_b") + .value("Value for input param B") + .build())) + .build()) + .build())))); + return block; + } +} diff --git a/block-kit/src/test/java/elements/BroadcastTest.java b/block-kit/src/test/java/elements/BroadcastTest.java new file mode 100644 index 0000000..e1567ed --- /dev/null +++ b/block-kit/src/test/java/elements/BroadcastTest.java @@ -0,0 +1,33 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class BroadcastTest { + @Test + public void testExample01() { + RichTextBlock block = Broadcast.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "broadcast", + "range": "everyone" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/ButtonTest.java b/block-kit/src/test/java/elements/ButtonTest.java new file mode 100644 index 0000000..cbae6c6 --- /dev/null +++ b/block-kit/src/test/java/elements/ButtonTest.java @@ -0,0 +1,116 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.LayoutBlock; +import com.slack.api.model.block.element.ButtonElement; +import com.slack.api.util.json.GsonFactory; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class ButtonTest { + @Test + public void testExample01() { + ButtonElement element = Button.example01(); + String actual = GsonFactory.createSnakeCase().toJson(element); + String expected = """ + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Click Me" + }, + "value": "click_me_123", + "action_id": "button" + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample02() { + ButtonElement element = Button.example02(); + String actual = GsonFactory.createSnakeCase().toJson(element); + String expected = """ + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Save" + }, + "style": "primary", + "value": "click_me_123", + "action_id": "button" + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample03() { + ButtonElement element = Button.example03(); + String actual = GsonFactory.createSnakeCase().toJson(element); + String expected = """ + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Link Button" + }, + "url": "https://docs.slack.dev/block-kit" + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample05() { + List blocks = Button.example05(); + String actual = GsonFactory.createSnakeCase().toJson(blocks); + String expected = """ + [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "This is a section block with a button." + }, + "accessory": { + "type": "button", + "text": { + "type": "plain_text", + "text": "Click Me" + }, + "value": "click_me_123", + "action_id": "button" + } + }, + { + "type": "actions", + "block_id": "actionblock789", + "elements": [ + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Primary Button" + }, + "style": "primary", + "value": "click_me_456" + }, + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Link Button" + }, + "url": "https://api.slack.com/block-kit" + } + ] + } + ] + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/ChannelTest.java b/block-kit/src/test/java/elements/ChannelTest.java new file mode 100644 index 0000000..0f9baae --- /dev/null +++ b/block-kit/src/test/java/elements/ChannelTest.java @@ -0,0 +1,33 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class ChannelTest { + @Test + public void testExample01() { + RichTextBlock block = Channel.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "channel", + "channel_id": "C123ABC456" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/ColorTest.java b/block-kit/src/test/java/elements/ColorTest.java new file mode 100644 index 0000000..c96731e --- /dev/null +++ b/block-kit/src/test/java/elements/ColorTest.java @@ -0,0 +1,33 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class ColorTest { + @Test + public void testExample01() { + RichTextBlock block = Color.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "color", + "value": "#F405B3" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/DatePickerTest.java b/block-kit/src/test/java/elements/DatePickerTest.java new file mode 100644 index 0000000..60750ca --- /dev/null +++ b/block-kit/src/test/java/elements/DatePickerTest.java @@ -0,0 +1,36 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class DatePickerTest { + @Test + public void testExample01() { + SectionBlock block = DatePicker.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section1234", + "text": { + "type": "mrkdwn", + "text": "Pick a date for the deadline." + }, + "accessory": { + "type": "datepicker", + "action_id": "datepicker123", + "initial_date": "1990-04-28", + "placeholder": { + "type": "plain_text", + "text": "Select a date" + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/DateTest.java b/block-kit/src/test/java/elements/DateTest.java new file mode 100644 index 0000000..7cbeab7 --- /dev/null +++ b/block-kit/src/test/java/elements/DateTest.java @@ -0,0 +1,35 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class DateTest { + @Test + public void testExample01() { + RichTextBlock block = Date.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "date", + "timestamp": 1720710212, + "format": "{date_num} at {time}", + "fallback": "timey" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/DatetimePickerTest.java b/block-kit/src/test/java/elements/DatetimePickerTest.java new file mode 100644 index 0000000..f29581d --- /dev/null +++ b/block-kit/src/test/java/elements/DatetimePickerTest.java @@ -0,0 +1,37 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.InputBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class DatetimePickerTest { + @Test + public void testExample01() { + InputBlock block = DatetimePicker.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "input", + "element": { + "type": "datetimepicker", + "action_id": "datetimepicker-action" + }, + "hint": { + "type": "plain_text", + "text": "This is some hint text", + "emoji": true + }, + "label": { + "type": "plain_text", + "text": "Start date", + "emoji": true + }, + "optional": false + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/EmailInputTest.java b/block-kit/src/test/java/elements/EmailInputTest.java new file mode 100644 index 0000000..ecdaf09 --- /dev/null +++ b/block-kit/src/test/java/elements/EmailInputTest.java @@ -0,0 +1,36 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.InputBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class EmailInputTest { + @Test + public void testExample01() { + InputBlock block = EmailInput.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "input", + "block_id": "input123", + "label": { + "type": "plain_text", + "text": "Email Address" + }, + "element": { + "type": "email_text_input", + "action_id": "email_text_input-action", + "placeholder": { + "type": "plain_text", + "text": "Enter an email" + } + }, + "optional": false + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/EmojiTest.java b/block-kit/src/test/java/elements/EmojiTest.java new file mode 100644 index 0000000..8bf0e13 --- /dev/null +++ b/block-kit/src/test/java/elements/EmojiTest.java @@ -0,0 +1,49 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class EmojiTest { + @Test + public void testExample01() { + RichTextBlock block = Emoji.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "emoji", + "name": "basketball" + }, + { + "type": "text", + "text": " " + }, + { + "type": "emoji", + "name": "snowboarder" + }, + { + "type": "text", + "text": " " + }, + { + "type": "emoji", + "name": "checkered_flag" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/FeedbackButtonsTest.java b/block-kit/src/test/java/elements/FeedbackButtonsTest.java new file mode 100644 index 0000000..c9482fe --- /dev/null +++ b/block-kit/src/test/java/elements/FeedbackButtonsTest.java @@ -0,0 +1,44 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.ContextActionsBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class FeedbackButtonsTest { + @Test + public void testExample01() { + ContextActionsBlock block = FeedbackButtons.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "context_actions", + "elements": [ + { + "type": "feedback_buttons", + "action_id": "feedback_buttons_1", + "positive_button": { + "text": { + "type": "plain_text", + "text": "Good" + }, + "value": "positive_feedback", + "accessibility_label": "Mark this response as good" + }, + "negative_button": { + "text": { + "type": "plain_text", + "text": "Bad" + }, + "value": "negative_feedback", + "accessibility_label": "Mark this response as bad" + } + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/FileInputTest.java b/block-kit/src/test/java/elements/FileInputTest.java new file mode 100644 index 0000000..22db5b1 --- /dev/null +++ b/block-kit/src/test/java/elements/FileInputTest.java @@ -0,0 +1,54 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.view.View; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class FileInputTest { + @Test + public void testExample01() { + View view = FileInput.example01(); + String actual = GsonFactory.createSnakeCase().toJson(view); + String expected = """ + { + "type": "modal", + "title": { + "type": "plain_text", + "text": "My App", + "emoji": true + }, + "submit": { + "type": "plain_text", + "text": "Submit", + "emoji": true + }, + "close": { + "type": "plain_text", + "text": "Cancel", + "emoji": true + }, + "blocks": [ + { + "type": "input", + "block_id": "input_block_id", + "label": { + "type": "plain_text", + "text": "Upload Files" + }, + "element": { + "type": "file_input", + "action_id": "file_input_action_id_1", + "filetypes": ["jpg", "png"], + "max_files": 5 + }, + "optional": false + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/IconButtonTest.java b/block-kit/src/test/java/elements/IconButtonTest.java new file mode 100644 index 0000000..396ba71 --- /dev/null +++ b/block-kit/src/test/java/elements/IconButtonTest.java @@ -0,0 +1,34 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.ContextActionsBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class IconButtonTest { + @Test + public void testExample01() { + ContextActionsBlock block = IconButton.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "context_actions", + "elements": [ + { + "type": "icon_button", + "icon": "trash", + "text": { + "type": "plain_text", + "text": "Delete" + }, + "action_id": "delete_button", + "value": "delete_item" + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/ImageTest.java b/block-kit/src/test/java/elements/ImageTest.java new file mode 100644 index 0000000..6d388f0 --- /dev/null +++ b/block-kit/src/test/java/elements/ImageTest.java @@ -0,0 +1,80 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class ImageTest { + @Test + public void testExample01() { + SectionBlock block = Image.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section567", + "text": { + "type": "mrkdwn", + "text": "This is a section block with an accessory image." + }, + "accessory": { + "type": "image", + "image_url": "https://pbs.twimg.com/profile_images/625633822235693056/lNGUneLX_400x400.jpg", + "alt_text": "cute cat" + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample02() { + SectionBlock block = Image.example02(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section567", + "text": { + "type": "mrkdwn", + "text": "This is a section block with an accessory image." + }, + "accessory": { + "type": "image", + "slack_file": { + "url": "https://files.slack.com/files-pri/T0123456-F0123456/xyz.png" + }, + "alt_text": "Slack file object." + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample03() { + SectionBlock block = Image.example03(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section567", + "text": { + "type": "mrkdwn", + "text": "This is a section block with an accessory image." + }, + "accessory": { + "type": "image", + "slack_file": { + "id": "F01234567" + }, + "alt_text": "Slack file object." + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/LinkTest.java b/block-kit/src/test/java/elements/LinkTest.java new file mode 100644 index 0000000..c6b84c3 --- /dev/null +++ b/block-kit/src/test/java/elements/LinkTest.java @@ -0,0 +1,33 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class LinkTest { + @Test + public void testExample01() { + RichTextBlock block = Link.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "link", + "url": "https://docs.slack.dev" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/MultiSelectMenuTest.java b/block-kit/src/test/java/elements/MultiSelectMenuTest.java new file mode 100644 index 0000000..9dc3657 --- /dev/null +++ b/block-kit/src/test/java/elements/MultiSelectMenuTest.java @@ -0,0 +1,159 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class MultiSelectMenuTest { + @Test + public void testExample01() { + SectionBlock block = MultiSelectMenu.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick items from the list" + }, + "accessory": { + "action_id": "text1234", + "type": "multi_static_select", + "placeholder": { + "type": "plain_text", + "text": "Select items" + }, + "options": [ + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-0" + }, + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-1" + }, + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-2" + } + ] + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample02() { + SectionBlock block = MultiSelectMenu.example02(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick items from the list" + }, + "accessory": { + "action_id": "text1234", + "type": "multi_external_select", + "placeholder": { + "type": "plain_text", + "text": "Select items" + }, + "min_query_length": 3 + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample03() { + SectionBlock block = MultiSelectMenu.example03(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick users from the list" + }, + "accessory": { + "action_id": "text1234", + "type": "multi_users_select", + "placeholder": { + "type": "plain_text", + "text": "Select users" + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample04() { + SectionBlock block = MultiSelectMenu.example04(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick conversations from the list" + }, + "accessory": { + "action_id": "text1234", + "type": "multi_conversations_select", + "placeholder": { + "type": "plain_text", + "text": "Select conversations" + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample05() { + SectionBlock block = MultiSelectMenu.example05(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick channels from the list" + }, + "accessory": { + "action_id": "text1234", + "type": "multi_channels_select", + "placeholder": { + "type": "plain_text", + "text": "Select channels" + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/NumberInputTest.java b/block-kit/src/test/java/elements/NumberInputTest.java new file mode 100644 index 0000000..601d8e6 --- /dev/null +++ b/block-kit/src/test/java/elements/NumberInputTest.java @@ -0,0 +1,33 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.InputBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class NumberInputTest { + @Test + public void testExample01() { + InputBlock block = NumberInput.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "input", + "element": { + "type": "number_input", + "is_decimal_allowed": false, + "action_id": "number_input-action" + }, + "label": { + "type": "plain_text", + "text": "Label", + "emoji": true + }, + "optional": false + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/OverflowMenuTest.java b/block-kit/src/test/java/elements/OverflowMenuTest.java new file mode 100644 index 0000000..4ab253d --- /dev/null +++ b/block-kit/src/test/java/elements/OverflowMenuTest.java @@ -0,0 +1,68 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class OverflowMenuTest { + @Test + public void testExample01() { + SectionBlock block = OverflowMenu.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section 890", + "text": { + "type": "mrkdwn", + "text": "This is a section block with an overflow menu." + }, + "accessory": { + "type": "overflow", + "action_id": "overflow", + "options": [ + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-0" + }, + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-1" + }, + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-2" + }, + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-3" + }, + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-4" + } + ] + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/PlainTextInputTest.java b/block-kit/src/test/java/elements/PlainTextInputTest.java new file mode 100644 index 0000000..008916f --- /dev/null +++ b/block-kit/src/test/java/elements/PlainTextInputTest.java @@ -0,0 +1,33 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.InputBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class PlainTextInputTest { + @Test + public void testExample01() { + InputBlock block = PlainTextInput.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "input", + "element": { + "type": "plain_text_input", + "action_id": "plain_text_input-action", + "multiline": false + }, + "label": { + "type": "plain_text", + "text": "Label", + "emoji": true + }, + "optional": false + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/RadioButtonsTest.java b/block-kit/src/test/java/elements/RadioButtonsTest.java new file mode 100644 index 0000000..959419e --- /dev/null +++ b/block-kit/src/test/java/elements/RadioButtonsTest.java @@ -0,0 +1,53 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class RadioButtonsTest { + @Test + public void testExample01() { + SectionBlock block = RadioButtons.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "text": { + "type": "plain_text", + "text": "Check out these rad radio buttons" + }, + "accessory": { + "type": "radio_buttons", + "action_id": "this_is_an_action_id", + "initial_option": { + "value": "A1", + "text": { + "type": "plain_text", + "text": "Radio 1" + } + }, + "options": [ + { + "value": "A1", + "text": { + "type": "plain_text", + "text": "Radio 1" + } + }, + { + "value": "A2", + "text": { + "type": "plain_text", + "text": "Radio 2" + } + } + ] + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/RichTextInputTest.java b/block-kit/src/test/java/elements/RichTextInputTest.java new file mode 100644 index 0000000..d32c94d --- /dev/null +++ b/block-kit/src/test/java/elements/RichTextInputTest.java @@ -0,0 +1,47 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.view.View; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class RichTextInputTest { + @Test + public void testExample01() { + View view = RichTextInput.example01(); + String actual = GsonFactory.createSnakeCase().toJson(view); + String expected = """ + { + "type": "home", + "blocks": [ + { + "type": "input", + "element": { + "type": "rich_text_input", + "action_id": "rich_text_input-action", + "dispatch_action_config": { + "trigger_actions_on": [ + "on_character_entered" + ] + }, + "focus_on_load": true, + "placeholder": { + "type": "plain_text", + "text": "Enter text" + } + }, + "label": { + "type": "plain_text", + "text": "Label", + "emoji": true + }, + "optional": false + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/RichTextListTest.java b/block-kit/src/test/java/elements/RichTextListTest.java new file mode 100644 index 0000000..6fddb86 --- /dev/null +++ b/block-kit/src/test/java/elements/RichTextListTest.java @@ -0,0 +1,157 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class RichTextListTest { + @Test + public void testExample01() { + RichTextBlock block = RichTextList.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "block_id": "block1", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "My favorite Slack features (in no particular order):" + } + ] + }, + { + "type": "rich_text_list", + "style": "bullet", + "indent": 0, + "border": 1, + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Huddles" + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Canvas" + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Developing with Block Kit" + } + ] + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample02() { + RichTextBlock block = RichTextList.example02(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "block_id": "block1", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Breakfast foods I enjoy:" + } + ] + }, + { + "type": "rich_text_list", + "style": "bullet", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Hashbrowns" + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Eggs" + } + ] + } + ] + }, + { + "type": "rich_text_list", + "style": "bullet", + "indent": 1, + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Scrambled" + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Over easy" + } + ] + } + ] + }, + { + "type": "rich_text_list", + "style": "bullet", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Pancakes, extra syrup" + } + ] + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/RichTextPreformattedTest.java b/block-kit/src/test/java/elements/RichTextPreformattedTest.java new file mode 100644 index 0000000..4ae915c --- /dev/null +++ b/block-kit/src/test/java/elements/RichTextPreformattedTest.java @@ -0,0 +1,34 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class RichTextPreformattedTest { + @Test + public void testExample01() { + RichTextBlock block = RichTextPreformatted.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_preformatted", + "border": 0, + "elements": [ + { + "type": "text", + "text": "{\\n \\"object\\": {\\n \\"description\\": \\"this is an example of a json object\\"\\n }\\n}" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/RichTextQuoteTest.java b/block-kit/src/test/java/elements/RichTextQuoteTest.java new file mode 100644 index 0000000..aa0264d --- /dev/null +++ b/block-kit/src/test/java/elements/RichTextQuoteTest.java @@ -0,0 +1,43 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class RichTextQuoteTest { + @Test + public void testExample01() { + RichTextBlock block = RichTextQuote.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "block_id": "Vrzsu", + "elements": [ + { + "type": "rich_text_quote", + "elements": [ + { + "type": "text", + "text": "What we need is good examples in our documentation." + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Yes - I completely agree, Luke!" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/RichTextSectionTest.java b/block-kit/src/test/java/elements/RichTextSectionTest.java new file mode 100644 index 0000000..91b7afe --- /dev/null +++ b/block-kit/src/test/java/elements/RichTextSectionTest.java @@ -0,0 +1,120 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class RichTextSectionTest { + @Test + public void testExample01() { + List blocks = RichTextSection.example01(); + String actual = GsonFactory.createSnakeCase().toJson(blocks); + String expected = """ + [ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Hello there, I am a basic rich text block!" + } + ] + } + ] + }, + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Hello there, " + }, + { + "type": "text", + "text": "I am a bold rich text block!", + "style": { + "bold": true, + "italic": false, + "strike": false, + "highlight": false, + "client_highlight": false, + "underline": false, + "unlink": false, + "code": false + } + } + ] + } + ] + }, + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Hello there, " + }, + { + "type": "text", + "text": "I am an italic rich text block!", + "style": { + "bold": false, + "italic": true, + "strike": false, + "highlight": false, + "client_highlight": false, + "underline": false, + "unlink": false, + "code": false + } + } + ] + } + ] + }, + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Hello there, " + }, + { + "type": "text", + "text": "I am a strikethrough rich text block!", + "style": { + "bold": false, + "italic": false, + "strike": true, + "highlight": false, + "client_highlight": false, + "underline": false, + "unlink": false, + "code": false + } + } + ] + } + ] + } + ] + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/SelectMenuTest.java b/block-kit/src/test/java/elements/SelectMenuTest.java new file mode 100644 index 0000000..e0fa0d6 --- /dev/null +++ b/block-kit/src/test/java/elements/SelectMenuTest.java @@ -0,0 +1,159 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class SelectMenuTest { + @Test + public void testExample01() { + SectionBlock block = SelectMenu.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick an item from the dropdown list" + }, + "accessory": { + "action_id": "text1234", + "type": "static_select", + "placeholder": { + "type": "plain_text", + "text": "Select an item" + }, + "options": [ + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-0" + }, + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-1" + }, + { + "text": { + "type": "plain_text", + "text": "*this is plain_text text*" + }, + "value": "value-2" + } + ] + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample02() { + SectionBlock block = SelectMenu.example02(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick an item from the dropdown list" + }, + "accessory": { + "action_id": "text1234", + "type": "external_select", + "placeholder": { + "type": "plain_text", + "text": "Select an item" + }, + "min_query_length": 3 + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample03() { + SectionBlock block = SelectMenu.example03(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick a user from the dropdown list" + }, + "accessory": { + "action_id": "text1234", + "type": "users_select", + "placeholder": { + "type": "plain_text", + "text": "Select an item" + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample04() { + SectionBlock block = SelectMenu.example04(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick a conversation from the dropdown list" + }, + "accessory": { + "action_id": "text1234", + "type": "conversations_select", + "placeholder": { + "type": "plain_text", + "text": "Select an item" + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } + + @Test + public void testExample05() { + SectionBlock block = SelectMenu.example05(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section678", + "text": { + "type": "mrkdwn", + "text": "Pick a channel from the dropdown list" + }, + "accessory": { + "action_id": "text1234", + "type": "channels_select", + "placeholder": { + "type": "plain_text", + "text": "Select an item" + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/TeamTest.java b/block-kit/src/test/java/elements/TeamTest.java new file mode 100644 index 0000000..fc3cc50 --- /dev/null +++ b/block-kit/src/test/java/elements/TeamTest.java @@ -0,0 +1,33 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class TeamTest { + @Test + public void testExample01() { + RichTextBlock block = Team.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "team", + "team_id": "T123ABC456" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/TextTest.java b/block-kit/src/test/java/elements/TextTest.java new file mode 100644 index 0000000..e6e00b5 --- /dev/null +++ b/block-kit/src/test/java/elements/TextTest.java @@ -0,0 +1,47 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class TextTest { + @Test + public void testExample01() { + RichTextBlock block = Text.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Hello there, " + }, + { + "type": "text", + "text": "I am a bold rich text block!", + "style": { + "bold": true, + "italic": false, + "strike": false, + "highlight": false, + "client_highlight": false, + "underline": false, + "unlink": false, + "code": false + } + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/TimePickerTest.java b/block-kit/src/test/java/elements/TimePickerTest.java new file mode 100644 index 0000000..4e4df73 --- /dev/null +++ b/block-kit/src/test/java/elements/TimePickerTest.java @@ -0,0 +1,37 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class TimePickerTest { + @Test + public void testExample01() { + SectionBlock block = TimePicker.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "block_id": "section1234", + "text": { + "type": "mrkdwn", + "text": "Pick a date for the deadline." + }, + "accessory": { + "type": "timepicker", + "timezone": "America/Los_Angeles", + "action_id": "timepicker123", + "initial_time": "11:40", + "placeholder": { + "type": "plain_text", + "text": "Select a time" + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/UrlInputTest.java b/block-kit/src/test/java/elements/UrlInputTest.java new file mode 100644 index 0000000..74ef73a --- /dev/null +++ b/block-kit/src/test/java/elements/UrlInputTest.java @@ -0,0 +1,32 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.InputBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class UrlInputTest { + @Test + public void testExample01() { + InputBlock block = UrlInput.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "input", + "element": { + "type": "url_text_input", + "action_id": "url_text_input-action" + }, + "label": { + "type": "plain_text", + "text": "Label", + "emoji": true + }, + "optional": false + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/UserGroupTest.java b/block-kit/src/test/java/elements/UserGroupTest.java new file mode 100644 index 0000000..17c055e --- /dev/null +++ b/block-kit/src/test/java/elements/UserGroupTest.java @@ -0,0 +1,33 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class UserGroupTest { + @Test + public void testExample01() { + RichTextBlock block = UserGroup.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "usergroup", + "usergroup_id": "G123ABC456" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/UserTest.java b/block-kit/src/test/java/elements/UserTest.java new file mode 100644 index 0000000..b6be589 --- /dev/null +++ b/block-kit/src/test/java/elements/UserTest.java @@ -0,0 +1,33 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.RichTextBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class UserTest { + @Test + public void testExample01() { + RichTextBlock block = User.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "user", + "user_id": "U123ABC456" + } + ] + } + ] + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +} diff --git a/block-kit/src/test/java/elements/WorkflowButtonTest.java b/block-kit/src/test/java/elements/WorkflowButtonTest.java new file mode 100644 index 0000000..519351a --- /dev/null +++ b/block-kit/src/test/java/elements/WorkflowButtonTest.java @@ -0,0 +1,49 @@ +package elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonParser; +import com.slack.api.model.block.SectionBlock; +import com.slack.api.util.json.GsonFactory; +import org.junit.jupiter.api.Test; + +public class WorkflowButtonTest { + @Test + public void testExample01() { + SectionBlock block = WorkflowButton.example01(); + String actual = GsonFactory.createSnakeCase().toJson(block); + String expected = """ + { + "type": "section", + "text": { + "text": "A message *with some bold text* and _some italicized text_.", + "type": "mrkdwn" + }, + "accessory": { + "type": "workflow_button", + "text": { + "type": "plain_text", + "text": "Run Workflow" + }, + "action_id": "workflowbutton123", + "workflow": { + "trigger": { + "url": "https://slack.com/shortcuts/Ft0123ABC456/xyz...zyx", + "customizable_input_parameters": [ + { + "name": "input_parameter_a", + "value": "Value for input param A" + }, + { + "name": "input_parameter_b", + "value": "Value for input param B" + } + ] + } + } + } + } + """; + assertEquals(JsonParser.parseString(expected), JsonParser.parseString(actual)); + } +}