diff --git a/README.md b/README.md index e8d8387..ef5b302 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,9 @@ Here is all avaliables hook's configurations and your descriptions. Remember tha - **api_key** The API Key to use the NewRelic REST API. You can find more [here](https://docs.newrelic.com/docs/apis/rest-api-v2/getting-started/api-keys) - **revision** The application's current revision (e.g 0.0.1r42) +- HangoutsChat + - **webhook_url** Indicates the Webhook URL to dispatch messages to HangoutsChat Room. + ## Example [Snitch App Sample](https://github.com/lucasgomide/snitch-app-example) diff --git a/hook/hangouts_chat.go b/hook/hangouts_chat.go new file mode 100644 index 0000000..1618980 --- /dev/null +++ b/hook/hangouts_chat.go @@ -0,0 +1,32 @@ +package hook + +import ( + "bytes" + "errors" + "net/http" + + "github.com/lucasgomide/snitch/types" +) + +type HangoutsChat struct { + WebhookUrl string +} + +func (s HangoutsChat) CallHook(deploy []types.Deploy) error { + message := `"The application *` + deploy[0].App + `* has been deployed just now by ` + deploy[0].User + ` at _` + deploy[0].ConvertTimestampToRFC822() + `_"` + + data := []byte(`{"text":` + message + `}`) + resp, err := http.Post(s.WebhookUrl, "application/json", bytes.NewReader(data)) + if err != nil { + return err + } + + if resp.StatusCode != 200 { + return errors.New(`HangoutsChat - response status code is ` + resp.Status) + } + return nil +} + +func (s HangoutsChat) ValidatesFields() error { + return nil +} diff --git a/hook/hangouts_chat_test.go b/hook/hangouts_chat_test.go new file mode 100644 index 0000000..b4e6376 --- /dev/null +++ b/hook/hangouts_chat_test.go @@ -0,0 +1,61 @@ +package hook + +import ( + "testing" + + "github.com/lucasgomide/snitch/types" + "gopkg.in/jarcoal/httpmock.v1" +) + +var hangoutWebhookUrl = "https://hangouts.chat/123" + +func TestHangoutWhenNotificatedSuccessful(t *testing.T) { + httpmock.Activate() + defer httpmock.DeactivateAndReset() + + httpmock.RegisterResponder("POST", hangoutWebhookUrl, + httpmock.NewStringResponder(200, `ok`)) + + hangout := &HangoutsChat{WebhookUrl: hangoutWebhookUrl} + var deploy []types.Deploy + deploy = append(deploy, types.Deploy{App: "app-sample"}) + + err := hangout.CallHook(deploy) + if err != nil { + t.Error(err) + } +} + +func TestHangoutWhenResponseStatusCodeIsnt200(t *testing.T) { + httpmock.Activate() + defer httpmock.DeactivateAndReset() + + httpmock.RegisterResponder("POST", hangoutWebhookUrl, + httpmock.NewStringResponder(400, `error`)) + + hangout := &HangoutsChat{WebhookUrl: hangoutWebhookUrl} + var deploy []types.Deploy + deploy = append(deploy, types.Deploy{App: "app-sample"}) + + err := hangout.CallHook(deploy) + expected := "HangoutsChat - response status code is 400" + if err == nil || err.Error() != expected { + t.Error("Expected: "+expected+", but got", err.Error()) + } +} + +func TestHangoutReturnsErrorWhenRequestFail(t *testing.T) { + httpmock.Activate() + defer httpmock.DeactivateAndReset() + + httpmock.RegisterNoResponder(nil) + + hangout := &HangoutsChat{WebhookUrl: hangoutWebhookUrl} + var deploy []types.Deploy + deploy = append(deploy, types.Deploy{App: "app-sample"}) + + err := hangout.CallHook(deploy) + if err == nil { + t.Error("The request has been failed but no error was raised") + } +} diff --git a/hook/hook.go b/hook/hook.go index f6a6f64..ea9a4dd 100644 --- a/hook/hook.go +++ b/hook/hook.go @@ -22,7 +22,7 @@ func Execute(h types.Hook, t types.Tsuru) { utils.LogError(err.Error()) } else { for hookName, conf := range config.Data() { - switch strings.Title(hookName.(string)) { + switch defineHookName(hookName.(string)) { case "Slack": h = &Slack{} case "Sentry": @@ -31,6 +31,8 @@ func Execute(h types.Hook, t types.Tsuru) { h = &Rollbar{} case "Newrelic": h = &NewRelic{} + case "Hangouts Chat": + h = &HangoutsChat{} default: continue } @@ -74,3 +76,9 @@ func executeHook(h types.Hook, deploy []types.Deploy, conf interface{}) error { return nil } + +func defineHookName(name string) string { + return strings.Title( + strings.Join(strings.Split(name, "_"), " "), + ) +} diff --git a/hook/hook_test.go b/hook/hook_test.go index b063239..5406128 100644 --- a/hook/hook_test.go +++ b/hook/hook_test.go @@ -91,6 +91,9 @@ func TestShouldExecuteHooksFromConfig(t *testing.T) { httpmock.RegisterResponder("POST", "http://dummy.sample", httpmock.NewStringResponder(200, `ok`)) + httpmock.RegisterResponder("POST", "http://hangouts.chat.sample", + httpmock.NewStringResponder(200, `ok`)) + httpmock.RegisterResponder("POST", "https://api.rollbar.com/api/1/deploy/", httpmock.NewStringResponder(200, `ok`)) @@ -116,6 +119,7 @@ func TestShouldExecuteHooksFromConfig(t *testing.T) { if msg != "" { t.Error("Expected that msg is not empty, got empty msg") + t.Error(msg) } } diff --git a/testdata/config.yaml b/testdata/config.yaml index b9914da..4a7b59c 100644 --- a/testdata/config.yaml +++ b/testdata/config.yaml @@ -1,5 +1,7 @@ slack: webhook_url: http://dummy.sample +hangouts_chat: + webhook_url: http://hangouts.chat.sample missing_hook: field: value rollbar: @@ -16,4 +18,4 @@ newrelic: host: https://api.newrelic.com application_id: "01234" api_key: 0a0b11223344 - revision: 0.0.1 \ No newline at end of file + revision: 0.0.1