From ca39fc73a49eadedf2dc07217a2771c5abc20810 Mon Sep 17 00:00:00 2001 From: Hunter Long Date: Wed, 3 Oct 2018 03:47:32 -0700 Subject: [PATCH] testing - notifer update --- cmd/main_test.go | 2 +- core/checkin.go | 35 +++++++++++++++++++++++++++++++++ core/database.go | 7 ++++++- core/notifier/notifiers_test.go | 2 +- core/services.go | 4 ++-- core/services_test.go | 2 +- handlers/api_handlers_test.go | 6 ------ handlers/handlers.go | 2 +- handlers/routes.go | 1 + handlers/services.go | 33 +++++++++++++++++++++++-------- notifiers/webhook.go | 9 ++++++--- notifiers/webhook_test.go | 6 +++--- source/tmpl/form_checkin.html | 19 ++++++++++++++++++ source/tmpl/service.html | 28 +++++++++----------------- types/checkin.go | 26 ++++++++---------------- types/service.go | 1 - utils/utils.go | 8 +++++++- 17 files changed, 125 insertions(+), 66 deletions(-) create mode 100644 source/tmpl/form_checkin.html diff --git a/cmd/main_test.go b/cmd/main_test.go index 356bc7d8..5e5dec06 100644 --- a/cmd/main_test.go +++ b/cmd/main_test.go @@ -311,7 +311,7 @@ func RunSelectAllNotifiers(t *testing.T) { notifier.SetDB(core.DbSession) core.CoreApp.Notifications = notifier.Load() assert.Nil(t, err) - assert.Equal(t, 5, len(core.CoreApp.Notifications)) + assert.Equal(t, 6, len(core.CoreApp.Notifications)) } func RunUserSelectAll(t *testing.T) { diff --git a/core/checkin.go b/core/checkin.go index d4d9b231..3d70c948 100644 --- a/core/checkin.go +++ b/core/checkin.go @@ -27,6 +27,10 @@ type Checkin struct { *types.Checkin } +type CheckinHit struct { + *types.CheckinHit +} + func (c *Checkin) String() string { return c.ApiKey } @@ -35,6 +39,16 @@ func ReturnCheckin(s *types.Checkin) *Checkin { return &Checkin{Checkin: s} } +func ReturnCheckinHit(h *types.CheckinHit) *CheckinHit { + return &CheckinHit{CheckinHit: h} +} + +func SelectCheckin(api string) *Checkin { + var checkin Checkin + checkinDB().Where("api_key = ?", api).First(&checkin) + return &checkin +} + func FindCheckin(api string) *types.Checkin { for _, ser := range CoreApp.Services { service := ser.Select() @@ -47,6 +61,12 @@ func FindCheckin(api string) *types.Checkin { return nil } +func (u *Checkin) Hits() []CheckinHit { + var checkins []CheckinHit + checkinDB().Where("checkin = ?", u.Id).Order("id DESC").Find(&checkins) + return checkins +} + func (u *Checkin) Create() (int64, error) { u.CreatedAt = time.Now() row := checkinDB().Create(u) @@ -57,6 +77,16 @@ func (u *Checkin) Create() (int64, error) { return u.Id, row.Error } +func (u *CheckinHit) Create() (int64, error) { + u.CreatedAt = time.Now() + row := checkinHitsDB().Create(u) + if row.Error == nil { + utils.Log(2, row.Error) + return 0, row.Error + } + return u.Id, row.Error +} + func SelectCheckinApi(api string) *Checkin { var checkin *Checkin checkinDB().Where("api = ?", api).Find(&checkin) @@ -95,3 +125,8 @@ func (f *Checkin) Ago() string { got, _ := timeago.TimeAgoWithTime(time.Now(), time.Now()) return got } + +func (f *CheckinHit) Ago() string { + got, _ := timeago.TimeAgoWithTime(time.Now(), time.Now()) + return got +} diff --git a/core/database.go b/core/database.go index f8406c87..7fa6a9ec 100644 --- a/core/database.go +++ b/core/database.go @@ -61,11 +61,16 @@ func usersDB() *gorm.DB { return DbSession.Model(&types.User{}) } -// hitsDB returns the 'hits' database column +// checkinDB returns the Checkin records for a service func checkinDB() *gorm.DB { return DbSession.Model(&types.Checkin{}) } +// checkinHitsDB returns the 'hits' from the Checkin record +func checkinHitsDB() *gorm.DB { + return DbSession.Model(&types.CheckinHit{}) +} + // HitsBetween returns the gorm database query for a collection of service hits between a time range func (s *Service) HitsBetween(t1, t2 time.Time, group string, column string) *gorm.DB { selector := Dbtimestamp(group, column) diff --git a/core/notifier/notifiers_test.go b/core/notifier/notifiers_test.go index 198db827..ef77caa5 100644 --- a/core/notifier/notifiers_test.go +++ b/core/notifier/notifiers_test.go @@ -232,7 +232,7 @@ func TestRunAllQueueAndStop(t *testing.T) { assert.Equal(t, 16, len(example.Queue)) go Queue(example) assert.Equal(t, 16, len(example.Queue)) - time.Sleep(10 * time.Second) + time.Sleep(12 * time.Second) assert.Equal(t, 6, len(example.Queue)) example.close() assert.False(t, example.IsRunning()) diff --git a/core/services.go b/core/services.go index 600ef537..d89946a0 100644 --- a/core/services.go +++ b/core/services.go @@ -49,8 +49,8 @@ func SelectService(id int64) *Service { return nil } -func (s *Service) Checkins() []*types.Checkin { - var hits []*types.Checkin +func (s *Service) Checkins() []*Checkin { + var hits []*Checkin servicesDB().Where("service = ?", s.Id).Find(&hits) return hits } diff --git a/core/services_test.go b/core/services_test.go index 6f9704db..b7775940 100644 --- a/core/services_test.go +++ b/core/services_test.go @@ -164,7 +164,7 @@ func TestServiceTotalHits(t *testing.T) { service := SelectService(5) hits, err := service.TotalHits() assert.Nil(t, err) - assert.Equal(t, uint64(0x5ac), hits) + assert.NotZero(t, hits) } func TestServiceSum(t *testing.T) { diff --git a/handlers/api_handlers_test.go b/handlers/api_handlers_test.go index d0c3e3b0..a786a354 100644 --- a/handlers/api_handlers_test.go +++ b/handlers/api_handlers_test.go @@ -90,7 +90,6 @@ func TestApiIndexHandler(t *testing.T) { rr, err := httpRequestAPI(t, "GET", "/api", nil) assert.Nil(t, err) body := rr.Body.String() - t.Log(body) var obj types.Core formatJSON(body, &obj) assert.Equal(t, 200, rr.Code) @@ -102,7 +101,6 @@ func TestApiAllServicesHandlerHandler(t *testing.T) { rr, err := httpRequestAPI(t, "GET", "/api/services", nil) assert.Nil(t, err) body := rr.Body.String() - t.Log(body) var obj []types.Service formatJSON(body, &obj) assert.Equal(t, 200, rr.Code) @@ -126,7 +124,6 @@ func TestApiCreateServiceHandler(t *testing.T) { assert.Nil(t, err) body := rr.Body.String() assert.Equal(t, 200, rr.Code) - t.Log(body) var obj types.Service formatJSON(body, &obj) assert.Equal(t, 200, rr.Code) @@ -162,7 +159,6 @@ func TestApiDeleteServiceHandler(t *testing.T) { rr, err := httpRequestAPI(t, "DELETE", "/api/services/1", nil) assert.Nil(t, err) body := rr.Body.String() - t.Log(body) var obj ApiResponse formatJSON(body, &obj) assert.Equal(t, 200, rr.Code) @@ -171,11 +167,9 @@ func TestApiDeleteServiceHandler(t *testing.T) { } func TestApiAllUsersHandler(t *testing.T) { - rr, err := httpRequestAPI(t, "GET", "/api/users", nil) assert.Nil(t, err) body := rr.Body.String() - t.Log(body) assert.Equal(t, 200, rr.Code) var obj []types.User formatJSON(body, &obj) diff --git a/handlers/handlers.go b/handlers/handlers.go index a1ac89db..7291bd7e 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -162,7 +162,7 @@ func executeResponse(w http.ResponseWriter, r *http.Request, file string, data i return } - templates := []string{"base.html", "head.html", "nav.html", "footer.html", "scripts.html", "form_service.html", "form_notifier.html", "form_user.html"} + templates := []string{"base.html", "head.html", "nav.html", "footer.html", "scripts.html", "form_service.html", "form_notifier.html", "form_user.html", "form_checkin.html"} javascripts := []string{"charts.js", "chart_index.js"} diff --git a/handlers/routes.go b/handlers/routes.go index 7f957d53..ac6010f1 100644 --- a/handlers/routes.go +++ b/handlers/routes.go @@ -62,6 +62,7 @@ func Router() *mux.Router { r.Handle("/service/{id}/delete", http.HandlerFunc(servicesDeleteHandler)) r.Handle("/service/{id}/delete_failures", http.HandlerFunc(servicesDeleteFailuresHandler)).Methods("GET") r.Handle("/service/{id}/checkin", http.HandlerFunc(checkinCreateUpdateHandler)).Methods("POST") + r.Handle("/checkin/{id}", http.HandlerFunc(checkinUpdateHandler)) r.Handle("/users", http.HandlerFunc(usersHandler)).Methods("GET") r.Handle("/users", http.HandlerFunc(createUserHandler)).Methods("POST") r.Handle("/user/{id}", http.HandlerFunc(usersEditHandler)).Methods("GET") diff --git a/handlers/services.go b/handlers/services.go index bde5bddf..1c2abcb5 100644 --- a/handlers/services.go +++ b/handlers/services.go @@ -23,6 +23,7 @@ import ( "github.com/hunterlong/statup/types" "github.com/hunterlong/statup/utils" "github.com/jinzhu/now" + "net" "net/http" "strconv" "time" @@ -257,14 +258,30 @@ func checkinCreateUpdateHandler(w http.ResponseWriter, r *http.Request) { return } vars := mux.Vars(r) + service := core.SelectService(utils.StringInt(vars["id"])) + interval := utils.StringInt(r.PostForm.Get("interval")) - serv := core.SelectService(utils.StringInt(vars["id"])) - service := serv - checkin := &types.Checkin{ - Service: service.Id, - Interval: interval, - ApiKey: utils.NewSHA1Hash(18), - } + grace := utils.StringInt(r.PostForm.Get("grace")) + checkin := core.ReturnCheckin(&types.Checkin{ + Service: service.Id, + Interval: interval, + GracePeriod: grace, + ApiKey: utils.NewSHA1Hash(18), + }) checkin.Create() - executeResponse(w, r, "service.html", service, "/services") + executeResponse(w, r, "service.html", service, fmt.Sprintf("/service/%v", service.Id)) +} + +func checkinUpdateHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + checkin := core.SelectCheckin(vars["id"]) + ip, _, _ := net.SplitHostPort(r.RemoteAddr) + checkinHit := core.ReturnCheckinHit(&types.CheckinHit{ + Checkin: checkin.Id, + From: ip, + CreatedAt: time.Now().UTC(), + }) + checkinHit.Create() + w.Write([]byte("ok")) + w.WriteHeader(http.StatusOK) } diff --git a/notifiers/webhook.go b/notifiers/webhook.go index c34a79f8..e576083b 100644 --- a/notifiers/webhook.go +++ b/notifiers/webhook.go @@ -60,7 +60,7 @@ var webhook = &Webhook{¬ifier.Notification{ Type: "textarea", Title: "HTTP Body", Placeholder: `{"service_id": "%s.Id", "service_name": "%s.Name"}`, - SmallText: "Optional HTTP body for a POST request. You can insert variables into your body request.
%service.Id, %service.Name
%failure.Issue", + SmallText: "Optional HTTP body for a POST request. You can insert variables into your body request.
%service.Id, %service.Name, %service.Online
%failure.Issue", DbField: "Var2", }, { Type: "text", @@ -87,8 +87,10 @@ func init() { // Send will send a HTTP Post to the Webhook API. It accepts type: string func (w *Webhook) Send(msg interface{}) error { - message := msg.(string) - _, err := w.run(message) + resp, err := w.run(msg.(string)) + if err == nil { + resp.Body.Close() + } return err } @@ -100,6 +102,7 @@ func replaceBodyText(body string, s *types.Service, f *types.Failure) string { if s != nil { body = strings.Replace(body, "%service.Name", s.Name, -1) body = strings.Replace(body, "%service.Id", utils.ToString(s.Id), -1) + body = strings.Replace(body, "%service.Online", utils.ToString(s.Online), -1) } if f != nil { body = strings.Replace(body, "%failure.Issue", f.Issue, -1) diff --git a/notifiers/webhook_test.go b/notifiers/webhook_test.go index ef808728..da4b75bc 100644 --- a/notifiers/webhook_test.go +++ b/notifiers/webhook_test.go @@ -24,7 +24,7 @@ import ( var ( WEBHOOK_URL = "https://jsonplaceholder.typicode.com/posts" - webhookMessage = `{ "title": "%service.Id", "body": "%service.Name", "userId": 19999 }` + webhookMessage = `{ "title": "%service.Id", "body": "%service.Name", "online": %service.Online, "userId": 19999 }` fullMsg string ) @@ -56,7 +56,7 @@ func TestWebhookNotifier(t *testing.T) { t.Run("Webhook Replace Body Text", func(t *testing.T) { fullMsg = replaceBodyText(webhookMessage, TestService, TestFailure) - assert.Equal(t, 78, len(fullMsg)) + assert.Equal(t, "{ \"title\": \"1\", \"body\": \"Interpol - All The Rage Back Home\", \"online\": false, \"userId\": 19999 }", fullMsg) }) t.Run("Webhook Within Limits", func(t *testing.T) { @@ -96,7 +96,7 @@ func TestWebhookNotifier(t *testing.T) { t.Run("Webhook Queue", func(t *testing.T) { go notifier.Queue(webhook) - time.Sleep(5 * time.Second) + time.Sleep(8 * time.Second) assert.Equal(t, WEBHOOK_URL, webhook.Host) assert.Equal(t, 1, len(webhook.Queue)) }) diff --git a/source/tmpl/form_checkin.html b/source/tmpl/form_checkin.html new file mode 100644 index 00000000..e87f8cd9 --- /dev/null +++ b/source/tmpl/form_checkin.html @@ -0,0 +1,19 @@ +{{define "form_checkin"}} +
+
+
+ + +
+
+ + +
+
+
+
+ +
+
+
+{{end}} diff --git a/source/tmpl/service.html b/source/tmpl/service.html index 4adc134e..fb1c0c7a 100644 --- a/source/tmpl/service.html +++ b/source/tmpl/service.html @@ -96,30 +96,20 @@ -

Service Checkins

{{ range $s.Checkins }} -
Check #{{.Id}} Checked in {{.Ago}}
- +
Check #{{.Id}} Checked in
+ + {{ end }} -
-
- -
- -
-
- -
-
-
-
- -
-
-
+ {{template "form_checkin" $s}} +
{{end}} diff --git a/types/checkin.go b/types/checkin.go index 9caa72d6..bf2b1e49 100644 --- a/types/checkin.go +++ b/types/checkin.go @@ -20,15 +20,14 @@ import ( ) type Checkin struct { - Id int64 `gorm:"primary_key;column:id"` - Service int64 `gorm:"index;column:service"` - Interval int64 `gorm:"column:check_interval"` - GracePeriod int64 `gorm:"column:grace_period"` - ApiKey string `gorm:"column:api_key"` - CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` - UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` - Hits []CheckinHit `json:"hits"` - CheckinInterface `json:"-"` + Id int64 `gorm:"primary_key;column:id"` + Service int64 `gorm:"index;column:service"` + Interval int64 `gorm:"column:check_interval"` + GracePeriod int64 `gorm:"column:grace_period"` + ApiKey string `gorm:"column:api_key"` + CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` + UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` + Hits []CheckinHit `json:"hits"` } type CheckinHit struct { @@ -37,12 +36,3 @@ type CheckinHit struct { From string `gorm:"column:from_location"` CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` } - -type CheckinInterface interface { - // Database functions - Create() (int64, error) - //Update() error - //Delete() error - Ago() string - Receivehit() -} diff --git a/types/service.go b/types/service.go index bb6f6610..72878cb9 100644 --- a/types/service.go +++ b/types/service.go @@ -56,7 +56,6 @@ type ServiceInterface interface { Create(bool) (int64, error) Update(bool) error Delete() error - Checkins() []*Checkin } // Start will create a channel for the service checking go routine diff --git a/utils/utils.go b/utils/utils.go index f8626f8e..d18b8a70 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -56,8 +56,14 @@ func ToString(s interface{}) string { return fmt.Sprintf("%v", v) case []byte: return string(v) + case bool: + if v { + return "true" + } + return "false" + default: + return fmt.Sprintf("%v", v) } - return "" } func Timezoner(t time.Time, zone float32) time.Time {