From 4ab4b1f5c093bd78a22e0433494b8983e82f7a83 Mon Sep 17 00:00:00 2001 From: Hunter Long Date: Wed, 15 Aug 2018 18:07:02 -0700 Subject: [PATCH] footer fix - SASS compile fix - additional testing --- .dockerignore | 23 +++++----- .travis.yml | 3 +- .travis/Dockerfile | 25 +++++++++++ Dockerfile-dev | 30 ------------- Makefile | 30 +++++++++---- README.md | 3 +- Dockerfile => cmd/Dockerfile | 5 +-- cmd/cli.go | 26 +++++++---- cmd/cli_test.go | 87 ++++++++++++++++++++++++++++++++++++ cmd/main.go | 6 ++- cmd/main_test.go | 36 --------------- core/core_test.go | 7 +++ core/export.go | 7 +++ core/services_test.go | 51 +++++++++++++++++++++ core/users_test.go | 58 ++++++++++++++++++++++-- handlers/handlers.go | 3 ++ handlers/handlers_test.go | 26 ++++++++--- source/source.go | 72 ++++++++++++++++++++++++++--- source/source_test.go | 8 ++-- source/tmpl/footer.html | 9 ++-- utils/utils.go | 9 ++++ utils/utils_test.go | 8 ++++ 22 files changed, 409 insertions(+), 123 deletions(-) create mode 100644 .travis/Dockerfile delete mode 100644 Dockerfile-dev rename Dockerfile => cmd/Dockerfile (80%) create mode 100644 cmd/cli_test.go diff --git a/.dockerignore b/.dockerignore index c3751463..60a6cd79 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,11 +1,12 @@ -.git -.gitignore -Dockerfile -Dockerfile-dev -.travis.yml -.travis -servers -build -logs -coverage.out -*.db \ No newline at end of file +** + +!/source +!/types +!/utils +!/plugin +!/notifiers +!/handlers +!/core +!/cmd +!/Makefile +!/README.md \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index b48b4dba..b83c291c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,12 +55,11 @@ before_script: - mysql -e 'CREATE DATABASE IF NOT EXISTS test;' - psql -c 'create database test;' -U postgres - make deps + - make install script: - - make install - make test - if [[ "$TRAVIS_BRANCH" == "master" ]]; then make coverage; fi - - make docker-test after_success: - if [[ "$TRAVIS_BRANCH" == "master" ]]; then travis_wait 30 docker pull karalabe/xgo-latest; fi diff --git a/.travis/Dockerfile b/.travis/Dockerfile new file mode 100644 index 00000000..9a9011f8 --- /dev/null +++ b/.travis/Dockerfile @@ -0,0 +1,25 @@ +FROM golang:1.10.3-alpine + +RUN apk add --no-cache libstdc++ gcc g++ make git ca-certificates linux-headers + +RUN wget -q https://assets.statup.io/sass && \ + chmod +x sass && \ + mv sass /usr/local/bin/sass +RUN sass -v + +WORKDIR $GOPATH/src/github.com/hunterlong/statup + +COPY . . +RUN make deps +RUN make compile +RUN make install + +ENV VERSION=$(VERSION) +ENV IS_DOCKER=true +ENV SASS=/usr/local/bin/sass +ENV ONLY_DB=sqlite +ENV STATUP_DIR=/go/src/github.com/hunterlong/statup +ENV GO_ENV=test + +EXPOSE 8080 +ENTRYPOINT SASS=$(SASS) VERSION=$(VERSION) make test \ No newline at end of file diff --git a/Dockerfile-dev b/Dockerfile-dev deleted file mode 100644 index 59bbc3e8..00000000 --- a/Dockerfile-dev +++ /dev/null @@ -1,30 +0,0 @@ -FROM golang:1.10.3 - -WORKDIR $GOPATH/src/github.com/hunterlong/statup - -COPY . . -ADD ./Makefile ./Makefile -RUN make deps -RUN make compile -RUN make install - -RUN apt update && \ - apt install -y postgresql apg - -RUN wget -q https://assets.statup.io/sass && \ - chmod +x sass && \ - mv sass /usr/local/bin/sass - -ENV VERSION=$(VERSION) -ENV IS_DOCKER=true -ENV SASS=/usr/local/bin/sass -ENV CMD_FILE=/usr/bin/cmd -ENV ONLY_DB=sqlite -ENV STATUP_DIR=/go/src/github.com/hunterlong/statup -ENV GO_ENV=test - -RUN printf "#!/usr/bin/env sh\n\$1\n" > $CMD_FILE && \ - chmod +x $CMD_FILE - -EXPOSE 8080 -ENTRYPOINT go test ./... -p 1 -ldflags="-X main.VERSION=$(VERSION)" -coverprofile=coverage.out -v \ No newline at end of file diff --git a/Makefile b/Makefile index 177c2f56..11ba124a 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION=0.4 +VERSION=0.41 GOPATH:=$(GOPATH) GOCMD=go GOBUILD=$(GOCMD) build @@ -20,11 +20,11 @@ all: deps compile install clean release: deps build-all compress -install: build +install: clean build mv $(BINARY_NAME) $(GOPATH)/bin/$(BINARY_NAME) $(GOPATH)/bin/$(BINARY_NAME) version -build: +build: compile $(GOBUILD) -ldflags="-X main.VERSION=$(VERSION)" -o $(BINARY_NAME) -v ./cmd run: build @@ -34,8 +34,8 @@ compile: cd source && $(GOPATH)/bin/rice embed-go $(GOPATH)/bin/wt compile source/scss/base.scss -b source/css -test: compile test-env - $(GOTEST) ./... -p 1 -ldflags="-X main.VERSION=$(VERSION)" -coverprofile=coverage.out -v +test: clean compile test-env + gocov test -v ./... -p 1 -ldflags="-X main.VERSION=$(VERSION)" -covermode=count > coverage.json test-all: compile test-env databases $(GOTEST) ./... -p 1 -ldflags="-X main.VERSION=$(VERSION)" -coverprofile=coverage.out -v @@ -43,6 +43,11 @@ test-all: compile test-env databases coverage: $(GOPATH)/bin/goveralls -coverprofile=coverage.out -service=travis -repotoken $(COVERALLS) +docs: + godoc2md github.com/hunterlong/statup > servers/docs/README.md + gocov-html coverage.json > servers/docs/COVERAGE.html + revive -formatter stylish > servers/docs/LINT.md + build-all: clean compile mkdir build $(XGO) $(BUILDVERSION) --targets=darwin/amd64 ./cmd @@ -55,10 +60,10 @@ build-all: clean compile $(XGO) --targets=linux/amd64 -ldflags="-X main.VERSION=$VERSION -linkmode external -extldflags -static" -out alpine ./cmd docker: - $(DOCKER) build -t hunterlong/statup:latest . + $(DOCKER) build -t hunterlong/statup:latest -f ./cmd/Dockerfile . docker-dev: - $(DOCKER) build -t hunterlong/statup:dev -f Dockerfile-dev . + $(DOCKER) build -t hunterlong/statup:dev -f ./.travis/Dockerfile . docker-run: docker $(DOCKER) run -t -p 8080:8080 hunterlong/statup:latest @@ -85,6 +90,12 @@ deps: $(GOGET) github.com/GeertJohan/go.rice $(GOGET) github.com/GeertJohan/go.rice/rice $(GOINSTALL) github.com/GeertJohan/go.rice/rice + $(GOCMD) get github.com/davecheney/godoc2md + $(GOCMD) install github.com/davecheney/godoc2md + $(GOCMD) get github.com/axw/gocov/gocov + $(GOCMD) get -u gopkg.in/matm/v1/gocov-html + $(GOCMD) install gopkg.in/matm/v1/gocov-html + $(GOCMD) get -u github.com/mgechev/revive $(GOGET) -d ./... clean: @@ -117,7 +128,6 @@ test-env: export DB_PASS=password123 export DB_DATABASE=root export NAME=Demo - export CMD_FILE=$(GOPATH)/src/github.com/hunterlong/statup/cmd.sh export STATUP_DIR=$(GOPATH)/src/github.com/hunterlong/statup compress: @@ -154,4 +164,6 @@ publish: -d "$(PUBLISH_BODY)" \ https://api.travis-ci.com/repo/hunterlong%2Fstatup-testing/requests curl -H "Content-Type: application/json" \ - --data '{"docker_tag": "dev"}' -X POST $(DOCKER) \ No newline at end of file + --data '{"docker_tag": "dev"}' -X POST $(DOCKER) + +.PHONY: build build-all \ No newline at end of file diff --git a/README.md b/README.md index 9b909ba6..83b45ca0 100644 --- a/README.md +++ b/README.md @@ -141,8 +141,7 @@ Statup accepts Push Requests! Feel free to add your own features and notifiers. [![Go Report Card](https://goreportcard.com/badge/github.com/hunterlong/statup)](https://goreportcard.com/report/github.com/hunterlong/statup) [![Build Status](https://travis-ci.org/hunterlong/statup.svg?branch=master)](https://travis-ci.org/hunterlong/statup) [![Cypress.io tests](https://img.shields.io/badge/cypress.io-tests-green.svg?style=flat-square)](https://dashboard.cypress.io/#/projects/bi8mhr/runs) -[![Docker Pulls](https://img.shields.io/docker/pulls/hunterlong/statup.svg)](https://hub.docker.com/r/hunterlong/statup/builds/) -[![Godoc](https://godoc.org/github.com/hunterlong/statup?status.svg)](https://godoc.org/github.com/hunterlong/statup) +[![Docker Pulls](https://img.shields.io/docker/pulls/hunterlong/statup.svg)](https://hub.docker.com/r/hunterlong/statup/builds/) [![Godoc](https://godoc.org/github.com/hunterlong/statup?status.svg)](https://godoc.org/github.com/hunterlong/statup)[![Coverage Status](https://coveralls.io/repos/github/hunterlong/statup/badge.svg?branch=master)](https://coveralls.io/github/hunterlong/statup?branch=master) diff --git a/Dockerfile b/cmd/Dockerfile similarity index 80% rename from Dockerfile rename to cmd/Dockerfile index 22f8ffcc..145d1991 100644 --- a/Dockerfile +++ b/cmd/Dockerfile @@ -14,10 +14,7 @@ RUN wget -q https://assets.statup.io/sass && \ ENV IS_DOCKER=true ENV SASS=/usr/local/bin/sass -ENV CMD_FILE=/usr/bin/cmd - -RUN printf "#!/usr/bin/env sh\n\$1\n" > $CMD_FILE && \ - chmod +x $CMD_FILE +ENV STATUP_DIR=/app WORKDIR /app VOLUME /app diff --git a/cmd/cli.go b/cmd/cli.go index 3f6d6a61..3206c1a4 100644 --- a/cmd/cli.go +++ b/cmd/cli.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "errors" "fmt" "github.com/hunterlong/statup/core" "github.com/hunterlong/statup/source" @@ -11,7 +12,6 @@ import ( "io/ioutil" "math/rand" "net/http" - "os" "strings" "time" "upper.io/db.v3/sqlite" @@ -22,21 +22,23 @@ const ( POINT = " " ) -func CatchCLI(args []string) { +func CatchCLI(args []string) error { dir := utils.Directory + source.Assets() switch args[1] { case "version": fmt.Printf("Statup v%v\n", VERSION) + return nil case "assets": - source.Assets() - source.CreateAllAssets(dir) + err := source.CreateAllAssets(dir) + return err case "sass": - source.CompileSASS(dir) + err := source.CompileSASS(dir) + return err case "update": gitCurrent, err := CheckGithubUpdates() if err != nil { - fmt.Println(err) - os.Exit(2) + return nil } fmt.Printf("Statup Version: v%v\nLatest Version: %v\n", VERSION, gitCurrent.TagName) if VERSION != gitCurrent.TagName[1:] { @@ -44,19 +46,21 @@ func CatchCLI(args []string) { } else { fmt.Printf("You have the latest version of Statup!\n") } + return nil case "test": cmd := args[2] switch cmd { case "plugins": LoadPlugins(true) } + return nil case "export": var err error fmt.Printf("Statup v%v Exporting Static 'index.html' page...\n", VERSION) - source.Assets() core.Configs, err = core.LoadConfig() if err != nil { utils.Log(4, "config.yml file not found") + return err } RunOnce() indexSource := core.ExportIndexHTML() @@ -67,22 +71,27 @@ func CatchCLI(args []string) { utils.Log(1, "Exported Statup index page: 'index.html'") case "help": HelpEcho() + return nil case "run": utils.Log(1, "Running 1 time and saving to database...") RunOnce() fmt.Println("Check is complete.") + return nil case "env": fmt.Println("Statup Environment Variables") envs, err := godotenv.Read(".env") if err != nil { utils.Log(4, "No .env file found in current directory.") + return err } for k, e := range envs { fmt.Printf("%v=%v\n", k, e) } default: utils.Log(3, "Statup does not have the command you entered.") + return errors.New("statup does not have the command you entered") } + return nil } func RunOnce() { @@ -118,6 +127,7 @@ func HelpEcho() { fmt.Println(" statup run - Check all services 1 time and then quit") fmt.Println(" statup test plugins - Test all plugins for required information") fmt.Println(" statup assets - Dump all assets used locally to be edited.") + fmt.Println(" statup sass - Compile .scss files into the css directory") fmt.Println(" statup env - Show all environment variables being used for Statup") fmt.Println(" statup export - Exports the index page as a static HTML for pushing") fmt.Println(" statup update - Attempts to update to the latest version") diff --git a/cmd/cli_test.go b/cmd/cli_test.go new file mode 100644 index 00000000..6e292f61 --- /dev/null +++ b/cmd/cli_test.go @@ -0,0 +1,87 @@ +package main + +import ( + "github.com/rendon/testcli" + "github.com/stretchr/testify/assert" + "os" + "testing" +) + +func TestVersionCommand(t *testing.T) { + c := testcli.Command("statup", "version") + c.Run() + assert.True(t, c.StdoutContains("Statup v"+VERSION)) +} + +func TestHelpCommand(t *testing.T) { + c := testcli.Command("statup", "help") + c.Run() + t.Log(c.Stdout()) + assert.True(t, c.StdoutContains("statup help - Shows the user basic information about Statup")) +} + +func TestExportCommand(t *testing.T) { + t.SkipNow() + c := testcli.Command("statup", "export") + c.Run() + t.Log(c.Stdout()) + assert.True(t, c.StdoutContains("Exporting Static 'index.html' page")) + assert.True(t, fileExists(dir+"/cmd/index.html")) +} + +func TestAssetsCommand(t *testing.T) { + c := testcli.Command("statup", "assets") + c.Run() + t.Log(c.Stdout()) + t.Log("Directory for Assets: ", dir) + assert.FileExists(t, dir+"/assets/robots.txt") + assert.FileExists(t, dir+"/assets/js/main.js") + assert.FileExists(t, dir+"/assets/scss/base.scss") +} + +func TestVersionCLI(t *testing.T) { + run := CatchCLI([]string{"statup", "version"}) + assert.Nil(t, run) +} + +func TestAssetsCLI(t *testing.T) { + run := CatchCLI([]string{"statup", "assets"}) + assert.Nil(t, run) + assert.FileExists(t, "../assets/css/base.css") + assert.FileExists(t, "../assets/scss/base.scss") +} + +func TestSassCLI(t *testing.T) { + if os.Getenv("IS_DOCKER") == "true" { + os.Setenv("SASS", "/usr/local/bin/sass") + } + run := CatchCLI([]string{"statup", "sass"}) + assert.Nil(t, run) + assert.FileExists(t, "../assets/css/base.css") +} + +func TestUpdateCLI(t *testing.T) { + run := CatchCLI([]string{"statup", "update"}) + assert.Nil(t, run) +} + +func TestTestPackageCLI(t *testing.T) { + run := CatchCLI([]string{"statup", "test", "plugins"}) + assert.Nil(t, run) +} + +func TestHelpCLI(t *testing.T) { + run := CatchCLI([]string{"statup", "help"}) + assert.Nil(t, run) +} + +func TestRunOnceCLI(t *testing.T) { + t.SkipNow() + run := CatchCLI([]string{"statup", "run"}) + assert.Nil(t, run) +} + +func TestEnvCLI(t *testing.T) { + run := CatchCLI([]string{"statup", "env"}) + assert.Error(t, run) +} diff --git a/cmd/main.go b/cmd/main.go index 4d7aca28..b064079e 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -30,7 +30,11 @@ func init() { func main() { var err error if len(os.Args) >= 2 { - CatchCLI(os.Args) + err := CatchCLI(os.Args) + if err != nil { + fmt.Println(err) + os.Exit(1) + } os.Exit(0) } utils.Log(1, fmt.Sprintf("Starting Statup v%v", VERSION)) diff --git a/cmd/main_test.go b/cmd/main_test.go index 95bb421a..301defcb 100644 --- a/cmd/main_test.go +++ b/cmd/main_test.go @@ -9,7 +9,6 @@ import ( "github.com/hunterlong/statup/source" "github.com/hunterlong/statup/types" "github.com/hunterlong/statup/utils" - "github.com/rendon/testcli" "github.com/stretchr/testify/assert" "net/http" "net/http/httptest" @@ -50,7 +49,6 @@ func TestRunAll(t *testing.T) { if os.Getenv("ONLY_DB") != "" { databases = []string{os.Getenv("ONLY_DB")} } - //databases := []string{"sqlite"} for _, dbt := range databases { @@ -174,39 +172,6 @@ func TestRunAll(t *testing.T) { } -func TestVersionCommand(t *testing.T) { - c := testcli.Command("statup", "version") - c.Run() - t.Log(c.Stdout()) - assert.True(t, c.StdoutContains("Statup v")) -} - -func TestHelpCommand(t *testing.T) { - c := testcli.Command("statup", "help") - c.Run() - t.Log(c.Stdout()) - assert.True(t, c.StdoutContains("statup help - Shows the user basic information about Statup")) -} - -func TestExportCommand(t *testing.T) { - t.SkipNow() - c := testcli.Command("statup", "export") - c.Run() - t.Log(c.Stdout()) - assert.True(t, c.StdoutContains("Exporting Static 'index.html' page")) - assert.True(t, fileExists(dir+"/cmd/index.html")) -} - -func TestAssetsCommand(t *testing.T) { - c := testcli.Command("statup", "assets") - c.Run() - t.Log(c.Stdout()) - t.Log("Directory for Assets: ", dir) - assert.FileExists(t, dir+"/assets/robots.txt") - assert.FileExists(t, dir+"/assets/js/main.js") - assert.FileExists(t, dir+"/assets/scss/base.scss") -} - func RunMakeDatabaseConfig(t *testing.T, db string) { port := 5432 if db == "mysql" { @@ -260,7 +225,6 @@ func RunSelectCoreMYQL(t *testing.T, db string) { var err error core.CoreApp, err = core.SelectCore() assert.Nil(t, err) - t.Log(core.CoreApp) assert.Equal(t, "Testing "+db, core.CoreApp.Name) assert.Equal(t, db, core.CoreApp.DbConnection) assert.NotEmpty(t, core.CoreApp.ApiKey) diff --git a/core/core_test.go b/core/core_test.go index 8233bbfa..e0df210f 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -71,3 +71,10 @@ func TestInsertNotifierDB(t *testing.T) { err := InsertNotifierDB() assert.Nil(t, err) } + +func TestExportStaticHTML(t *testing.T) { + data := ExportIndexHTML() + assert.Contains(t, data, "Statup made with ❤️") + assert.Contains(t, data, "") + assert.Contains(t, data, "") +} diff --git a/core/export.go b/core/export.go index 9124f387..21eafafb 100644 --- a/core/export.go +++ b/core/export.go @@ -9,6 +9,7 @@ import ( ) func ExportIndexHTML() string { + source.Assets() CoreApp.UseCdn = true //out := index{*CoreApp, CoreApp.Services} nav, _ := source.TmplBox.String("nav.html") @@ -28,6 +29,12 @@ func ExportIndexHTML() string { "VERSION": func() string { return VERSION }, + "CoreApp": func() *Core { + return CoreApp + }, + "USE_CDN": func() bool { + return CoreApp.UseCdn + }, "underscore": func(html string) string { return utils.UnderScoreString(html) }, diff --git a/core/services_test.go b/core/services_test.go index 258d58a4..0f4c2c40 100644 --- a/core/services_test.go +++ b/core/services_test.go @@ -66,6 +66,57 @@ func TestCheckTCPService(t *testing.T) { assert.NotZero(t, service.Latency) } +func TestServiceOnline24Hours(t *testing.T) { + service := SelectService(5) + amount := service.Online24() + assert.Equal(t, float32(100), amount) +} + +func TestServiceSmallText(t *testing.T) { + service := SelectService(5) + text := service.SmallText() + assert.Contains(t, text, "Online since") +} + +func TestServiceAvgUptime(t *testing.T) { + service := SelectService(5) + uptime := service.AvgUptime() + assert.Equal(t, "100", uptime) +} + +func TestServiceHits(t *testing.T) { + service := SelectService(5) + hits, err := service.Hits() + assert.Nil(t, err) + assert.Equal(t, int(1), len(hits)) +} + +func TestServiceLimitedHits(t *testing.T) { + service := SelectService(5) + hits, err := service.LimitedHits() + assert.Nil(t, err) + assert.Equal(t, int(1), len(hits)) +} + +func TestServiceTotalHits(t *testing.T) { + service := SelectService(5) + hits, err := service.TotalHits() + assert.Nil(t, err) + assert.Equal(t, uint64(0x1), hits) +} + +func TestServiceSum(t *testing.T) { + service := SelectService(5) + sum, err := service.Sum() + assert.Nil(t, err) + assert.NotZero(t, sum) +} + +func TestCountOnline(t *testing.T) { + amount := CountOnline() + assert.Equal(t, 2, amount) +} + func TestCreateService(t *testing.T) { s := &types.Service{ Name: "Interpol - All The Rage Back Home", diff --git a/core/users_test.go b/core/users_test.go index 2e214c9f..5ac25cfa 100644 --- a/core/users_test.go +++ b/core/users_test.go @@ -31,16 +31,68 @@ func TestSelectUser(t *testing.T) { assert.True(t, user.Admin) } +func TestSelectUsername(t *testing.T) { + user, err := SelectUsername("hunter") + assert.Nil(t, err) + assert.Equal(t, "test@email.com", user.Email) + assert.Equal(t, int64(1), user.Id) + assert.True(t, user.Admin) +} + func TestUpdateUser(t *testing.T) { user, err := SelectUser(1) assert.Nil(t, err) - user.Username = "updated" - err = UpdateUser(user) assert.Nil(t, err) - updatedUser, err := SelectUser(1) assert.Nil(t, err) assert.Equal(t, "updated", updatedUser.Username) } + +func TestCreateUser2(t *testing.T) { + user := &types.User{ + Username: "hunterlong", + Password: "password123", + Email: "user@email.com", + Admin: true, + } + userId, err := CreateUser(user) + assert.Nil(t, err) + assert.NotZero(t, userId) +} + +func TestSelectAllUsersAgain(t *testing.T) { + users, err := SelectAllUsers() + assert.Nil(t, err) + assert.Equal(t, 2, len(users)) +} + +func TestAuthUser(t *testing.T) { + user, auth := AuthUser("hunterlong", "password123") + assert.True(t, auth) + assert.NotNil(t, user) + assert.Equal(t, "user@email.com", user.Email) + assert.Equal(t, int64(2), user.Id) + assert.True(t, user.Admin) +} + +func TestFailedAuthUser(t *testing.T) { + user, auth := AuthUser("hunter", "wrongpassword") + assert.False(t, auth) + assert.Nil(t, user) +} + +func TestCheckPassword(t *testing.T) { + user, err := SelectUser(2) + assert.Nil(t, err) + pass := CheckHash("password123", user.Password) + assert.True(t, pass) +} + +func TestDeleteUser(t *testing.T) { + user, err := SelectUser(2) + assert.Nil(t, err) + err = DeleteUser(user) + assert.Nil(t, err) +} diff --git a/handlers/handlers.go b/handlers/handlers.go index 9ef1b3a6..98210279 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -87,6 +87,9 @@ func ExecuteResponse(w http.ResponseWriter, r *http.Request, file string, data i "VERSION": func() string { return core.VERSION }, + "CoreApp": func() *core.Core { + return core.CoreApp + }, "USE_CDN": func() bool { return core.CoreApp.UseCdn }, diff --git a/handlers/handlers_test.go b/handlers/handlers_test.go index 171fbaac..08af9b3a 100644 --- a/handlers/handlers_test.go +++ b/handlers/handlers_test.go @@ -123,8 +123,6 @@ func TestServiceChartHandler(t *testing.T) { assert.Equal(t, 200, rr.Code) assert.Contains(t, body, "var ctx_1") assert.Contains(t, body, "var ctx_2") - assert.Contains(t, body, "var ctx_3") - assert.Contains(t, body, "var ctx_4") } func TestDashboardHandler(t *testing.T) { @@ -339,7 +337,6 @@ func TestViewHTTPServicesHandler(t *testing.T) { } func TestViewTCPServicesHandler(t *testing.T) { - t.SkipNow() req, err := http.NewRequest("GET", "/service/7", nil) assert.Nil(t, err) rr := httptest.NewRecorder() @@ -357,6 +354,7 @@ func TestServicesDeleteFailuresHandler(t *testing.T) { rr := httptest.NewRecorder() Router().ServeHTTP(rr, req) assert.Equal(t, 200, rr.Code) + assert.True(t, IsRouteAuthenticated(req)) } func TestServicesUpdateHandler(t *testing.T) { @@ -379,6 +377,7 @@ func TestServicesUpdateHandler(t *testing.T) { assert.Equal(t, 200, rr.Code) assert.Contains(t, body, "Statup | The Bravery - An Honest Mistake Service") assert.Contains(t, body, "Statup made with ❤️") + assert.True(t, IsRouteAuthenticated(req)) } func TestDeleteServiceHandler(t *testing.T) { @@ -390,7 +389,6 @@ func TestDeleteServiceHandler(t *testing.T) { } func TestLogsHandler(t *testing.T) { - t.SkipNow() req, err := http.NewRequest("GET", "/logs", nil) assert.Nil(t, err) rr := httptest.NewRecorder() @@ -402,7 +400,6 @@ func TestLogsHandler(t *testing.T) { } func TestLogsLineHandler(t *testing.T) { - t.SkipNow() req, err := http.NewRequest("GET", "/logs/line", nil) assert.Nil(t, err) rr := httptest.NewRecorder() @@ -509,6 +506,25 @@ func TestViewNotificationSettingsHandler(t *testing.T) { assert.True(t, IsRouteAuthenticated(req)) } +func TestSaveFooterHandler(t *testing.T) { + form := url.Values{} + form.Add("footer", "Created by Hunter Long") + req, err := http.NewRequest("POST", "/settings", strings.NewReader(form.Encode())) + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + assert.Nil(t, err) + rr := httptest.NewRecorder() + Router().ServeHTTP(rr, req) + assert.Equal(t, 200, rr.Code) + + req, err = http.NewRequest("GET", "/", nil) + assert.Nil(t, err) + rr = httptest.NewRecorder() + Router().ServeHTTP(rr, req) + body := rr.Body.String() + assert.Equal(t, 200, rr.Code) + assert.Contains(t, body, "Created by Hunter Long") +} + func TestError404Handler(t *testing.T) { req, err := http.NewRequest("GET", "/404me", nil) assert.Nil(t, err) diff --git a/source/source.go b/source/source.go index 88bf5228..dca799b1 100644 --- a/source/source.go +++ b/source/source.go @@ -1,9 +1,11 @@ package source import ( + "errors" "fmt" "github.com/GeertJohan/go.rice" "github.com/hunterlong/statup/utils" + "io" "io/ioutil" "os" "os/exec" @@ -28,20 +30,53 @@ func Assets() { func CompileSASS(folder string) error { sassBin := os.Getenv("SASS") + if sassBin == "" { + return errors.New("missing the SASS executable environment variable") + } scssFile := fmt.Sprintf("%v/%v", folder, "assets/scss/base.scss") baseFile := fmt.Sprintf("%v/%v", folder, "assets/css/base.css") utils.Log(1, fmt.Sprintf("Compiling SASS %v into %v", scssFile, baseFile)) command := fmt.Sprintf("%v %v %v", sassBin, scssFile, baseFile) - testCmd := exec.Command("bash", "-c", command) - out, err := testCmd.Output() + + utils.Log(1, fmt.Sprintf("Command: sh -c %v", command)) + + testCmd := exec.Command("sh", "-c", command) + + var stdout, stderr []byte + var errStdout, errStderr error + stdoutIn, _ := testCmd.StdoutPipe() + stderrIn, _ := testCmd.StderrPipe() + testCmd.Start() + + go func() { + stdout, errStdout = copyAndCapture(os.Stdout, stdoutIn) + }() + + go func() { + stderr, errStderr = copyAndCapture(os.Stderr, stderrIn) + }() + + err := testCmd.Wait() if err != nil { - utils.Log(3, fmt.Sprintf("Failed to compile assets with SASS %v", err)) - utils.Log(3, fmt.Sprintf("%v %v %v", sassBin, scssFile, baseFile)) + utils.Log(3, err) return err } - utils.Log(1, string(out)) + + if errStdout != nil || errStderr != nil { + utils.Log(3, fmt.Sprintf("Failed to compile assets with SASS %v", err)) + return errors.New("failed to capture stdout or stderr") + } + + if err != nil { + utils.Log(3, fmt.Sprintf("Failed to compile assets with SASS %v", err)) + utils.Log(3, fmt.Sprintf("bash -c %v %v %v", sassBin, scssFile, baseFile)) + return err + } + + outStr, errStr := string(stdout), string(stderr) + utils.Log(1, fmt.Sprintf("out: %v | error: %v", outStr, errStr)) utils.Log(1, "SASS Compiling is complete!") return err } @@ -95,6 +130,7 @@ func CreateAllAssets(folder string) error { utils.Log(1, "Inserting scss, css, and javascript files into assets folder") CopyToPublic(ScssBox, folder+"/assets/scss", "base.scss") CopyToPublic(ScssBox, folder+"/assets/scss", "variables.scss") + CopyToPublic(ScssBox, folder+"/assets/scss", "mobile.scss") CopyToPublic(CssBox, folder+"/assets/css", "bootstrap.min.css") CopyToPublic(CssBox, folder+"/assets/css", "base.css") CopyToPublic(JsBox, folder+"/assets/js", "bootstrap.min.js") @@ -141,3 +177,29 @@ func MakePublicFolder(folder string) { } } } + +func copyAndCapture(w io.Writer, r io.Reader) ([]byte, error) { + var out []byte + buf := make([]byte, 1024, 1024) + for { + n, err := r.Read(buf[:]) + if n > 0 { + d := buf[:n] + out = append(out, d...) + _, err := w.Write(d) + if err != nil { + return out, err + } + } + if err != nil { + // Read returns io.EOF at the end of file, which is not an error for us + if err == io.EOF { + err = nil + } + return out, err + } + } + // never reached + panic(true) + return nil, nil +} diff --git a/source/source_test.go b/source/source_test.go index 9ede0e33..07c56d82 100644 --- a/source/source_test.go +++ b/source/source_test.go @@ -25,12 +25,14 @@ func TestCore_UsingAssets(t *testing.T) { func TestCreateAssets(t *testing.T) { assert.Nil(t, CreateAllAssets(dir)) assert.True(t, HasAssets(dir)) + assert.FileExists(t, "../assets/css/base.css") + assert.FileExists(t, "../assets/scss/base.scss") } func TestCompileSASS(t *testing.T) { - t.SkipNow() - //os.Setenv("SASS", "sass") - os.Setenv("CMD_FILE", dir+"/cmd.sh") + if os.Getenv("IS_DOCKER") == "true" { + os.Setenv("SASS", "/usr/local/bin/sass") + } assert.Nil(t, CompileSASS(dir)) assert.True(t, HasAssets(dir)) } diff --git a/source/tmpl/footer.html b/source/tmpl/footer.html index 00840732..2e4839da 100644 --- a/source/tmpl/footer.html +++ b/source/tmpl/footer.html @@ -1,8 +1,9 @@ {{ define "footer"}} {{ end }} \ No newline at end of file diff --git a/utils/utils.go b/utils/utils.go index 0e5695e1..c1f65a83 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -80,3 +80,12 @@ func DeleteFile(file string) bool { } return true } + +func DeleteDirectory(directory string) bool { + err := os.RemoveAll(directory) + if err != nil { + Log(3, err) + return false + } + return true +} diff --git a/utils/utils_test.go b/utils/utils_test.go index 62d500d6..43e5b7af 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -25,6 +25,10 @@ func TestLog(t *testing.T) { assert.Nil(t, Log(5, errors.New("this is a 5 level error"))) } +func TestLogFileCreation(t *testing.T) { + assert.FileExists(t, "../logs/statup.log") +} + func TestDeleteFile(t *testing.T) { assert.True(t, DeleteFile(Directory+"/logs/statup.log")) } @@ -67,3 +71,7 @@ func TestRandomString(t *testing.T) { func TestSha256(t *testing.T) { assert.Equal(t, "dc724af18fbdd4e59189f5fe768a5f8311527050", Sha256([]byte("testing"))) } + +func TestDeleteDirectory(t *testing.T) { + assert.True(t, DeleteDirectory(Directory+"/logs")) +}