mirror of https://github.com/statping/statping
not finalized, notifications works, additional testing
parent
c92fe8a329
commit
1cfc5b4bda
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
<h6 class="mt-4 text-muted">Notifiers</h6>
|
<h6 class="mt-4 text-muted">Notifiers</h6>
|
||||||
|
|
||||||
|
{{notifiers}}
|
||||||
|
|
||||||
<div id="notifiers_tabs">
|
<div id="notifiers_tabs">
|
||||||
<a v-for="(notifier, index) in notifiers" v-bind:key="`${notifier.method}`" @click.prevent="changeTab" class="nav-link text-capitalize" v-bind:class="{active: liClass(`v-pills-${notifier.method.toLowerCase()}-tab`)}" v-bind:id="`v-pills-${notifier.method.toLowerCase()}-tab`" data-toggle="pill" v-bind:href="`#v-pills-${notifier.method.toLowerCase()}`" role="tab" v-bind:aria-controls="`v-pills-${notifier.method.toLowerCase()}`" aria-selected="false">
|
<a v-for="(notifier, index) in notifiers" v-bind:key="`${notifier.method}`" @click.prevent="changeTab" class="nav-link text-capitalize" v-bind:class="{active: liClass(`v-pills-${notifier.method.toLowerCase()}-tab`)}" v-bind:id="`v-pills-${notifier.method.toLowerCase()}-tab`" data-toggle="pill" v-bind:href="`#v-pills-${notifier.method.toLowerCase()}`" role="tab" v-bind:aria-controls="`v-pills-${notifier.method.toLowerCase()}`" aria-selected="false">
|
||||||
<font-awesome-icon :icon="iconName(notifier.icon)" class="mr-2"/> {{notifier.title}}
|
<font-awesome-icon :icon="iconName(notifier.icon)" class="mr-2"/> {{notifier.title}}
|
||||||
|
@ -152,10 +154,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.update()
|
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.update()
|
this.update()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async update() {
|
async update() {
|
||||||
|
|
|
@ -12,12 +12,10 @@ import (
|
||||||
|
|
||||||
func apiNotifiersHandler(w http.ResponseWriter, r *http.Request) {
|
func apiNotifiersHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
var notifs []notifications.Notification
|
var notifs []notifications.Notification
|
||||||
notifiers := services.AllNotifiers()
|
for _, n := range services.AllNotifiers() {
|
||||||
for _, n := range notifiers {
|
no := n.Select()
|
||||||
notif := n.Select()
|
notif, _ := notifications.Find(no.Method)
|
||||||
notifer, _ := notifications.Find(notif.Method)
|
notifs = append(notifs, *no.UpdateFields(notif))
|
||||||
notif.UpdateFields(notifer)
|
|
||||||
notifs = append(notifs, *notif)
|
|
||||||
}
|
}
|
||||||
sort.Sort(notifications.NotificationOrder(notifs))
|
sort.Sort(notifications.NotificationOrder(notifs))
|
||||||
returnJson(notifs, w, r)
|
returnJson(notifs, w, r)
|
||||||
|
@ -25,12 +23,12 @@ func apiNotifiersHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
func apiNotifierGetHandler(w http.ResponseWriter, r *http.Request) {
|
func apiNotifierGetHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
notif := services.FindNotifier(vars["notifier"])
|
notifer := services.FindNotifier(vars["notifier"])
|
||||||
if notif == nil {
|
if notifer == nil {
|
||||||
sendErrorJson(errors.New("could not find notifier"), w, r)
|
sendErrorJson(errors.New("could not find notifier"), w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
returnJson(notif, w, r)
|
returnJson(notifer, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiNotifierUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
func apiNotifierUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -48,8 +46,7 @@ func apiNotifierUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
log.Infof("Updating %s Notifier", notifer.Title)
|
log.Infof("Updating %s Notifier", notifer.Title)
|
||||||
|
|
||||||
err = notifer.Update()
|
if err := notifer.Update(); err != nil {
|
||||||
if err != nil {
|
|
||||||
sendErrorJson(err, w, r)
|
sendErrorJson(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"github.com/statping/statping/types/services"
|
"github.com/statping/statping/types/services"
|
||||||
"github.com/statping/statping/utils"
|
"github.com/statping/statping/utils"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,7 +13,7 @@ func TestAttachment(t *testing.T) {
|
||||||
notifiers.InitNotifiers()
|
notifiers.InitNotifiers()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnAuthenticatedNotifierRoutes(t *testing.T) {
|
func TestAuthenticatedNotifierRoutes(t *testing.T) {
|
||||||
slackWebhookUrl := utils.Params.GetString("SLACK_URL")
|
slackWebhookUrl := utils.Params.GetString("SLACK_URL")
|
||||||
|
|
||||||
tests := []HTTPTest{
|
tests := []HTTPTest{
|
||||||
|
@ -42,7 +43,12 @@ func TestUnAuthenticatedNotifierRoutes(t *testing.T) {
|
||||||
URL: "/api/notifier/slack",
|
URL: "/api/notifier/slack",
|
||||||
Method: "GET",
|
Method: "GET",
|
||||||
ExpectedStatus: 200,
|
ExpectedStatus: 200,
|
||||||
BeforeTest: SetTestENV,
|
BeforeTest: func(t *testing.T) error {
|
||||||
|
notif := services.FindNotifier("slack")
|
||||||
|
require.NotNil(t, notif)
|
||||||
|
assert.Equal(t, "slack", notif.Method)
|
||||||
|
return SetTestENV(t)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "No Authentication - Update Notifier",
|
Name: "No Authentication - Update Notifier",
|
||||||
|
@ -68,7 +74,20 @@ func TestUnAuthenticatedNotifierRoutes(t *testing.T) {
|
||||||
"limits": 55
|
"limits": 55
|
||||||
}`,
|
}`,
|
||||||
ExpectedStatus: 200,
|
ExpectedStatus: 200,
|
||||||
BeforeTest: SetTestENV,
|
BeforeTest: func(t *testing.T) error {
|
||||||
|
notif := services.FindNotifier("slack")
|
||||||
|
require.NotNil(t, notif)
|
||||||
|
assert.Equal(t, "slack", notif.Method)
|
||||||
|
assert.False(t, notif.Enabled.Bool)
|
||||||
|
return SetTestENV(t)
|
||||||
|
},
|
||||||
|
AfterTest: func(t *testing.T) error {
|
||||||
|
notif := services.FindNotifier("slack")
|
||||||
|
require.NotNil(t, notif)
|
||||||
|
assert.Equal(t, "slack", notif.Method)
|
||||||
|
assert.True(t, notif.Enabled.Bool)
|
||||||
|
return UnsetTestENV(t)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Test Notifier (OnSuccess)",
|
Name: "Test Notifier (OnSuccess)",
|
||||||
|
@ -154,7 +173,7 @@ func TestApiNotifiersRoutes(t *testing.T) {
|
||||||
URL: "/api/notifier/slack",
|
URL: "/api/notifier/slack",
|
||||||
Method: "GET",
|
Method: "GET",
|
||||||
ExpectedStatus: 200,
|
ExpectedStatus: 200,
|
||||||
ExpectedContains: []string{`"method":"slack"`},
|
ExpectedContains: []string{`"method":"slack"`, `"host":"https://slack.api/example/12345"`},
|
||||||
BeforeTest: SetTestENV,
|
BeforeTest: SetTestENV,
|
||||||
SecureRoute: true,
|
SecureRoute: true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,6 +22,10 @@ func (c *commandLine) Select() *notifications.Notification {
|
||||||
return c.Notification
|
return c.Notification
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *commandLine) Valid(values notifications.Values) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var Command = &commandLine{¬ifications.Notification{
|
var Command = &commandLine{¬ifications.Notification{
|
||||||
Method: "command",
|
Method: "command",
|
||||||
Title: "Command",
|
Title: "Command",
|
||||||
|
|
|
@ -51,6 +51,10 @@ func (d *discord) Select() *notifications.Notification {
|
||||||
return d.Notification
|
return d.Notification
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *discord) Valid(values notifications.Values) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// OnFailure will trigger failing service
|
// OnFailure will trigger failing service
|
||||||
func (d *discord) OnFailure(s services.Service, f failures.Failure) (string, error) {
|
func (d *discord) OnFailure(s services.Service, f failures.Failure) (string, error) {
|
||||||
out, err := d.sendRequest(ReplaceVars(d.FailureData.String, s, f))
|
out, err := d.sendRequest(ReplaceVars(d.FailureData.String, s, f))
|
||||||
|
|
|
@ -28,6 +28,10 @@ func (e *emailer) Select() *notifications.Notification {
|
||||||
return e.Notification
|
return e.Notification
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *emailer) Valid(values notifications.Values) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var email = &emailer{¬ifications.Notification{
|
var email = &emailer{¬ifications.Notification{
|
||||||
Method: "email",
|
Method: "email",
|
||||||
Title: "SMTP Mail",
|
Title: "SMTP Mail",
|
||||||
|
|
|
@ -22,6 +22,10 @@ func (g *gotify) Select() *notifications.Notification {
|
||||||
return g.Notification
|
return g.Notification
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *gotify) Valid(values notifications.Values) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var Gotify = &gotify{¬ifications.Notification{
|
var Gotify = &gotify{¬ifications.Notification{
|
||||||
Method: "gotify",
|
Method: "gotify",
|
||||||
Title: "Gotify",
|
Title: "Gotify",
|
||||||
|
|
|
@ -26,6 +26,10 @@ func (l *lineNotifier) Select() *notifications.Notification {
|
||||||
return l.Notification
|
return l.Notification
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *lineNotifier) Valid(values notifications.Values) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var LineNotify = &lineNotifier{¬ifications.Notification{
|
var LineNotify = &lineNotifier{¬ifications.Notification{
|
||||||
Method: lineNotifyMethod,
|
Method: lineNotifyMethod,
|
||||||
Title: "LINE Notify",
|
Title: "LINE Notify",
|
||||||
|
|
|
@ -22,6 +22,10 @@ func (m *mobilePush) Select() *notifications.Notification {
|
||||||
return m.Notification
|
return m.Notification
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *mobilePush) Valid(values notifications.Values) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var Mobile = &mobilePush{¬ifications.Notification{
|
var Mobile = &mobilePush{¬ifications.Notification{
|
||||||
Method: "mobile",
|
Method: "mobile",
|
||||||
Title: "Mobile",
|
Title: "Mobile",
|
||||||
|
|
|
@ -27,6 +27,10 @@ func (t *pushover) Select() *notifications.Notification {
|
||||||
return t.Notification
|
return t.Notification
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *pushover) Valid(values notifications.Values) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var Pushover = &pushover{¬ifications.Notification{
|
var Pushover = &pushover{¬ifications.Notification{
|
||||||
Method: "pushover",
|
Method: "pushover",
|
||||||
Title: "Pushover",
|
Title: "Pushover",
|
||||||
|
|
|
@ -91,3 +91,7 @@ func (s *slack) OnSuccess(srv services.Service) (string, error) {
|
||||||
func (s *slack) OnSave() (string, error) {
|
func (s *slack) OnSave() (string, error) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *slack) Valid(values notifications.Values) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -27,6 +27,10 @@ func (s *statpingEmailer) Select() *notifications.Notification {
|
||||||
return s.Notification
|
return s.Notification
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *statpingEmailer) Valid(values notifications.Values) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var statpingMailer = &statpingEmailer{¬ifications.Notification{
|
var statpingMailer = &statpingEmailer{¬ifications.Notification{
|
||||||
Method: statpingEmailerName,
|
Method: statpingEmailerName,
|
||||||
Title: "Email",
|
Title: "Email",
|
||||||
|
|
|
@ -25,6 +25,10 @@ func (t *telegram) Select() *notifications.Notification {
|
||||||
return t.Notification
|
return t.Notification
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *telegram) Valid(values notifications.Values) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var Telegram = &telegram{¬ifications.Notification{
|
var Telegram = &telegram{¬ifications.Notification{
|
||||||
Method: "telegram",
|
Method: "telegram",
|
||||||
Title: "Telegram",
|
Title: "Telegram",
|
||||||
|
|
|
@ -26,6 +26,10 @@ func (t *twilio) Select() *notifications.Notification {
|
||||||
return t.Notification
|
return t.Notification
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *twilio) Valid(values notifications.Values) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var Twilio = &twilio{¬ifications.Notification{
|
var Twilio = &twilio{¬ifications.Notification{
|
||||||
Method: "twilio",
|
Method: "twilio",
|
||||||
Title: "Twilio",
|
Title: "Twilio",
|
||||||
|
|
|
@ -80,6 +80,10 @@ func (w *webhooker) Select() *notifications.Notification {
|
||||||
return w.Notification
|
return w.Notification
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *webhooker) Valid(values notifications.Values) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (w *webhooker) sendHttpWebhook(body string) (*http.Response, error) {
|
func (w *webhooker) sendHttpWebhook(body string) (*http.Response, error) {
|
||||||
utils.Log.Infoln(fmt.Sprintf("sending body: '%v' to %v as a %v request", body, w.Host.String, w.Var1.String))
|
utils.Log.Infoln(fmt.Sprintf("sending body: '%v' to %v as a %v request", body, w.Host.String, w.Var1.String))
|
||||||
client := new(http.Client)
|
client := new(http.Client)
|
||||||
|
|
|
@ -48,6 +48,10 @@ func Select() (*Core, error) {
|
||||||
func (c *Core) Create() error {
|
func (c *Core) Create() error {
|
||||||
if c.ApiSecret == "" {
|
if c.ApiSecret == "" {
|
||||||
c.ApiSecret = utils.RandomString(16)
|
c.ApiSecret = utils.RandomString(16)
|
||||||
|
apiEnv := utils.Params.GetString("API_SECRET")
|
||||||
|
if apiEnv != "" {
|
||||||
|
c.ApiSecret = apiEnv
|
||||||
|
}
|
||||||
}
|
}
|
||||||
q := db.Create(c)
|
q := db.Create(c)
|
||||||
utils.Log.Infof("API Key created: %s", c.ApiSecret)
|
utils.Log.Infof("API Key created: %s", c.ApiSecret)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package notifications
|
package notifications
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"github.com/statping/statping/database"
|
"github.com/statping/statping/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,11 +15,10 @@ func SetDB(database database.Database) {
|
||||||
func Find(method string) (*Notification, error) {
|
func Find(method string) (*Notification, error) {
|
||||||
var n Notification
|
var n Notification
|
||||||
q := db.Where("method = ?", method).Find(&n)
|
q := db.Where("method = ?", method).Find(&n)
|
||||||
if &n == nil {
|
if q.Error() != nil {
|
||||||
return nil, errors.New("cannot find notifier")
|
return nil, q.Error()
|
||||||
}
|
}
|
||||||
n.UpdateFields(&n)
|
return &n, nil
|
||||||
return &n, q.Error()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Notification) Create() error {
|
func (n *Notification) Create() error {
|
||||||
|
@ -45,6 +43,7 @@ func (n *Notification) Create() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Notification) UpdateFields(notif *Notification) *Notification {
|
func (n *Notification) UpdateFields(notif *Notification) *Notification {
|
||||||
|
n.Id = notif.Id
|
||||||
n.Limits = notif.Limits
|
n.Limits = notif.Limits
|
||||||
n.Enabled = notif.Enabled
|
n.Enabled = notif.Enabled
|
||||||
n.Host = notif.Host
|
n.Host = notif.Host
|
||||||
|
|
|
@ -2,13 +2,9 @@ package notifications
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/statping/statping/types/metrics"
|
"github.com/statping/statping/types/metrics"
|
||||||
"github.com/statping/statping/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AfterFind for Notification will set the timezone
|
|
||||||
func (n *Notification) AfterFind() (err error) {
|
func (n *Notification) AfterFind() (err error) {
|
||||||
n.CreatedAt = utils.Now()
|
|
||||||
n.UpdatedAt = utils.Now()
|
|
||||||
metrics.Query("notifier", "find")
|
metrics.Query("notifier", "find")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,17 @@ func (n *Notification) Logger() *logrus.Logger {
|
||||||
|
|
||||||
type RunFunc func(interface{}) error
|
type RunFunc func(interface{}) error
|
||||||
|
|
||||||
|
type Values struct {
|
||||||
|
Host string
|
||||||
|
Port int64
|
||||||
|
Username string
|
||||||
|
Password string
|
||||||
|
Var1 string
|
||||||
|
Var2 string
|
||||||
|
ApiKey string
|
||||||
|
ApiSecret string
|
||||||
|
}
|
||||||
|
|
||||||
// NotificationForm contains the HTML fields for each variable/input you want the notifier to accept.
|
// NotificationForm contains the HTML fields for each variable/input you want the notifier to accept.
|
||||||
type NotificationForm struct {
|
type NotificationForm struct {
|
||||||
Type string `json:"type"` // the html input type (text, password, email)
|
Type string `json:"type"` // the html input type (text, password, email)
|
||||||
|
|
|
@ -20,7 +20,9 @@ func ReturnNotifier(method string) ServiceNotifier {
|
||||||
func FindNotifier(method string) *notifications.Notification {
|
func FindNotifier(method string) *notifications.Notification {
|
||||||
n := allNotifiers[method]
|
n := allNotifiers[method]
|
||||||
if n != nil {
|
if n != nil {
|
||||||
return n.Select()
|
notif := n.Select()
|
||||||
|
no, _ := notifications.Find(notif.Method)
|
||||||
|
return notif.UpdateFields(no)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -31,4 +33,5 @@ type ServiceNotifier interface {
|
||||||
OnTest() (string, error) // OnTest is triggered for testing
|
OnTest() (string, error) // OnTest is triggered for testing
|
||||||
OnSave() (string, error) // OnSave is triggered for testing
|
OnSave() (string, error) // OnSave is triggered for testing
|
||||||
Select() *notifications.Notification // OnTest is triggered for testing
|
Select() *notifications.Notification // OnTest is triggered for testing
|
||||||
|
Valid(notifications.Values) error // Valid checks your form values
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/statping/statping/types/failures"
|
"github.com/statping/statping/types/failures"
|
||||||
"github.com/statping/statping/types/hits"
|
"github.com/statping/statping/types/hits"
|
||||||
"github.com/statping/statping/types/incidents"
|
"github.com/statping/statping/types/incidents"
|
||||||
|
"github.com/statping/statping/types/notifications"
|
||||||
"github.com/statping/statping/types/null"
|
"github.com/statping/statping/types/null"
|
||||||
"github.com/statping/statping/utils"
|
"github.com/statping/statping/utils"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -182,10 +183,11 @@ func startupDb(t *testing.T) {
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
db, err := database.OpenTester()
|
db, err := database.OpenTester()
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
db.AutoMigrate(&Service{}, &hits.Hit{}, &checkins.Checkin{}, &checkins.CheckinHit{}, &failures.Failure{}, &incidents.Incident{}, &incidents.IncidentUpdate{})
|
db.AutoMigrate(&Service{}, ¬ifications.Notification{}, &hits.Hit{}, &checkins.Checkin{}, &checkins.CheckinHit{}, &failures.Failure{}, &incidents.Incident{}, &incidents.IncidentUpdate{})
|
||||||
checkins.SetDB(db)
|
checkins.SetDB(db)
|
||||||
failures.SetDB(db)
|
failures.SetDB(db)
|
||||||
incidents.SetDB(db)
|
incidents.SetDB(db)
|
||||||
|
notifications.SetDB(db)
|
||||||
hits.SetDB(db)
|
hits.SetDB(db)
|
||||||
SetDB(db)
|
SetDB(db)
|
||||||
|
|
||||||
|
@ -198,6 +200,7 @@ func startupDb(t *testing.T) {
|
||||||
db.Create(&fail2)
|
db.Create(&fail2)
|
||||||
db.Create(&incident1)
|
db.Create(&incident1)
|
||||||
db.Create(&incidentUpdate1)
|
db.Create(&incidentUpdate1)
|
||||||
|
db.Create(&incidentUpdate1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServices(t *testing.T) {
|
func TestServices(t *testing.T) {
|
||||||
|
|
|
@ -322,3 +322,7 @@ func (e *exampleNotifier) OnTest() (string, error) {
|
||||||
e.tests++
|
e.tests++
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *exampleNotifier) Valid(form notifications.Values) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue