Skip to content

Commit

Permalink
Changed interfaces to be private, updated related code and tests. Imp…
Browse files Browse the repository at this point in the history
…lemented getType for each interface to properly identify blocks, elements, and objects
  • Loading branch information
MattDavisRV authored and james-lawrence committed Feb 27, 2019
1 parent cc1779f commit 45f072b
Show file tree
Hide file tree
Showing 16 changed files with 128 additions and 137 deletions.
53 changes: 31 additions & 22 deletions block.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,48 @@ package slack

// More Information: https://api.slack.com/block-kit

var (
// validBlockList contains a list of
validBlockList = []string{
"section",
"divider",
"image",
"actions",
"context",
}
// MessageBlockType defines a named string type to define each block type
// as a constant for use within the package.
type MessageBlockType string
type MessageElementType string
type MessageObjectType string

const (
mbtSection MessageBlockType = "section"
mbtDivider MessageBlockType = "divider"
mbtImage MessageBlockType = "image"
mbtAction MessageBlockType = "actions"
mbtContext MessageBlockType = "context"

metImage MessageElementType = "image"
metButton MessageElementType = "button"
metOverflow MessageElementType = "overflow"
metDatepicker MessageElementType = "datepicker"
metSelect MessageElementType = "static_select"

motImage MessageObjectType = "image"
motConfirmation MessageObjectType = "confirmation"
motOption MessageObjectType = "option"
motOptionGroup MessageObjectType = "option_group"
)

// Block defines an interface all block types should implement
// block defines an interface all block types should implement
// to ensure consistency between blocks.
type Block interface {
ValidateBlock() bool
type block interface {
blockType() MessageBlockType
}

// NewBlockMessage creates a new Message that contains one or more blocks to be displayed
func NewBlockMessage(blocks ...Block) Message {
func NewBlockMessage(blocks ...block) Message {
return Message{
Msg: Msg{
Blocks: blocks,
},
}
}

// isStringInSlice is a helper function used in validating the block structs to
// verify a valid type has been used.
func isStringInSlice(a []string, x string) bool {
for _, n := range a {
if x == n {
return true
}
}
return false
// AddBlockMessage appends a block to the end of the existing list of blocks
func AddBlockMessage(message Message, newBlk block) Message {
message.Msg.Blocks = append(message.Msg.Blocks, newBlk)
return message
}
19 changes: 8 additions & 11 deletions block_action.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
package slack

import "strings"

// ActionBlock defines data that is used to hold interactive elements.
//
// More Information: https://api.slack.com/reference/messaging/blocks#actions
type ActionBlock struct {
Type string `json:"type"`
BlockID string `json:"block_id,omitempty"`
Elements []BlockElement `json:"elements"`
Type MessageBlockType `json:"type"`
BlockID string `json:"block_id,omitempty"`
Elements []blockElement `json:"elements"`
}

// ValidateBlock ensures that the type set to the block is found in the list of
// valid slack block.
func (s *ActionBlock) ValidateBlock() bool {
return isStringInSlice(validBlockList, strings.ToLower(s.Type))
// blockType returns the type of the block
func (s ActionBlock) blockType() MessageBlockType {
return s.Type
}

// NewActionBlock returns a new instance of an Action Block
func NewActionBlock(blockID string, elements ...BlockElement) *ActionBlock {
func NewActionBlock(blockID string, elements ...blockElement) *ActionBlock {
return &ActionBlock{
Type: "actions",
Type: mbtAction,
BlockID: blockID,
Elements: elements,
}
Expand Down
2 changes: 1 addition & 1 deletion block_action_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func TestNewActionBlock(t *testing.T) {
approveBtn := NewButtonBlockElement("", "click_me_123", approveBtnTxt)

actionBlock := NewActionBlock("test", approveBtn)
assert.Equal(t, actionBlock.Type, "actions")
assert.Equal(t, string(actionBlock.Type), "actions")
assert.Equal(t, actionBlock.BlockID, "test")
assert.Equal(t, len(actionBlock.Elements), 1)

Expand Down
19 changes: 8 additions & 11 deletions block_context.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
package slack

import "strings"

// ContextBlock defines data that is used to display message context, which can
// include both images and text.
//
// More Information: https://api.slack.com/reference/messaging/blocks#actions
type ContextBlock struct {
Type string `json:"type"`
BlockID string `json:"block_id,omitempty"`
Elements []BlockObject `json:"elements"`
Type MessageBlockType `json:"type"`
BlockID string `json:"block_id,omitempty"`
Elements []blockObject `json:"elements"`
}

// ValidateBlock ensures that the type set to the block is found in the list of
// valid slack block.
func (s *ContextBlock) ValidateBlock() bool {
return isStringInSlice(validBlockList, strings.ToLower(s.Type))
// blockType returns the type of the block
func (s ContextBlock) blockType() MessageBlockType {
return s.Type
}

// NewContextBlock returns a newinstance of a context block
func NewContextBlock(blockID string, elements ...BlockObject) *ContextBlock {
func NewContextBlock(blockID string, elements ...blockObject) *ContextBlock {
return &ContextBlock{
Type: "context",
Type: mbtContext,
BlockID: blockID,
Elements: elements,
}
Expand Down
2 changes: 1 addition & 1 deletion block_context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func TestNewContextBlock(t *testing.T) {
textExample := NewTextBlockObject("plain_text", "Location: Central Business District", true, false)

actionBlock := NewContextBlock("test", locationPinImage, textExample)
assert.Equal(t, actionBlock.Type, "context")
assert.Equal(t, string(actionBlock.Type), "context")
assert.Equal(t, actionBlock.BlockID, "test")
assert.Equal(t, len(actionBlock.Elements), 2)

Expand Down
16 changes: 6 additions & 10 deletions block_divider.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
package slack

import "strings"

// DividerBlock for displaying a divider line between blocks (similar to <hr> tag in html)
//
// More Information: https://api.slack.com/reference/messaging/blocks#divider
type DividerBlock struct {
Type string `json:"type"`
BlockID string `json:"block_id,omitempty"`
Type MessageBlockType `json:"type"`
BlockID string `json:"block_id,omitempty"`
}

// ValidateBlock ensures that the type set to the block is found in the list of
// valid slack block.
func (s *DividerBlock) ValidateBlock() bool {
return isStringInSlice(validBlockList, strings.ToLower(s.Type))

// blockType returns the type of the block
func (s DividerBlock) blockType() MessageBlockType {
return s.Type
}

// NewDividerBlock returns a new instance of a divider block
func NewDividerBlock() *DividerBlock {

return &DividerBlock{
Type: "divider",
Type: mbtDivider,
}

}
2 changes: 1 addition & 1 deletion block_divider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ import (
func TestNewDividerBlock(t *testing.T) {

dividerBlock := NewDividerBlock()
assert.Equal(t, dividerBlock.Type, "divider")
assert.Equal(t, string(dividerBlock.Type), "divider")

}
56 changes: 28 additions & 28 deletions block_element.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package slack

// https://api.slack.com/reference/messaging/block-elements

// BlockElement defines an interface that all block element types should
// blockElement defines an interface that all block element types should
// implement.
type BlockElement interface {
ValidateElement() bool
type blockElement interface {
blockType() MessageElementType
}

// ImageBlockElement An element to insert an image - this element can be used
Expand All @@ -14,20 +14,20 @@ type BlockElement interface {
//
// More Information: https://api.slack.com/reference/messaging/block-elements#image
type ImageBlockElement struct {
Type string `json:"type"`
ImageURL string `json:"image_url"`
AltText string `json:"alt_text"`
Type MessageElementType `json:"type"`
ImageURL string `json:"image_url"`
AltText string `json:"alt_text"`
}

// ValidateElement performs validation checks to ensure the element is valid
func (s ImageBlockElement) ValidateElement() bool {
return true
// validateType enforces block objects for block parameters
func (s ImageBlockElement) blockType() MessageElementType {
return s.Type
}

// NewImageBlockElement returns a new instance of an image block element
func NewImageBlockElement(imageURL, altText string) *ImageBlockElement {
return &ImageBlockElement{
Type: "image",
Type: metImage,
ImageURL: imageURL,
AltText: altText,
}
Expand All @@ -39,23 +39,23 @@ func NewImageBlockElement(imageURL, altText string) *ImageBlockElement {
//
// More Information: https://api.slack.com/reference/messaging/block-elements#button
type ButtonBlockElement struct {
Type string `json:"type,omitempty"`
Type MessageElementType `json:"type,omitempty"`
Text *TextBlockObject `json:"text"`
ActionID string `json:"action_id,omitempty"`
URL string `json:"url,omitempty"`
Value string `json:"value,omitempty"`
Confirm *ConfirmationBlockObject `json:"confirm,omitempty"`
}

// ValidateElement performs validation checks to ensure the element is valid
func (s ButtonBlockElement) ValidateElement() bool {
return true
// validateType enforces block objects for block parameters
func (s ButtonBlockElement) blockType() MessageElementType {
return s.Type
}

// NewButtonBlockElement returns an instance of a new button element to be used within a block
func NewButtonBlockElement(actionID, value string, text *TextBlockObject) *ButtonBlockElement {
return &ButtonBlockElement{
Type: "button",
Type: metButton,
ActionID: actionID,
Text: text,
Value: value,
Expand All @@ -76,9 +76,9 @@ type SelectBlockElement struct {
Confirm *ConfirmationBlockObject `json:"confirm,omitempty"`
}

// ValidateElement performs validation checks to ensure the element is valid
func (s SelectBlockElement) ValidateElement() bool {
return true
// validateType enforces block objects for block parameters
func (s SelectBlockElement) blockType() MessageElementType {
return MessageElementType(s.Type)
}

// NewOptionsSelectBlockElement returns a new instance of SelectBlockElement for use with
Expand Down Expand Up @@ -115,21 +115,21 @@ func NewOptionsGroupSelectBlockElement(
//
// More Information: https://api.slack.com/reference/messaging/block-elements#overflow
type OverflowBlockElement struct {
Type string `json:"type"`
Type MessageElementType `json:"type"`
ActionID string `json:"action_id,omitempty"`
Options []*OptionBlockObject `json:"options"`
Confirm *ConfirmationBlockObject `json:"confirm,omitempty"`
}

// ValidateElement performs validation checks to ensure the element is valid
func (s OverflowBlockElement) ValidateElement() bool {
return true
// validateType enforces block objects for block parameters
func (s OverflowBlockElement) blockType() MessageElementType {
return s.Type
}

// NewOverflowBlockElement returns an instance of a new Overflow Block Element
func NewOverflowBlockElement(actionID string, options ...*OptionBlockObject) *OverflowBlockElement {
return &OverflowBlockElement{
Type: "overflow",
Type: metOverflow,
ActionID: actionID,
Options: options,
}
Expand All @@ -141,22 +141,22 @@ func NewOverflowBlockElement(actionID string, options ...*OptionBlockObject) *Ov
//
// More Information: https://api.slack.com/reference/messaging/block-elements#datepicker
type DatePickerBlockElement struct {
Type string `json:"type"`
Type MessageElementType `json:"type"`
ActionID string `json:"action_id"`
Placeholder *TextBlockObject `json:"placeholder,omitempty"`
InitialDate string `json:"initial_date,omitempty"`
Confirm *ConfirmationBlockObject `json:"confirm,omitempty"`
}

// ValidateElement performs validation checks to ensure the element is valid
func (s DatePickerBlockElement) ValidateElement() bool {
return true
// validateType enforces block objects for block parameters
func (s DatePickerBlockElement) blockType() MessageElementType {
return s.Type
}

// NewDatePickerBlockElement returns an instance of a date picker element
func NewDatePickerBlockElement(actionID string) *DatePickerBlockElement {
return &DatePickerBlockElement{
Type: "datepicker",
Type: metDatepicker,
ActionID: actionID,
}
}
10 changes: 5 additions & 5 deletions block_element_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ func TestNewImageBlockElement(t *testing.T) {

imageElement := NewImageBlockObject("https://api.slack.com/img/blocks/bkb_template_images/tripAgentLocationMarker.png", "Location Pin Icon")

assert.Equal(t, imageElement.Type, "image")
assert.Equal(t, string(imageElement.Type), "image")
assert.Contains(t, imageElement.ImageURL, "tripAgentLocationMarker")
assert.Equal(t, imageElement.AltText, "Location Pin Icon")

Expand All @@ -21,7 +21,7 @@ func TestNewButtonBlockElement(t *testing.T) {
btnTxt := NewTextBlockObject("plain_text", "Next 2 Results", false, false)
btnElement := NewButtonBlockElement("test", "click_me_123", btnTxt)

assert.Equal(t, btnElement.Type, "button")
assert.Equal(t, string(btnElement.Type), "button")
assert.Equal(t, btnElement.ActionID, "test")
assert.Equal(t, btnElement.Value, "click_me_123")
assert.Equal(t, btnElement.Text.Text, "Next 2 Results")
Expand Down Expand Up @@ -49,7 +49,7 @@ func TestNewOptionsGroupSelectBlockElement(t *testing.T) {

optGroup := NewOptionsGroupSelectBlockElement("static_select", nil, "test", testGroupOption)

assert.Equal(t, optGroup.Type, "static_select")
assert.Equal(t, string(optGroup.Type), "static_select")
assert.Equal(t, optGroup.ActionID, "test")
assert.Equal(t, len(optGroup.OptionGroups), 1)

Expand All @@ -70,7 +70,7 @@ func TestNewOverflowBlockElement(t *testing.T) {
// Build overflow section
overflowElement := NewOverflowBlockElement("test", overflowOptionOne, overflowOptionTwo, overflowOptionThree)

assert.Equal(t, overflowElement.Type, "overflow")
assert.Equal(t, string(overflowElement.Type), "overflow")
assert.Equal(t, overflowElement.ActionID, "test")
assert.Equal(t, len(overflowElement.Options), 3)

Expand All @@ -80,7 +80,7 @@ func TestNewDatePickerBlockElement(t *testing.T) {

datepickerElement := NewDatePickerBlockElement("test")

assert.Equal(t, datepickerElement.Type, "datepicker")
assert.Equal(t, string(datepickerElement.Type), "datepicker")
assert.Equal(t, datepickerElement.ActionID, "test")

}
Loading

0 comments on commit 45f072b

Please sign in to comment.