Skip to content

Commit

Permalink
chore: merge pr #160: assert service compliance
Browse files Browse the repository at this point in the history
  • Loading branch information
piksel authored Apr 20, 2021
2 parents 2bfefae + b5f98f7 commit 23170b8
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 13 deletions.
6 changes: 3 additions & 3 deletions pkg/services/gotify/gotify.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Service struct {
standard.Standard
config *Config
pkr format.PropKeyResolver
client *http.Client
Client *http.Client
}

// Initialize loads ServiceConfig from configURL and sets logger for this Service
Expand All @@ -32,7 +32,7 @@ func (service *Service) Initialize(configURL *url.URL, logger types.StdLogger) e
service.pkr = format.NewPropKeyResolver(service.config)
err := service.config.SetURL(configURL)

service.client = &http.Client{
service.Client = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
// If DisableTLS is specified, we might still need to disable TLS verification
Expand Down Expand Up @@ -105,7 +105,7 @@ func (service *Service) Send(message string, params *types.Params) error {
return err
}
jsonBuffer := bytes.NewBuffer(jsonBody)
resp, err := service.client.Post(postURL, "application/json", jsonBuffer)
resp, err := service.Client.Post(postURL, "application/json", jsonBuffer)
if err != nil {
return fmt.Errorf("failed to send notification to Gotify: %s", err)
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/services/gotify/gotify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ var _ = Describe("the Gotify plugin URL building and token validation functions"
It("should not report an error if the server accepts the payload", func() {
serviceURL, _ := url.Parse("gotify://my.gotify.tld/Aaa.bbb.ccc.ddd")
err = service.Initialize(serviceURL, logger)
httpmock.ActivateNonDefault(service.client)
httpmock.ActivateNonDefault(service.Client)
Expect(err).NotTo(HaveOccurred())

targetURL := "https://my.gotify.tld/message?token=Aaa.bbb.ccc.ddd"
Expand All @@ -131,7 +131,7 @@ var _ = Describe("the Gotify plugin URL building and token validation functions"
It("should not panic if an error occurs when sending the payload", func() {
serviceURL, _ := url.Parse("gotify://my.gotify.tld/Aaa.bbb.ccc.ddd")
err = service.Initialize(serviceURL, logger)
httpmock.ActivateNonDefault(service.client)
httpmock.ActivateNonDefault(service.Client)
Expect(err).NotTo(HaveOccurred())

targetURL := "https://my.gotify.tld/message?token=Aaa.bbb.ccc.ddd"
Expand Down
16 changes: 13 additions & 3 deletions pkg/services/ifttt/ifttt_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ const (
// Config is the configuration needed to send IFTTT notifications
type Config struct {
standard.EnumlessConfig
WebHookID string
Events []string `key:"events"`
WebHookID string `required:"true"`
Events []string `key:"events" required:"true"`
Value1 string `key:"value1"`
Value2 string `key:"value2"`
Value3 string `key:"value3"`
UseMessageAsValue uint8 `key:"messagevalue" desc:"" default:"2"`
UseMessageAsValue uint8 `key:"messagevalue" desc:"sets the corresponding value field to the notification message" default:"2"`
UseTitleAsValue uint8 `key:"titlevalue" desc:"sets the corresponding value field to the notification title" default:"0"`
Title string `key:"title" default:"" desc:"notification title, optionally set by the sender"`
}

// GetURL returns a URL representation of it's current field values
Expand Down Expand Up @@ -62,6 +64,14 @@ func (config *Config) setURL(resolver types.ConfigQueryResolver, url *url.URL) e
return errors.New("invalid value for messagevalue: only values 1-3 are supported")
}

if config.UseTitleAsValue > 3 {
return errors.New("invalid value for titlevalue: only values 1-3 or 0 (for disabling) are supported")
}

if config.UseTitleAsValue == config.UseMessageAsValue {
return errors.New("titlevalue cannot use the same number as messagevalue")
}

if len(config.Events) < 1 {
return errors.New("events missing from config URL")
}
Expand Down
25 changes: 21 additions & 4 deletions pkg/services/opsgenie/opsgenie.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ func (service *Service) Initialize(configURL *url.URL, logger types.StdLogger) e
// See: https://docs.opsgenie.com/docs/alert-api#create-alert
func (service *Service) Send(message string, params *types.Params) error {
config := service.config
url := fmt.Sprintf(alertEndpointTemplate, config.Host, config.Port)
endpointURL := fmt.Sprintf(alertEndpointTemplate, config.Host, config.Port)
payload, err := service.newAlertPayload(message, params)
if err != nil {
return err
}
return service.sendAlert(url, config.APIKey, payload)
return service.sendAlert(endpointURL, config.APIKey, payload)
}

func (service *Service) newAlertPayload(message string, params *types.Params) (AlertPayload, error) {
Expand All @@ -87,10 +87,27 @@ func (service *Service) newAlertPayload(message string, params *types.Params) (A
return AlertPayload{}, err
}

// Use `Message` for the title if available, or if the message is too long
// Use `Description` for the message in these scenarios
title := payloadFields.Title
description := message
if title == "" {
if len(message) > 130 {
title = message[:130]
} else {
title = message
description = ""
}
}

if payloadFields.Description != "" && description != "" {
description = description + "\n"
}

result := AlertPayload{
Message: message,
Message: title,
Alias: payloadFields.Alias,
Description: payloadFields.Description,
Description: description + payloadFields.Description,
Responders: payloadFields.Responders,
VisibleTo: payloadFields.VisibleTo,
Actions: payloadFields.Actions,
Expand Down
1 change: 1 addition & 0 deletions pkg/services/opsgenie/opsgenie_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Config struct {
Priority string `key:"priority" desc:"Priority level of the alert. Possible values are P1, P2, P3, P4 and P5" optional:"true"`
Note string `key:"note" desc:"Additional note that will be added while creating the alert" optional:"true"`
User string `key:"user" desc:"Display name of the request owner" optional:"true"`
Title string `key:"title" default:"" desc:"notification title, optionally set by the sender"`
}

// Enums returns an empty map because the OpsGenie service doesn't use Enums
Expand Down
100 changes: 100 additions & 0 deletions pkg/services/services_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package services_test

import (
"github.com/containrrr/shoutrrr/pkg/router"
"github.com/containrrr/shoutrrr/pkg/services/gotify"
"github.com/containrrr/shoutrrr/pkg/types"
"github.com/jarcoal/httpmock"
"log"
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

func TestServices(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Service Compliance Suite")
}

var serviceURLs = map[string]string{
"discord": "discord://token@id",
"gotify": "gotify://example.com/Aaa.bbb.ccc.ddd",
"hangouts": "hangouts://chat.googleapis.com/v1/spaces/FOO/messages?key=bar&token=baz",
"ifttt": "ifttt://key?events=event",
"join": "join://:apikey@join/?devices=device",
"logger": "logger://",
"mattermost": "mattermost://[email protected]/token",
"opsgenie": "opsgenie://example.com/token?responders=user:dummy",
"pushbullet": "pushbullet://tokentokentokentokentokentokentoke",
"pushover": "pushover://:token@user/?devices=device",
"rocketchat": "rocketchat://example.com/token/channel",
"slack": "slack://AAAAAAAAA/BBBBBBBBB/123456789123456789123456",
"smtp": "smtp://host.tld:25/[email protected]&[email protected]",
"teams": "teams://11111111-4444-4444-8444-cccccccccccc@22222222-4444-4444-8444-cccccccccccc/33333333012222222222333333333344/44444444-4444-4444-8444-cccccccccccc",
"telegram": "telegram://000000000:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@telegram?channels=channel",
"xmpp": "xmpp://",
"zulip": "zulip://mail:[email protected]/?stream=foo&topic=bar",
}

var logger = log.New(GinkgoWriter, "Test", log.LstdFlags)

var _ = Describe("services", func() {

BeforeEach(func() {

})
AfterEach(func() {

})

When("passed the a title param", func() {

var serviceRouter *router.ServiceRouter

AfterEach(func() {
httpmock.DeactivateAndReset()
})

for key, configURL := range serviceURLs {

key := key //necessary to ensure the correct value is passed to the closure
configURL := configURL
serviceRouter, _ = router.New(logger)

It("should not throw an error for "+key, func() {

if key == "smtp" {
Skip("smtp does not use HTTP and needs a specific test")
}
if key == "xmpp" {
Skip("not supported")
}

httpmock.Activate()
if key == "discord" || key == "ifttt" {
// Always return a "No content" result, as the http request isn't what is under test
httpmock.RegisterNoResponder(httpmock.NewStringResponder(204, ""))
} else {
// Always return an "OK" result, as the http request isn't what is under test
httpmock.RegisterNoResponder(httpmock.NewStringResponder(200, ""))
}

service, err := serviceRouter.Locate(configURL)
Expect(err).NotTo(HaveOccurred())

if key == "gotify" {
gotifyService := service.(*gotify.Service)
httpmock.ActivateNonDefault(gotifyService.Client)
}

err = service.Send("test", (*types.Params)(&map[string]string{
"title": "test title",
}))
Expect(err).NotTo(HaveOccurred())
})

}
})

})
1 change: 1 addition & 0 deletions pkg/services/telegram/telegram_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type Config struct {
Notification bool `key:"notification" default:"Yes" desc:"If disabled, sends message silently"`
ParseMode parseMode `key:"parsemode" default:"None" desc:"How the text message should be parsed"`
Channels []string `key:"channels"`
Title string `key:"title" default:"" desc:"notification title, optionally set by the sender"`
}

// Enums returns the fields that should use a corresponding EnumFormatter to Print/Parse their values
Expand Down
2 changes: 1 addition & 1 deletion pkg/services/telegram/telegram_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ var _ = Describe("the telegram service", func() {
testutils.TestConfigSetInvalidQueryValue(&Config{}, "telegram://12345:mock-token@telegram/?channels=channel-1&foo=bar")

testutils.TestConfigGetEnumsCount(&Config{}, 1)
testutils.TestConfigGetFieldsCount(&Config{}, 4)
testutils.TestConfigGetFieldsCount(&Config{}, 5)
})
})

Expand Down

0 comments on commit 23170b8

Please sign in to comment.