feat: notification provider (#8)
All checks were successful
CD / test (push) Successful in 48s
CD / Build and push (push) Successful in 3m48s

Co-authored-by: Timo Behrendt <t.behrendt@t00n.de>
Co-committed-by: Timo Behrendt <t.behrendt@t00n.de>
This commit was merged in pull request #8.
This commit is contained in:
2024-08-11 11:52:51 +02:00
committed by t.behrendt
parent b8bdcaa35e
commit 7bb1e9ca08
11 changed files with 304 additions and 31 deletions

View File

@@ -0,0 +1,16 @@
package notificationProviderConsole
import (
"fmt"
)
type NotificationProviderImplConsole struct{}
func New() *NotificationProviderImplConsole {
return &NotificationProviderImplConsole{}
}
func (p *NotificationProviderImplConsole) SendNotification(title string, message string) error {
fmt.Printf("%s: %s\n", title, message)
return nil
}

View File

@@ -0,0 +1,87 @@
package notificationProviderGotify
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/url"
)
type NotificationProviderImplGotifyConfig struct {
Url string `yaml:"url"`
Token string `yaml:"token"`
Priority int `yaml:"priority"`
}
type NotificationProviderImplGotify struct {
Url url.URL
Token string
Priority int
HTTPClient *http.Client
}
func New(config NotificationProviderImplGotifyConfig) (*NotificationProviderImplGotify, error) {
if config.Url == "" {
return nil, fmt.Errorf("url is required")
}
url, err := url.Parse(config.Url)
if err != nil {
return nil, err
}
if config.Token == "" {
return nil, fmt.Errorf("token is required")
}
if config.Priority < 0 || config.Priority > 4 {
return nil, fmt.Errorf("priority must be between 0 and 4")
}
return &NotificationProviderImplGotify{
*url,
config.Token,
config.Priority,
&http.Client{},
}, nil
}
func (p *NotificationProviderImplGotify) SendNotification(title string, message string) error {
type GotifyMessage struct {
Message string `json:"message"`
Title string `json:"title"`
Priority int `json:"priority"`
}
messageJson, err := json.Marshal(GotifyMessage{
message,
title,
p.Priority,
})
if err != nil {
return err
}
messageUrl := p.Url
messageUrl.JoinPath("message")
messageUrl.Query().Add("token", p.Token)
req, err := http.NewRequest("POST", messageUrl.String(), bytes.NewBuffer(messageJson))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
res, err := p.HTTPClient.Do(req)
if err != nil {
return err
}
if res.StatusCode != 200 {
return fmt.Errorf("unexpected status code: %d", res.StatusCode)
}
return nil
}

View File

@@ -0,0 +1,81 @@
package notificationProviderGotify_test
import (
"net/http"
"net/http/httptest"
"testing"
gotify "realdnydns/pkg/notificationProvider/gotify"
)
func TestNew(t *testing.T) {
t.Run("URL is required", testNewEmptyUrl())
t.Run("Token is required", testNewEmptyToken())
t.Run("Priority must be between 0 and 4", testNewInvalidPriority())
t.Run("Sends POST request to url", testNewSendsPostRequest())
}
func testNewEmptyUrl() func(t *testing.T) {
return func(t *testing.T) {
_, err := gotify.New(gotify.NotificationProviderImplGotifyConfig{
Token: "1234",
Priority: 1,
})
if err.Error() != "url is required" {
t.Errorf("Expected error 'url is required', got %v", err)
}
}
}
func testNewEmptyToken() func(t *testing.T) {
return func(t *testing.T) {
_, err := gotify.New(gotify.NotificationProviderImplGotifyConfig{
Url: "http://localhost:1234",
Priority: 0,
})
if err.Error() != "token is required" {
t.Errorf("Expected error 'token is required', got %v", err)
}
}
}
func testNewInvalidPriority() func(t *testing.T) {
return func(t *testing.T) {
_, err := gotify.New(gotify.NotificationProviderImplGotifyConfig{
Url: "http://localhost:1234",
Token: "token",
Priority: 5,
})
if err.Error() != "priority must be between 0 and 4" {
t.Errorf("Expected error 'priority must be between 0 and 4', got %v", err)
}
}
}
func testNewSendsPostRequest() func(t *testing.T) {
return func(t *testing.T) {
mockServer := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
},
))
defer mockServer.Close()
provider, err := gotify.New(gotify.NotificationProviderImplGotifyConfig{
Url: mockServer.URL,
Token: "1234",
Priority: 0,
})
if err != nil {
t.Fatalf("New() returned unexpected error: %v", err)
}
err = provider.SendNotification("title", "message")
if err != nil {
t.Fatalf("SendNotification() returned unexpected error: %v", err)
}
}
}

View File

@@ -0,0 +1,5 @@
package notificationProvider
type NotificationProvider interface {
SendNotification(title string, message string) error
}