service permalink - tests - dev docs

pull/127/head
hunterlong 2019-02-06 10:51:30 -08:00
parent 69b3cb43bf
commit f9b6c1f54e
19 changed files with 3645 additions and 2108 deletions

36
Gopkg.lock generated
View File

@ -3,14 +3,14 @@
[[projects]]
branch = "master"
digest = "1:65796e5fdb94d94bc0ee6bc422aa3541dbe69ed4da275cb5a27f8fa141f4e35c"
digest = "1:6212ce7f839b40213d1ff75c3df7816c4023faf4d29da630ce1dfdd1ccd5fb02"
name = "github.com/GeertJohan/go.rice"
packages = [
".",
"embedded",
]
pruneopts = "UT"
revision = "c02ca9a983da5807ddf7d796784928f5be4afd09"
revision = "0af3f3b09a0a8b391f63ab52ba5ab50f84fabd30"
[[projects]]
digest = "1:f1ec92a2b8473612547f6e13edbc8c8e6cda6c8be9c54b31958aad4a7ccaaa2b"
@ -69,12 +69,12 @@
version = "v1.1.1"
[[projects]]
digest = "1:e73f5b0152105f18bc131fba127d9949305c8693f8a762588a82a48f61756f5f"
digest = "1:ca59b1175189b3f0e9f1793d2c350114be36eaabbe5b9f554b35edee1de50aea"
name = "github.com/gorilla/mux"
packages = ["."]
pruneopts = "UT"
revision = "e3702bed27f0d39777b0b37b664b6280e8ef8fbf"
version = "v1.6.2"
revision = "a7962380ca08b5a188038c69871b8d3fbdf31e89"
version = "v1.7.0"
[[projects]]
digest = "1:e72d1ebb8d395cf9f346fd9cbc652e5ae222dd85e0ac842dc57f175abed6d195"
@ -121,14 +121,6 @@
revision = "23d116af351c84513e1946b527c88823e476be13"
version = "v1.3.0"
[[projects]]
branch = "master"
digest = "1:caf6db28595425c0e0f2301a00257d11712f65c1878e12cffc42f6b9a9cf3f23"
name = "github.com/kardianos/osext"
packages = ["."]
pruneopts = "UT"
revision = "ae77be60afb1dcacde03767a8c37337fad28ac14"
[[projects]]
digest = "1:b18ffc558326ebaed3b4a175617f1e12ed4e3f53d6ebfe5ba372a3de16d22278"
name = "github.com/lib/pq"
@ -166,20 +158,20 @@
revision = "6283090d169f51a2410b4e260341a01c9a4c0ca7"
[[projects]]
branch = "master"
digest = "1:def689e73e9252f6f7fe66834a76751a41b767e03daab299e607e7226c58a855"
digest = "1:9421f6e9e28ef86933e824b5caff441366f2b69bb281085b9dca40e1f27a1602"
name = "github.com/shurcooL/sanitized_anchor_name"
packages = ["."]
pruneopts = "UT"
revision = "86672fcb3f950f35f2e675df2240550f2a50762f"
revision = "7bfe4c7ecddb3666a94b053b422cdd8f5aaa3615"
version = "v1.0.0"
[[projects]]
digest = "1:18752d0b95816a1b777505a97f71c7467a8445b8ffb55631a7bf779f6ba4fa83"
digest = "1:972c2427413d41a1e06ca4897e8528e5a1622894050e2f527b38ddf0f343f759"
name = "github.com/stretchr/testify"
packages = ["assert"]
pruneopts = "UT"
revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686"
version = "v1.2.2"
revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053"
version = "v1.3.0"
[[projects]]
branch = "master"
@ -190,15 +182,15 @@
"blowfish",
]
pruneopts = "UT"
revision = "505ab145d0a99da450461ae2c1a9f6cd10d1f447"
revision = "b8fe1690c61389d7d2a8074a507d1d40c5d30448"
[[projects]]
digest = "1:c25289f43ac4a68d88b02245742347c94f1e108c534dda442188015ff80669b3"
name = "google.golang.org/appengine"
packages = ["cloudsql"]
pruneopts = "UT"
revision = "4a4468ece617fc8205e99368fa2200e9d1fad421"
version = "v1.3.0"
revision = "e9657d882bb81064595ca3b56cbe2546bbabf7b1"
version = "v1.4.0"
[[projects]]
branch = "v3"

View File

