Changed interfaces to be private, updated related code and tests. Implemented getType for each interface to properly identify blocks, elements, and objects
Matt authored 5 years ago
James committed 5 years ago
3 | 3 | |
4 | 4 | // More Information: https://api.slack.com/block-kit |
5 | 5 | |
6 | var ( | |
7 | // validBlockList contains a list of | |
8 | validBlockList = []string{ | |
9 | "section", | |
10 | "divider", | |
11 | "image", | |
12 | "actions", | |
13 | "context", | |
14 | } | |
6 | // MessageBlockType defines a named string type to define each block type | |
7 | // as a constant for use within the package. | |
8 | type MessageBlockType string | |
9 | type MessageElementType string | |
10 | type MessageObjectType string | |
11 | ||
12 | const ( | |
13 | mbtSection MessageBlockType = "section" | |
14 | mbtDivider MessageBlockType = "divider" | |
15 | mbtImage MessageBlockType = "image" | |
16 | mbtAction MessageBlockType = "actions" | |
17 | mbtContext MessageBlockType = "context" | |
18 | ||
19 | metImage MessageElementType = "image" | |
20 | metButton MessageElementType = "button" | |
21 | metOverflow MessageElementType = "overflow" | |
22 | metDatepicker MessageElementType = "datepicker" | |
23 | metSelect MessageElementType = "static_select" | |
24 | ||
25 | motImage MessageObjectType = "image" | |
26 | motConfirmation MessageObjectType = "confirmation" | |
27 | motOption MessageObjectType = "option" | |
28 | motOptionGroup MessageObjectType = "option_group" | |
15 | 29 | ) |
16 | 30 | |
17 | // Block defines an interface all block types should implement | |
31 | // block defines an interface all block types should implement | |
18 | 32 | // to ensure consistency between blocks. |
19 | type Block interface { | |
20 | ValidateBlock() bool | |
33 | type block interface { | |
34 | blockType() MessageBlockType | |
21 | 35 | } |
22 | 36 | |
23 | 37 | // NewBlockMessage creates a new Message that contains one or more blocks to be displayed |
24 | func NewBlockMessage(blocks ...Block) Message { | |
38 | func NewBlockMessage(blocks ...block) Message { | |
25 | 39 | return Message{ |
26 | 40 | Msg: Msg{ |
27 | 41 | Blocks: blocks, |
29 | 43 | } |
30 | 44 | } |
31 | 45 | |
32 | // isStringInSlice is a helper function used in validating the block structs to | |
33 | // verify a valid type has been used. | |
34 | func isStringInSlice(a []string, x string) bool { | |
35 | for _, n := range a { | |
36 | if x == n { | |
37 | return true | |
38 | } | |
39 | } | |
40 | return false | |
46 | // AddBlockMessage appends a block to the end of the existing list of blocks | |
47 | func AddBlockMessage(message Message, newBlk block) Message { | |
48 | message.Msg.Blocks = append(message.Msg.Blocks, newBlk) | |
49 | return message | |
41 | 50 | } |
0 | 0 | package slack |
1 | ||
2 | import "strings" | |
3 | 1 | |
4 | 2 | // ActionBlock defines data that is used to hold interactive elements. |
5 | 3 | // |
6 | 4 | // More Information: https://api.slack.com/reference/messaging/blocks#actions |
7 | 5 | type ActionBlock struct { |
8 | Type string `json:"type"` | |
9 | BlockID string `json:"block_id,omitempty"` | |
10 | Elements []BlockElement `json:"elements"` | |
6 | Type MessageBlockType `json:"type"` | |
7 | BlockID string `json:"block_id,omitempty"` | |
8 | Elements []blockElement `json:"elements"` | |
11 | 9 | } |
12 | 10 | |
13 | // ValidateBlock ensures that the type set to the block is found in the list of | |
14 | // valid slack block. | |
15 | func (s *ActionBlock) ValidateBlock() bool { | |
16 | return isStringInSlice(validBlockList, strings.ToLower(s.Type)) | |
11 | // blockType returns the type of the block | |
12 | func (s ActionBlock) blockType() MessageBlockType { | |
13 | return s.Type | |
17 | 14 | } |
18 | 15 | |
19 | 16 | // NewActionBlock returns a new instance of an Action Block |
20 | func NewActionBlock(blockID string, elements ...BlockElement) *ActionBlock { | |
17 | func NewActionBlock(blockID string, elements ...blockElement) *ActionBlock { | |
21 | 18 | return &ActionBlock{ |
22 | Type: "actions", | |
19 | Type: mbtAction, | |
23 | 20 | BlockID: blockID, |
24 | 21 | Elements: elements, |
25 | 22 | } |
11 | 11 | approveBtn := NewButtonBlockElement("", "click_me_123", approveBtnTxt) |
12 | 12 | |
13 | 13 | actionBlock := NewActionBlock("test", approveBtn) |
14 | assert.Equal(t, actionBlock.Type, "actions") | |
14 | assert.Equal(t, string(actionBlock.Type), "actions") | |
15 | 15 | assert.Equal(t, actionBlock.BlockID, "test") |
16 | 16 | assert.Equal(t, len(actionBlock.Elements), 1) |
17 | 17 |
0 | 0 | package slack |
1 | ||
2 | import "strings" | |
3 | 1 | |
4 | 2 | // ContextBlock defines data that is used to display message context, which can |
5 | 3 | // include both images and text. |
6 | 4 | // |
7 | 5 | // More Information: https://api.slack.com/reference/messaging/blocks#actions |
8 | 6 | type ContextBlock struct { |
9 | Type string `json:"type"` | |
10 | BlockID string `json:"block_id,omitempty"` | |
11 | Elements []BlockObject `json:"elements"` | |
7 | Type MessageBlockType `json:"type"` | |
8 | BlockID string `json:"block_id,omitempty"` | |
9 | Elements []blockObject `json:"elements"` | |
12 | 10 | } |
13 | 11 | |
14 | // ValidateBlock ensures that the type set to the block is found in the list of | |
15 | // valid slack block. | |
16 | func (s *ContextBlock) ValidateBlock() bool { | |
17 | return isStringInSlice(validBlockList, strings.ToLower(s.Type)) | |
12 | // blockType returns the type of the block | |
13 | func (s ContextBlock) blockType() MessageBlockType { | |
14 | return s.Type | |
18 | 15 | } |
19 | 16 | |
20 | 17 | // NewContextBlock returns a newinstance of a context block |
21 | func NewContextBlock(blockID string, elements ...BlockObject) *ContextBlock { | |
18 | func NewContextBlock(blockID string, elements ...blockObject) *ContextBlock { | |
22 | 19 | return &ContextBlock{ |
23 | Type: "context", | |
20 | Type: mbtContext, | |
24 | 21 | BlockID: blockID, |
25 | 22 | Elements: elements, |
26 | 23 | } |
11 | 11 | textExample := NewTextBlockObject("plain_text", "Location: Central Business District", true, false) |
12 | 12 | |
13 | 13 | actionBlock := NewContextBlock("test", locationPinImage, textExample) |
14 | assert.Equal(t, actionBlock.Type, "context") | |
14 | assert.Equal(t, string(actionBlock.Type), "context") | |
15 | 15 | assert.Equal(t, actionBlock.BlockID, "test") |
16 | 16 | assert.Equal(t, len(actionBlock.Elements), 2) |
17 | 17 |
0 | 0 | package slack |
1 | ||
2 | import "strings" | |
3 | 1 | |
4 | 2 | // DividerBlock for displaying a divider line between blocks (similar to <hr> tag in html) |
5 | 3 | // |
6 | 4 | // More Information: https://api.slack.com/reference/messaging/blocks#divider |
7 | 5 | type DividerBlock struct { |
8 | Type string `json:"type"` | |
9 | BlockID string `json:"block_id,omitempty"` | |
6 | Type MessageBlockType `json:"type"` | |
7 | BlockID string `json:"block_id,omitempty"` | |
10 | 8 | } |
11 | 9 | |
12 | // ValidateBlock ensures that the type set to the block is found in the list of | |
13 | // valid slack block. | |
14 | func (s *DividerBlock) ValidateBlock() bool { | |
15 | return isStringInSlice(validBlockList, strings.ToLower(s.Type)) | |
16 | ||
10 | // blockType returns the type of the block | |
11 | func (s DividerBlock) blockType() MessageBlockType { | |
12 | return s.Type | |
17 | 13 | } |
18 | 14 | |
19 | 15 | // NewDividerBlock returns a new instance of a divider block |
20 | 16 | func NewDividerBlock() *DividerBlock { |
21 | 17 | |
22 | 18 | return &DividerBlock{ |
23 | Type: "divider", | |
19 | Type: mbtDivider, | |
24 | 20 | } |
25 | 21 | |
26 | 22 | } |
8 | 8 | func TestNewDividerBlock(t *testing.T) { |
9 | 9 | |
10 | 10 | dividerBlock := NewDividerBlock() |
11 | assert.Equal(t, dividerBlock.Type, "divider") | |
11 | assert.Equal(t, string(dividerBlock.Type), "divider") | |
12 | 12 | |
13 | 13 | } |
1 | 1 | |
2 | 2 | // https://api.slack.com/reference/messaging/block-elements |
3 | 3 | |
4 | // BlockElement defines an interface that all block element types should | |
4 | // blockElement defines an interface that all block element types should | |
5 | 5 | // implement. |
6 | type BlockElement interface { | |
7 | ValidateElement() bool | |
6 | type blockElement interface { | |
7 | blockType() MessageElementType | |
8 | 8 | } |
9 | 9 | |
10 | 10 | // ImageBlockElement An element to insert an image - this element can be used |
13 | 13 | // |
14 | 14 | // More Information: https://api.slack.com/reference/messaging/block-elements#image |
15 | 15 | type ImageBlockElement struct { |
16 | Type string `json:"type"` | |
17 | ImageURL string `json:"image_url"` | |
18 | AltText string `json:"alt_text"` | |
16 | Type MessageElementType `json:"type"` | |
17 | ImageURL string `json:"image_url"` | |
18 | AltText string `json:"alt_text"` | |
19 | 19 | } |
20 | 20 | |
21 | // ValidateElement performs validation checks to ensure the element is valid | |
22 | func (s ImageBlockElement) ValidateElement() bool { | |
23 | return true | |
21 | // validateType enforces block objects for block parameters | |
22 | func (s ImageBlockElement) blockType() MessageElementType { | |
23 | return s.Type | |
24 | 24 | } |
25 | 25 | |
26 | 26 | // NewImageBlockElement returns a new instance of an image block element |
27 | 27 | func NewImageBlockElement(imageURL, altText string) *ImageBlockElement { |
28 | 28 | return &ImageBlockElement{ |
29 | Type: "image", | |
29 | Type: metImage, | |
30 | 30 | ImageURL: imageURL, |
31 | 31 | AltText: altText, |
32 | 32 | } |
38 | 38 | // |
39 | 39 | // More Information: https://api.slack.com/reference/messaging/block-elements#button |
40 | 40 | type ButtonBlockElement struct { |
41 | Type string `json:"type,omitempty"` | |
41 | Type MessageElementType `json:"type,omitempty"` | |
42 | 42 | Text *TextBlockObject `json:"text"` |
43 | 43 | ActionID string `json:"action_id,omitempty"` |
44 | 44 | URL string `json:"url,omitempty"` |
46 | 46 | Confirm *ConfirmationBlockObject `json:"confirm,omitempty"` |
47 | 47 | } |
48 | 48 | |
49 | // ValidateElement performs validation checks to ensure the element is valid | |
50 | func (s ButtonBlockElement) ValidateElement() bool { | |
51 | return true | |
49 | // validateType enforces block objects for block parameters | |
50 | func (s ButtonBlockElement) blockType() MessageElementType { | |
51 | return s.Type | |
52 | 52 | } |
53 | 53 | |
54 | 54 | // NewButtonBlockElement returns an instance of a new button element to be used within a block |
55 | 55 | func NewButtonBlockElement(actionID, value string, text *TextBlockObject) *ButtonBlockElement { |
56 | 56 | return &ButtonBlockElement{ |
57 | Type: "button", | |
57 | Type: metButton, | |
58 | 58 | ActionID: actionID, |
59 | 59 | Text: text, |
60 | 60 | Value: value, |
75 | 75 | Confirm *ConfirmationBlockObject `json:"confirm,omitempty"` |
76 | 76 | } |
77 | 77 | |
78 | // ValidateElement performs validation checks to ensure the element is valid | |
79 | func (s SelectBlockElement) ValidateElement() bool { | |
80 | return true | |
78 | // validateType enforces block objects for block parameters | |
79 | func (s SelectBlockElement) blockType() MessageElementType { | |
80 | return MessageElementType(s.Type) | |
81 | 81 | } |
82 | 82 | |
83 | 83 | // NewOptionsSelectBlockElement returns a new instance of SelectBlockElement for use with |
114 | 114 | // |
115 | 115 | // More Information: https://api.slack.com/reference/messaging/block-elements#overflow |
116 | 116 | type OverflowBlockElement struct { |
117 | Type string `json:"type"` | |
117 | Type MessageElementType `json:"type"` | |
118 | 118 | ActionID string `json:"action_id,omitempty"` |
119 | 119 | Options []*OptionBlockObject `json:"options"` |
120 | 120 | Confirm *ConfirmationBlockObject `json:"confirm,omitempty"` |
121 | 121 | } |
122 | 122 | |
123 | // ValidateElement performs validation checks to ensure the element is valid | |
124 | func (s OverflowBlockElement) ValidateElement() bool { | |
125 | return true | |
123 | // validateType enforces block objects for block parameters | |
124 | func (s OverflowBlockElement) blockType() MessageElementType { | |
125 | return s.Type | |
126 | 126 | } |
127 | 127 | |
128 | 128 | // NewOverflowBlockElement returns an instance of a new Overflow Block Element |
129 | 129 | func NewOverflowBlockElement(actionID string, options ...*OptionBlockObject) *OverflowBlockElement { |
130 | 130 | return &OverflowBlockElement{ |
131 | Type: "overflow", | |
131 | Type: metOverflow, | |
132 | 132 | ActionID: actionID, |
133 | 133 | Options: options, |
134 | 134 | } |
140 | 140 | // |
141 | 141 | // More Information: https://api.slack.com/reference/messaging/block-elements#datepicker |
142 | 142 | type DatePickerBlockElement struct { |
143 | Type string `json:"type"` | |
143 | Type MessageElementType `json:"type"` | |
144 | 144 | ActionID string `json:"action_id"` |
145 | 145 | Placeholder *TextBlockObject `json:"placeholder,omitempty"` |
146 | 146 | InitialDate string `json:"initial_date,omitempty"` |
147 | 147 | Confirm *ConfirmationBlockObject `json:"confirm,omitempty"` |
148 | 148 | } |
149 | 149 | |
150 | // ValidateElement performs validation checks to ensure the element is valid | |
151 | func (s DatePickerBlockElement) ValidateElement() bool { | |
152 | return true | |
150 | // validateType enforces block objects for block parameters | |
151 | func (s DatePickerBlockElement) blockType() MessageElementType { | |
152 | return s.Type | |
153 | 153 | } |
154 | 154 | |
155 | 155 | // NewDatePickerBlockElement returns an instance of a date picker element |
156 | 156 | func NewDatePickerBlockElement(actionID string) *DatePickerBlockElement { |
157 | 157 | return &DatePickerBlockElement{ |
158 | Type: "datepicker", | |
158 | Type: metDatepicker, | |
159 | 159 | ActionID: actionID, |
160 | 160 | } |
161 | 161 | } |
9 | 9 | |
10 | 10 | imageElement := NewImageBlockObject("https://api.slack.com/img/blocks/bkb_template_images/tripAgentLocationMarker.png", "Location Pin Icon") |
11 | 11 | |
12 | assert.Equal(t, imageElement.Type, "image") | |
12 | assert.Equal(t, string(imageElement.Type), "image") | |
13 | 13 | assert.Contains(t, imageElement.ImageURL, "tripAgentLocationMarker") |
14 | 14 | assert.Equal(t, imageElement.AltText, "Location Pin Icon") |
15 | 15 | |
20 | 20 | btnTxt := NewTextBlockObject("plain_text", "Next 2 Results", false, false) |
21 | 21 | btnElement := NewButtonBlockElement("test", "click_me_123", btnTxt) |
22 | 22 | |
23 | assert.Equal(t, btnElement.Type, "button") | |
23 | assert.Equal(t, string(btnElement.Type), "button") | |
24 | 24 | assert.Equal(t, btnElement.ActionID, "test") |
25 | 25 | assert.Equal(t, btnElement.Value, "click_me_123") |
26 | 26 | assert.Equal(t, btnElement.Text.Text, "Next 2 Results") |
48 | 48 | |
49 | 49 | optGroup := NewOptionsGroupSelectBlockElement("static_select", nil, "test", testGroupOption) |
50 | 50 | |
51 | assert.Equal(t, optGroup.Type, "static_select") | |
51 | assert.Equal(t, string(optGroup.Type), "static_select") | |
52 | 52 | assert.Equal(t, optGroup.ActionID, "test") |
53 | 53 | assert.Equal(t, len(optGroup.OptionGroups), 1) |
54 | 54 | |
69 | 69 | // Build overflow section |
70 | 70 | overflowElement := NewOverflowBlockElement("test", overflowOptionOne, overflowOptionTwo, overflowOptionThree) |
71 | 71 | |
72 | assert.Equal(t, overflowElement.Type, "overflow") | |
72 | assert.Equal(t, string(overflowElement.Type), "overflow") | |
73 | 73 | assert.Equal(t, overflowElement.ActionID, "test") |
74 | 74 | assert.Equal(t, len(overflowElement.Options), 3) |
75 | 75 | |
79 | 79 | |
80 | 80 | datepickerElement := NewDatePickerBlockElement("test") |
81 | 81 | |
82 | assert.Equal(t, datepickerElement.Type, "datepicker") | |
82 | assert.Equal(t, string(datepickerElement.Type), "datepicker") | |
83 | 83 | assert.Equal(t, datepickerElement.ActionID, "test") |
84 | 84 | |
85 | 85 | } |
0 | 0 | package slack |
1 | ||
2 | import "strings" | |
3 | 1 | |
4 | 2 | // ImageBlock defines data required to display an image as a block element |
5 | 3 | // |
6 | 4 | // More Information: https://api.slack.com/reference/messaging/blocks#image |
7 | 5 | type ImageBlock struct { |
8 | Type string `json:"type"` | |
6 | Type MessageBlockType `json:"type"` | |
9 | 7 | ImageURL string `json:"image_url"` |
10 | 8 | AltText string `json:"alt_text"` |
11 | 9 | BlockID string `json:"block_id,omitempty"` |
12 | 10 | Title *TextBlockObject `json:"title"` |
13 | 11 | } |
14 | 12 | |
15 | // ValidateBlock ensures that the type set to the block is found in the list of | |
16 | // valid slack block. | |
17 | func (s *ImageBlock) ValidateBlock() bool { | |
18 | return isStringInSlice(validBlockList, strings.ToLower(s.Type)) | |
19 | ||
13 | // blockType returns the type of the block | |
14 | func (s ImageBlock) blockType() MessageBlockType { | |
15 | return s.Type | |
20 | 16 | } |
21 | 17 | |
22 | 18 | // NewImageBlock returns an instance of a new Image Block type |
23 | 19 | func NewImageBlock(imageURL, altText, blockID string, title *TextBlockObject) *ImageBlock { |
24 | 20 | return &ImageBlock{ |
25 | Type: "image", | |
21 | Type: mbtImage, | |
26 | 22 | ImageURL: imageURL, |
27 | 23 | AltText: altText, |
28 | 24 | BlockID: blockID, |
10 | 10 | imageText := NewTextBlockObject("plain_text", "Location", false, false) |
11 | 11 | imageBlock := NewImageBlock("https://api.slack.com/img/blocks/bkb_template_images/tripAgentLocationMarker.png", "Marker", "test", imageText) |
12 | 12 | |
13 | assert.Equal(t, imageBlock.Type, "image") | |
13 | assert.Equal(t, string(imageBlock.Type), "image") | |
14 | 14 | assert.Equal(t, imageBlock.Title.Type, "plain_text") |
15 | 15 | assert.Equal(t, imageBlock.BlockID, "test") |
16 | 16 | assert.Contains(t, imageBlock.Title.Text, "Location") |
6 | 6 | // BlockObject defines an interface that all block object types should |
7 | 7 | // implement. |
8 | 8 | // @TODO: Is this interface needed? |
9 | type BlockObject interface { | |
10 | ValidateObject() bool | |
9 | type blockObject interface { | |
10 | validateType() MessageObjectType | |
11 | 11 | } |
12 | 12 | |
13 | 13 | // ImageBlockObject An element to insert an image - this element can be used |
16 | 16 | // |
17 | 17 | // More Information: https://api.slack.com/reference/messaging/block-elements#image |
18 | 18 | type ImageBlockObject struct { |
19 | Type string `json:"type"` | |
20 | ImageURL string `json:"image_url"` | |
21 | AltText string `json:"alt_text"` | |
19 | Type MessageObjectType `json:"type"` | |
20 | ImageURL string `json:"image_url"` | |
21 | AltText string `json:"alt_text"` | |
22 | 22 | } |
23 | 23 | |
24 | // ValidateObject performs validation checks to ensure the element is valid | |
25 | func (s ImageBlockObject) ValidateObject() bool { | |
26 | return true | |
24 | // validateType enforces block objects for element and block parameters | |
25 | func (s ImageBlockObject) validateType() MessageObjectType { | |
26 | return s.Type | |
27 | 27 | } |
28 | 28 | |
29 | 29 | // NewImageBlockObject returns a new instance of an image block element |
30 | 30 | func NewImageBlockObject(imageURL, altText string) *ImageBlockObject { |
31 | 31 | return &ImageBlockObject{ |
32 | Type: "image", | |
32 | Type: motImage, | |
33 | 33 | ImageURL: imageURL, |
34 | 34 | AltText: altText, |
35 | 35 | } |
45 | 45 | Verbatim bool `json:"verbatim,omitempty"` |
46 | 46 | } |
47 | 47 | |
48 | // ValidateObject performs validation checks to ensure the element is valid | |
49 | func (s *TextBlockObject) ValidateObject() bool { | |
50 | return true | |
48 | // validateType enforces block objects for element and block parameters | |
49 | func (s TextBlockObject) validateType() MessageObjectType { | |
50 | return MessageObjectType(s.Type) | |
51 | 51 | } |
52 | 52 | |
53 | 53 | // NewTextBlockObject returns an instance of a new Text Block Object |
72 | 72 | Deny *TextBlockObject `json:"deny"` |
73 | 73 | } |
74 | 74 | |
75 | // ValidateObject performs validation checks to ensure the element is valid | |
76 | func (s *ConfirmationBlockObject) ValidateObject() bool { | |
77 | return true | |
75 | // validateType enforces block objects for element and block parameters | |
76 | func (s ConfirmationBlockObject) validateType() MessageObjectType { | |
77 | return motConfirmation | |
78 | 78 | } |
79 | 79 | |
80 | 80 | // NewConfirmationBlockObject returns an instance of a new Confirmation Block Object |
95 | 95 | Value string `json:"value"` |
96 | 96 | } |
97 | 97 | |
98 | // ValidateObject performs validation checks to ensure the element is valid | |
99 | func (s *OptionBlockObject) ValidateObject() bool { | |
100 | return true | |
101 | } | |
102 | ||
103 | 98 | // NewOptionBlockObject returns an instance of a new Option Block Element |
104 | 99 | func NewOptionBlockObject(value string, text *TextBlockObject) *OptionBlockObject { |
105 | 100 | return &OptionBlockObject{ |
106 | 101 | Text: text, |
107 | 102 | Value: value, |
108 | 103 | } |
104 | } | |
105 | ||
106 | // validateType enforces block objects for element and block parameters | |
107 | func (s OptionBlockObject) validateType() MessageObjectType { | |
108 | return motOption | |
109 | 109 | } |
110 | 110 | |
111 | 111 | // OptionGroupBlockObject Provides a way to group options in a select menu. |
116 | 116 | Options []*OptionBlockObject `json:"options"` |
117 | 117 | } |
118 | 118 | |
119 | // ValidateObject performs validation checks to ensure the element is valid | |
120 | func (s *OptionGroupBlockObject) ValidateObject() bool { | |
121 | return true | |
119 | // validateType enforces block objects for element and block parameters | |
120 | func (s OptionGroupBlockObject) validateType() MessageObjectType { | |
121 | return motOptionGroup | |
122 | 122 | } |
123 | 123 | |
124 | 124 | // NewOptionGroupBlockElement returns an instance of a new option group block element |
9 | 9 | |
10 | 10 | imageObject := NewImageBlockObject("https://api.slack.com/img/blocks/bkb_template_images/beagle.png", "Beagle") |
11 | 11 | |
12 | assert.Equal(t, imageObject.Type, "image") | |
12 | assert.Equal(t, string(imageObject.Type), "image") | |
13 | 13 | assert.Equal(t, imageObject.AltText, "Beagle") |
14 | 14 | assert.Contains(t, imageObject.ImageURL, "beagle.png") |
15 | 15 |
0 | 0 | package slack |
1 | ||
2 | import "strings" | |
3 | 1 | |
4 | 2 | // SectionBlock defines a new block of type section |
5 | 3 | // |
6 | 4 | // More Information: https://api.slack.com/reference/messaging/blocks#section |
7 | 5 | type SectionBlock struct { |
8 | Type string `json:"type"` | |
6 | Type MessageBlockType `json:"type"` | |
9 | 7 | Text *TextBlockObject `json:"text,omitempty"` |
10 | 8 | BlockID string `json:"block_id,omitempty"` |
11 | 9 | Fields []*TextBlockObject `json:"fields,omitempty"` |
12 | Accessory BlockElement `json:"accessory,omitempty"` | |
10 | Accessory blockElement `json:"accessory,omitempty"` | |
13 | 11 | } |
14 | 12 | |
15 | // ValidateBlock ensures that the type set to the block is found in the list of | |
16 | // valid slack block. | |
17 | func (s *SectionBlock) ValidateBlock() bool { | |
18 | return isStringInSlice(validBlockList, strings.ToLower(s.Type)) | |
19 | ||
13 | // blockType returns the type of the block | |
14 | func (s SectionBlock) blockType() MessageBlockType { | |
15 | return s.Type | |
20 | 16 | } |
21 | 17 | |
22 | 18 | // NewSectionBlock returns a new instance of a section block to be rendered |
23 | func NewSectionBlock(textObj *TextBlockObject, fields []*TextBlockObject, accessory BlockElement) *SectionBlock { | |
19 | func NewSectionBlock(textObj *TextBlockObject, fields []*TextBlockObject, accessory blockElement) *SectionBlock { | |
24 | 20 | return &SectionBlock{ |
25 | Type: "section", | |
21 | Type: mbtSection, | |
26 | 22 | Text: textObj, |
27 | 23 | Fields: fields, |
28 | 24 | Accessory: accessory, |
10 | 10 | textInfo := NewTextBlockObject("mrkdwn", "*<fakeLink.toHotelPage.com|The Ritz-Carlton New Orleans>*\n★★★★★\n$340 per night\nRated: 9.1 - Excellent", false, false) |
11 | 11 | |
12 | 12 | sectionBlock := NewSectionBlock(textInfo, nil, nil) |
13 | assert.Equal(t, sectionBlock.Type, "section") | |
13 | assert.Equal(t, string(sectionBlock.Type), "section") | |
14 | 14 | assert.Equal(t, len(sectionBlock.Fields), 0) |
15 | 15 | assert.Nil(t, sectionBlock.Accessory) |
16 | 16 | assert.Equal(t, sectionBlock.Text.Type, "mrkdwn") |