Skip to content

Commit

Permalink
[Dembo] Add slack notification client
Browse files Browse the repository at this point in the history
  • Loading branch information
walbertus committed Sep 17, 2019
1 parent c7767a8 commit 885e52c
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 0 deletions.
34 changes: 34 additions & 0 deletions plugins/slack-notification-plugin/slack/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package slack

import (
"github.com/go-resty/resty/v2"
)

type SlackClient interface {
Publish(message Message) error
}

type slackClient struct {
client *resty.Client
config SlackConfig
}

func (s *slackClient) Publish(message Message) error {
messageJson, err := message.JSON()
if err != nil {
return err
}
path := s.config.url
_, err = s.client.R().
SetBody(messageJson).
SetHeader("Content-Type", "application/json").
Post(path)
return err
}

func NewSlackClient(client *resty.Client) SlackClient {
return &slackClient{
client: client,
config: NewSlackConfig(),
}
}
102 changes: 102 additions & 0 deletions plugins/slack-notification-plugin/slack/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package slack

import (
"errors"
"io/ioutil"
"net/http"
"testing"

"github.com/go-resty/resty/v2"
"github.com/jarcoal/httpmock"
"github.com/stretchr/testify/assert"
)

type slackClientTest struct {
client SlackClient
}

func (context *slackClientTest) setUp(t *testing.T) {
httpClient := resty.New()
httpmock.ActivateNonDefault(httpClient.GetClient())
context.client = NewSlackClient(httpClient)
assert.NotNil(t, context.client)
}

func (context *slackClientTest) tearDown() {
httpmock.DeactivateAndReset()
}

func newNotificationServiceTestContext() *slackClientTest {
return &slackClientTest{}
}

func TestSlackClient_Publish(t *testing.T) {
ctx := newNotificationServiceTestContext()
ctx.setUp(t)
defer ctx.tearDown()

config := NewSlackConfig()
message := MessageMock{}
message.On("JSON").Return("message sent", nil)

httpmock.RegisterResponder(
"POST",
config.url,
func(req *http.Request) (*http.Response, error) {
body, err := ioutil.ReadAll(req.Body)
assert.NoError(t, err)
assert.Equal(t, "message sent", string(body))

contentType := req.Header.Get("Content-type")
assert.Equal(t, "application/json", contentType)

response := httpmock.NewStringResponse(200, "")
return response, nil
},
)
err := ctx.client.Publish(&message)
assert.NoError(t, err)
assert.Equal(t, 1, httpmock.GetTotalCallCount())
}

func TestSlackClient_PublishErrorJSON(t *testing.T) {
ctx := newNotificationServiceTestContext()
ctx.setUp(t)
defer ctx.tearDown()

message := MessageMock{}
message.On("JSON").Return("", errors.New("JSON unmarshal error")).Once()

err := ctx.client.Publish(&message)
assert.Error(t, err)
assert.Equal(t, 0, httpmock.GetTotalCallCount())
}

func TestSlackClient_PublishErrorRequest(t *testing.T) {
ctx := newNotificationServiceTestContext()
ctx.setUp(t)
defer ctx.tearDown()

config := NewSlackConfig()
message := MessageMock{}
message.On("JSON").Return("message sent", nil)

httpmock.RegisterResponder(
"POST",
config.url,
func(req *http.Request) (*http.Response, error) {
body, err := ioutil.ReadAll(req.Body)
assert.NoError(t, err)
assert.Equal(t, "message sent", string(body))

contentType := req.Header.Get("Content-type")
assert.Equal(t, "application/json", contentType)

response := httpmock.NewStringResponse(503, "")
return response, errors.New("internal server error")
},
)
err := ctx.client.Publish(&message)
assert.Error(t, err)
assert.Equal(t, 1, httpmock.GetTotalCallCount())
}
18 changes: 18 additions & 0 deletions plugins/slack-notification-plugin/slack/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package slack

import "github.com/spf13/viper"

type SlackConfig struct {
url string
}

func NewSlackConfig() SlackConfig {
fang := viper.New()
fang.AutomaticEnv()
fang.SetEnvPrefix("SLACK_PLUGIN")
fang.SetDefault("URL", "https://hooks.slack.com/services")
config := SlackConfig{
url: fang.GetString("URL"),
}
return config
}
5 changes: 5 additions & 0 deletions plugins/slack-notification-plugin/slack/message.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package slack

type Message interface {
JSON() (string, error)
}
14 changes: 14 additions & 0 deletions plugins/slack-notification-plugin/slack/message_mock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package slack

import (
"github.com/stretchr/testify/mock"
)

type MessageMock struct {
mock.Mock
}

func (m *MessageMock) JSON() (string, error) {
args := m.Called()
return args.Get(0).(string), args.Error(1)
}

0 comments on commit 885e52c

Please sign in to comment.