@ -43,7 +43,7 @@
[[constraint]]
name = "github.com/gorilla/mux"
version = "1.6.2"
version = "1.7.0"
[[constraint]]
name = "github.com/gorilla/sessions"
@ -63,7 +63,7 @@
[[constraint]]
name = "github.com/stretchr/testify"
version = "1.2.2"
version = "1.3.0"
[[constraint]]
branch = "master"
@ -80,9 +80,3 @@
[prune]
go-tests = true
unused-packages = true
[metadata.heroku]
root-package = "github.com/hunterlong/statping"
go-version = "1.11"
install = [ "./cmd" ]
additional-tools = ["github.com/GeertJohan/go.rice/..."]

View File

@ -98,15 +98,18 @@ coverage:
# generate documentation for Statping functions
docs:
godoc2md -ex github.com/hunterlong/statping >> dev/README.md
godoc2md -ex github.com/hunterlong/statping/cmd >> dev/README.md
godoc2md -ex github.com/hunterlong/statping/core > dev/README.md
godoc2md -ex github.com/hunterlong/statping/handlers >> dev/README.md
godoc2md -ex github.com/hunterlong/statping/notifiers >> dev/README.md
godoc2md -ex github.com/hunterlong/statping/plugin >> dev/README.md
godoc2md -ex github.com/hunterlong/statping/source >> dev/README.md
godoc2md -ex github.com/hunterlong/statping/types >> dev/README.md
godoc2md -ex github.com/hunterlong/statping/utils >> dev/README.md
rm -f dev/README.md
printf "# Statping Dev Documentation\n" > dev/README.md
printf "This readme is automatically generated from the Golang documentation. [![GoDoc](https://godoc.org/github.com/golang/gddo?status.svg)](https://godoc.org/github.com/hunterlong/statping)\n\n" > dev/README.md
godocdown github.com/hunterlong/statping >> dev/README.md
godocdown github.com/hunterlong/statping/cmd >> dev/README.md
godocdown github.com/hunterlong/statping/core >> dev/README.md
godocdown github.com/hunterlong/statping/handlers >> dev/README.md
godocdown github.com/hunterlong/statping/notifiers >> dev/README.md
godocdown github.com/hunterlong/statping/plugin >> dev/README.md
godocdown github.com/hunterlong/statping/source >> dev/README.md
godocdown github.com/hunterlong/statping/types >> dev/README.md
godocdown github.com/hunterlong/statping/utils >> dev/README.md
gocov-html coverage.json > dev/COVERAGE.html
revive -formatter stylish > dev/LINT.md
@ -215,6 +218,7 @@ dev-deps:
$(GOGET) github.com/mattn/goveralls
$(GOINSTALL) github.com/mattn/goveralls
$(GOGET) github.com/rendon/testcli
$(GOGET) github.com/robertkrimen/godocdown/godocdown
$(GOGET) github.com/karalabe/xgo
$(GOGET) github.com/GeertJohan/go.rice
$(GOGET) github.com/GeertJohan/go.rice/rice

View File

