Skip to content
Permalink
Browse files

notification fixes, tests

  • Loading branch information
hunterlong committed Mar 25, 2020
1 parent f331e9b commit 7d385b4da24a2c06b375c6b1b5ee21a1e43e5a45
@@ -1,3 +1,8 @@
# 0.90.17
- Fixed notification fields for frontend
- Fixed notification JSON form to send integer if value is an integer.
- Added testing for notifiers

# 0.90.16
- Added Notify After (int) field for Services. Will send notifications after x amount of failures.
- Added new method in utils package for replacing `{{.Service.*}}` and `{{.Failure.*}}` variables from string to it's true value
@@ -5,6 +5,7 @@ import (
"github.com/statping/statping/notifiers"
"github.com/statping/statping/types/core"
"github.com/statping/statping/types/services"
"github.com/statping/statping/utils"
)

func InitApp() error {
@@ -22,5 +23,6 @@ func InitApp() error {

database.StartMaintenceRoutine()
core.App.Setup = true
core.App.Started = utils.Now()
return nil
}
@@ -92,7 +92,11 @@ export default {
this.form.method = this.notifier.method
this.notifier.form.forEach((f) => {
let field = f.field.toLowerCase()
this.form[field] = this.notifier[field]
let val = this.notifier[field]
if (this.isNumeric(val)) {
val = parseInt(val)
}
this.form[field] = val
});
await Api.notifier_save(this.form)
// const notifiers = await Api.notifiers()
@@ -109,12 +113,16 @@ export default {
let form = {}
this.notifier.form.forEach((f) => {
let field = f.field.toLowerCase()
this.form[field] = this.notifier[field]
let val = this.notifier[field]
if (this.isNumeric(val)) {
val = parseInt(val)
}
this.form[field] = val
});
form.enabled = this.notifier.enabled
form.limits = parseInt(this.notifier.limits)
form.method = this.notifier.method
const tested = await Api.notifier_test(form)
this.form.enabled = this.notifier.enabled
this.form.limits = parseInt(this.notifier.limits)
this.form.method = this.notifier.method
const tested = await Api.notifier_test(this.form)
if (tested === 'ok') {
this.ok = true
} else {
@@ -9,6 +9,9 @@ export default Vue.mixin({
now() {
return new Date()
},
isNumeric: function (n) {
return !isNaN(parseFloat(n)) && isFinite(n);
},
current() {
return parseISO(new Date())
},
@@ -17,7 +17,6 @@ package handlers

import (
"encoding/json"
"errors"
"fmt"
"github.com/gorilla/mux"
"github.com/statping/statping/types/notifications"
@@ -34,16 +33,14 @@ func apiNotifiersHandler(w http.ResponseWriter, r *http.Request) {

func apiNotifierGetHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
notifier := vars["notifier"]
notifiers := services.AllNotifiers()
for _, n := range notifiers {
notf := n.Select()
if notifier == notf.Method {
returnJson(n, w, r)
return
}
notif := services.FindNotifier(vars["notifier"])
notifer, err := notifications.Find(notif.Method)
if err != nil {
sendErrorJson(err, w, r)
return
}
sendErrorJson(errors.New("notifier not found"), w, r)
notif = notif.UpdateFields(notifer)
returnJson(notif, w, r)
}

func apiNotifierUpdateHandler(w http.ResponseWriter, r *http.Request) {
@@ -53,14 +50,15 @@ func apiNotifierUpdateHandler(w http.ResponseWriter, r *http.Request) {
sendErrorJson(err, w, r)
return
}
defer r.Body.Close()

var notif *notifications.Notification
decoder := json.NewDecoder(r.Body)
err = decoder.Decode(&notifer)
err = decoder.Decode(&notif)
if err != nil {
sendErrorJson(err, w, r)
return
}
notifer = notifer.UpdateFields(notif)
err = notifer.Update()
if err != nil {
sendErrorJson(err, w, r)
@@ -102,6 +102,7 @@ func processSetupHandler(w http.ResponseWriter, r *http.Request) {
//ApiSecret: apiSecret.(string),
Domain: "http://localhost:8080",
Version: core.App.Version,
Started: utils.Now(),
CreatedAt: utils.Now(),
UseCdn: null.NewNullBool(false),
Footer: null.NewNullString(""),
@@ -72,25 +72,25 @@ func runCommand(app string, cmd ...string) (string, string, error) {
}

// OnFailure for commandLine will trigger failing service
func (u *commandLine) OnFailure(s *services.Service, f *failures.Failure) error {
msg := u.GetValue("var2")
func (c *commandLine) OnFailure(s *services.Service, f *failures.Failure) error {
msg := c.GetValue("var2")
tmpl := ReplaceVars(msg, s, f)
_, _, err := runCommand(u.Host, tmpl)
_, _, err := runCommand(c.Host, tmpl)
return err
}

// OnSuccess for commandLine will trigger successful service
func (u *commandLine) OnSuccess(s *services.Service) error {
msg := u.GetValue("var1")
func (c *commandLine) OnSuccess(s *services.Service) error {
msg := c.GetValue("var1")
tmpl := ReplaceVars(msg, s, nil)
_, _, err := runCommand(u.Host, tmpl)
_, _, err := runCommand(c.Host, tmpl)
return err
}

// OnTest for commandLine triggers when this notifier has been saved
func (u *commandLine) OnTest() error {
cmds := strings.Split(u.Var1, " ")
in, out, err := runCommand(u.Host, cmds...)
func (c *commandLine) OnTest() error {
cmds := strings.Split(c.Var1, " ")
in, out, err := runCommand(c.Host, cmds...)
utils.Log.Infoln(in)
utils.Log.Infoln(out)
return err
@@ -0,0 +1,67 @@
// Statping
// Copyright (C) 2018. Hunter Long and the project contributors
// Written by Hunter Long <info@socialeck.com> and the project contributors
//
// https://github.com/hunterlong/statping
//
// The licenses for most software and other practical works are designed
// to take away your freedom to share and change the works. By contrast,
// the GNU General Public License is intended to guarantee your freedom to
// share and change all versions of a program--to make sure it remains free
// software for all its users.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package notifiers

import (
"github.com/statping/statping/database"
"github.com/statping/statping/types/notifications"
"github.com/statping/statping/types/null"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"testing"
"time"
)

func TestCommandNotifier(t *testing.T) {
db, err := database.OpenTester()
require.Nil(t, err)
db.AutoMigrate(&notifications.Notification{})
notifications.SetDB(db)

t.Run("Load Command", func(t *testing.T) {
Command.Host = "/bin/echo"
Command.Var1 = "service {{.Service.Domain}} is online"
Command.Var2 = "service {{.Service.Domain}} is offline"
Command.Delay = time.Duration(100 * time.Millisecond)
Command.Limits = 99
Command.Enabled = null.NewNullBool(true)

Add(Command)

assert.Equal(t, "Hunter Long", Command.Author)
assert.Equal(t, "/bin/echo", Command.Host)
})

t.Run("Command Notifier Tester", func(t *testing.T) {
assert.True(t, Command.CanSend())
})

t.Run("Command OnFailure", func(t *testing.T) {
err := Command.OnFailure(exampleService, exampleFailure)
assert.Nil(t, err)
})

t.Run("Command OnSuccess", func(t *testing.T) {
err := Command.OnSuccess(exampleService)
assert.Nil(t, err)
})

t.Run("Command Test", func(t *testing.T) {
err := Command.OnTest()
assert.Nil(t, err)
})

}
@@ -0,0 +1,79 @@
// Statping
// Copyright (C) 2018. Hunter Long and the project contributors
// Written by Hunter Long <info@socialeck.com> and the project contributors
//
// https://github.com/hunterlong/statping
//
// The licenses for most software and other practical works are designed
// to take away your freedom to share and change the works. By contrast,
// the GNU General Public License is intended to guarantee your freedom to
// share and change all versions of a program--to make sure it remains free
// software for all its users.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package notifiers

import (
"github.com/statping/statping/database"
"github.com/statping/statping/types/notifications"
"github.com/statping/statping/types/null"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"os"
"testing"
"time"
)

var (
DISCORD_URL = os.Getenv("DISCORD_URL")
discordMessage = `{"content": "The discord notifier on Statping has been tested!"}`
)

func init() {
DISCORD_URL = os.Getenv("DISCORD_URL")
}

func TestDiscordNotifier(t *testing.T) {
db, err := database.OpenTester()
require.Nil(t, err)
db.AutoMigrate(&notifications.Notification{})
notifications.SetDB(db)

if DISCORD_URL == "" {
t.Log("discord notifier testing skipped, missing DISCORD_URL environment variable")
t.SkipNow()
}

t.Run("Load discord", func(t *testing.T) {
Discorder.Host = DISCORD_URL
Discorder.Delay = time.Duration(100 * time.Millisecond)
Discorder.Enabled = null.NewNullBool(true)

Add(Discorder)

assert.Equal(t, "Hunter Long", Discorder.Author)
assert.Equal(t, DISCORD_URL, Discorder.Host)
})

t.Run("discord Notifier Tester", func(t *testing.T) {
assert.True(t, Discorder.CanSend())
})

t.Run("discord OnFailure", func(t *testing.T) {
err := Discorder.OnFailure(exampleService, exampleFailure)
assert.Nil(t, err)
})

t.Run("discord OnSuccess", func(t *testing.T) {
err := Discorder.OnSuccess(exampleService)
assert.Nil(t, err)
})

t.Run("discord Test", func(t *testing.T) {
err := Discorder.OnTest()
assert.Nil(t, err)
})

}
@@ -16,7 +16,6 @@
package notifiers

import (
"bytes"
"crypto/tls"
"fmt"
"github.com/go-mail/mail"
@@ -26,7 +25,6 @@ import (
"github.com/statping/statping/types/null"
"github.com/statping/statping/types/services"
"github.com/statping/statping/utils"
"html/template"
"time"
)

@@ -183,7 +181,7 @@ func (e *emailer) OnFailure(s *services.Service, f *failures.Failure) error {
To: e.Var2,
Subject: fmt.Sprintf("Service %v is Failing", s.Name),
Template: mainEmailTemplate,
Data: interface{}(s),
Data: ToMap(s, f),
From: e.Var1,
}
return e.dialSend(email)
@@ -196,7 +194,7 @@ func (e *emailer) OnSuccess(s *services.Service) error {
To: e.Var2,
Subject: msg,
Template: mainEmailTemplate,
Data: interface{}(s),
Data: ToMap(s, nil),
From: e.Var1,
}
return e.dialSend(email)
@@ -230,7 +228,6 @@ func (e *emailer) OnTest() error {

func (e *emailer) dialSend(email *emailOutgoing) error {
mailer = mail.NewDialer(e.Host, e.Port, e.Username, e.Password)
emailSource(email)
m := mail.NewMessage()
// if email setting TLS is Disabled
if e.ApiKey == "true" {
@@ -241,29 +238,11 @@ func (e *emailer) dialSend(email *emailOutgoing) error {
m.SetHeader("From", email.From)
m.SetHeader("To", email.To)
m.SetHeader("Subject", email.Subject)
m.SetBody("text/html", email.Source)
m.SetBody("text/html", utils.ReplaceTemplate(email.Template, email.Data))

if err := mailer.DialAndSend(m); err != nil {
utils.Log.Errorln(fmt.Sprintf("email '%v' sent to: %v (size: %v) %v", email.Subject, email.To, len([]byte(email.Source)), err))
return err
}
return nil
}

func emailSource(email *emailOutgoing) {
source := emailTemplate(email.Template, email.Data)
email.Source = source
}

func emailTemplate(contents string, data interface{}) string {
t := template.New("email")
t, err := t.Parse(contents)
if err != nil {
utils.Log.Errorln(err)
}
var tpl bytes.Buffer
if err := t.Execute(&tpl, data); err != nil {
utils.Log.Warnln(err)
}
result := tpl.String()
return result
}

0 comments on commit 7d385b4

Please sign in to comment.
You can’t perform that action at this time.