@ -39,6 +39,7 @@ func InsertSampleData() error {
Timeout: 10,
Order: 1,
GroupId: 1,
Permalink: types.NewNullString("google"),
CreatedAt: createdOn,
})
s2 := ReturnService(&types.Service{
@ -50,6 +51,7 @@ func InsertSampleData() error {
Method: "GET",
Timeout: 20,
Order: 2,
Permalink: types.NewNullString("statping_github"),
CreatedAt: createdOn,
})
s3 := ReturnService(&types.Service{

View File

@ -55,6 +55,16 @@ func SelectService(id int64) *Service {
return nil
}
// SelectServiceLink returns a *core.Service from the service permalink
func SelectServiceLink(permalink string) *Service {
for _, s := range Services() {
if s.Select().Permalink.String == permalink {
return s.(*Service)
}
}
return nil
}
// CheckinProcess runs the checkin routine for each checkin attached to service
func (s *Service) CheckinProcess() {
checkins := s.AllCheckins()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -90,6 +90,18 @@ func TestMainApiRoutes(t *testing.T) {
Method: "GET",
ExpectedStatus: 200,
ExpectedContains: []string{`"name":"Tester","description":"This is an awesome test"`},
},
{
Name: "Statping Renew API Keys",
URL: "/api/renew",
Method: "POST",
ExpectedStatus: 303,
},
{
Name: "Statping Clear Cache",
URL: "/api/clear_cache",
Method: "POST",
ExpectedStatus: 303,
}}
for _, v := range tests {
@ -127,6 +139,27 @@ func TestApiServiceRoutes(t *testing.T) {
Body: "",
ExpectedStatus: 200,
},
{
Name: "Statping Service 1 Ping Data",
URL: "/api/services/1/ping",
Method: "GET",
Body: "",
ExpectedStatus: 200,
},
{
Name: "Statping Service 1 Heatmap Data",
URL: "/api/services/1/heatmap",
Method: "GET",
Body: "",
ExpectedStatus: 200,
},
{
Name: "Statping Service 1 Hits",
URL: "/api/services/1/hits",
Method: "GET",
Body: "",
ExpectedStatus: 200,
},
{
Name: "Statping Service 1 Failures",
URL: "/api/services/1/failures",
@ -136,7 +169,7 @@ func TestApiServiceRoutes(t *testing.T) {
},
{
Name: "Statping Reorder Services",
URL: "/api/services/reorder",
URL: "/api/reorder",
Method: "POST",
Body: `[{"service":1,"order":1},{"service":5,"order":2},{"service":2,"order":3},{"service":3,"order":4},{"service":4,"order":5}]`,
ExpectedStatus: 200,

View File

@ -1,6 +1,7 @@
package handlers
import (
"github.com/hunterlong/statping/utils"
"github.com/stretchr/testify/assert"
"net/url"
"testing"
@ -16,6 +17,9 @@ func TestGenericRoutes(t *testing.T) {
form2.Add("username", "admin")
form2.Add("password", "wrongpassword")
form3 := url.Values{}
form3.Add("variables", "$background-color: #fcfcfc;")
tests := []HTTPTest{
{
Name: "Statping Index",
@ -98,6 +102,39 @@ func TestGenericRoutes(t *testing.T) {
ExpectedStatus: 200,
ExpectedContains: []string{"statping_total_services 5"},
},
{
Name: "Last Log Line",
URL: "/logs/line",
Method: "GET",
ExpectedStatus: 200,
},
{
Name: "Export JSON file of all objcts",
URL: "/settings/export",
Method: "GET",
ExpectedStatus: 200,
},
{
Name: "Export Static Assets",
URL: "/settings/build",
Method: "GET",
ExpectedStatus: 303,
ExpectedFiles: []string{utils.Directory + "/assets/css/base.css"},
},
{
Name: "Save SCSS",
URL: "/settings/css",
Method: "POST",
Body: form3.Encode(),
ExpectedStatus: 303,
HttpHeaders: []string{"Content-Type=application/x-www-form-urlencoded"},
},
{
Name: "Delete Assets",
URL: "/settings/delete_assets",
Method: "GET",
ExpectedStatus: 303,
},
}
for _, v := range tests {

View File

@ -107,6 +107,12 @@ var handlerFuncs = func(w http.ResponseWriter, r *http.Request) template.FuncMap
}
return utils.Timezoner(time.Unix(t, 0), core.CoreApp.Timezone).String()
},
"ServiceLink": func(s *core.Service) string {
if s.Permalink.Valid {
return s.Permalink.String
}
return utils.ToString(s.Id)
},
"NewService": func() *types.Service {
return new(types.Service)
},

View File

@ -30,7 +30,8 @@ var (
router *mux.Router
)
// Router returns all of the routes used in Statping
// Router returns all of the routes used in Statping.
// Server will use static assets if the 'assets' directory is found in the root directory.
func Router() *mux.Router {
dir := utils.Directory
CacheStorage = NewStorage()

View File

@ -24,6 +24,7 @@ import (
"github.com/hunterlong/statping/types"
"github.com/hunterlong/statping/utils"
"net/http"
"strconv"
"time"
)
@ -86,15 +87,22 @@ func servicesViewHandler(w http.ResponseWriter, r *http.Request) {
fields := parseGet(r)
r.ParseForm()
startField := utils.ToInt(fields.Get("start"))
endField := utils.ToInt(fields.Get("end"))
group := r.Form.Get("group")
serv := core.SelectService(utils.ToInt(vars["id"]))
var serv *core.Service
id := vars["id"]
if _, err := strconv.Atoi(id); err == nil {
serv = core.SelectService(utils.ToInt(id))
} else {
serv = core.SelectServiceLink(id)
}
if serv == nil {
w.WriteHeader(http.StatusNotFound)
return
}
startField := utils.ToInt(fields.Get("start"))
endField := utils.ToInt(fields.Get("end"))
group := r.Form.Get("group")
end := time.Now().UTC()
start := end.Add((-24 * 7) * time.Hour).UTC()

View File

@ -20,7 +20,13 @@ func TestServiceRoutes(t *testing.T) {
Method: "GET",
ExpectedStatus: 200,
ExpectedContains: []string{`<title>Statping Github Status</title>`},
}}
}, {
Name: "chart.js index file",
URL: "/charts.js",
Method: "GET",
ExpectedStatus: 200,
},
}
for _, v := range tests {
t.Run(v.Name, func(t *testing.T) {

View File

@ -82,9 +82,10 @@ func saveSASSHandler(w http.ResponseWriter, r *http.Request) {
return
}
r.ParseForm()
theme := r.PostForm.Get("theme")
variables := r.PostForm.Get("variables")
mobile := r.PostForm.Get("mobile")
form := r.PostForm
theme := form.Get("theme")
variables := form.Get("variables")
mobile := form.Get("mobile")
source.SaveAsset([]byte(theme), utils.Directory, "scss/base.scss")
source.SaveAsset([]byte(variables), utils.Directory, "scss/variables.scss")
source.SaveAsset([]byte(mobile), utils.Directory, "scss/mobile.scss")

View File

@ -86,6 +86,13 @@
<small class="form-text text-muted">If the endpoint does not respond within this time it will be considered to be offline</small>
</div>
</div>
<div class="form-group row">
<label for="post_data" class="col-sm-4 col-form-label">Permalink URL</label>
<div class="col-sm-8">
<input type="text" name="permalink" class="form-control" value="{{.Permalink.String}}" id="permalink" autocapitalize="none" spellcheck="true" placeholder='awesome_service'>
<small class="form-text text-muted">Use text for the service URL rather than the service number.</small>
</div>
</div>
<div class="form-group row d-none">
<label for="order" class="col-sm-4 col-form-label">List Order</label>
<div class="col-sm-8">
@ -107,7 +114,7 @@
<label for="order" class="col-sm-4 col-form-label">Visible</label>
<div class="col-8 mt-1">
<span class="switch float-left">
<input type="checkbox" name="public-option" class="switch" id="switch-public" {{if .Public.Bool}}checked{{end}}>
<input type="checkbox" name="public-option" class="switch" id="switch-public" {{if eq .Id 0}}checked{{else}}{{if .Public.Bool}}checked{{end}}{{end}}>
<label for="switch-public">Show service details to the public</label>
<input type="hidden" name="public" id="switch-public-value" value="{{if .Public.Bool}}true{{else}}false{{end}}">
</span>

View File

@ -57,7 +57,7 @@
<div class="card">
<div class="card-body">
<div class="col-12">
<h4 class="mt-3"><a href="/service/{{.Id}}"{{if not .Online}} class="text-danger"{{end}}>{{ .Name }}</a>
<h4 class="mt-3"><a href="/service/{{ServiceLink .}}"{{if not .Online}} class="text-danger"{{end}}>{{ .Name }}</a>
{{if .Online}}
<span class="badge bg-success float-right">ONLINE</span>
{{ else }}
@ -91,7 +91,7 @@
<span class="d-none d-md-inline">{{.SmallText}}</span>
</div>
<div class="col-sm-12 col-md-2">
<a href="/service/{{ .Id }}" class="btn {{if .Online}}btn-success{{else}}btn-danger{{end}} btn-sm float-right dyn-dark btn-block">View Service</a>
<a href="/service/{{ServiceLink .}}" class="btn {{if .Online}}btn-success{{else}}btn-danger{{end}} btn-sm float-right dyn-dark btn-block">View Service</a>
</div>
</div>

View File

@ -23,7 +23,7 @@
<td class="d-none d-md-table-cell">{{if .Public.Bool}}<span class="badge badge-primary">PUBLIC</span>{{else}}<span class="badge badge-secondary">PRIVATE</span>{{end}}</td>
<td class="text-right">
<div class="btn-group">
<a href="/service/{{.Id}}" class="btn btn-outline-secondary"><i class="fas fa-chart-area"></i> View</a>
<a href="/service/{{ServiceLink .}}" class="btn btn-outline-secondary"><i class="fas fa-chart-area"></i> View</a>
{{if Auth}}<a href="/api/services/{{.Id}}" class="ajax_delete btn btn-danger" data-method="DELETE" data-obj="service_{{.Id}}" data-id="{{.Id}}"><i class="fas fa-times"></i></a>{{end}}
</div>
</td>

File diff suppressed because one or more lines are too long

View File

@ -36,6 +36,7 @@ type Service struct {
AllowNotifications NullBool `gorm:"default:true;column:allow_notifications" json:"allow_notifications"`
Public NullBool `gorm:"default:true;column:public" json:"public"`
GroupId int `gorm:"default:0;column:group_id" json:"group_id"`
Permalink NullString `gorm:"column:permalink" json:"permalink"`
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
Online bool `gorm:"-" json:"online"`