mirror of
https://github.com/Forceu/Gokapi.git
synced 2026-03-13 13:39:02 -05:00
Added unit test
This commit is contained in:
14
.github/workflows/test-code.yml
vendored
14
.github/workflows/test-code.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Test Compilation
|
||||
name: Compile and run unit tests
|
||||
on: [push, pull_request]
|
||||
|
||||
|
||||
@@ -9,11 +9,7 @@ jobs:
|
||||
steps:
|
||||
- name: checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: install buildx
|
||||
id: buildx
|
||||
uses: crazy-max/ghaction-docker-buildx@v1
|
||||
with:
|
||||
version: latest
|
||||
- name: build the image
|
||||
run: |
|
||||
docker buildx build --tag f0rc3/gokapi:test --platform linux/386,linux/amd64,linux/arm/v6,linux/arm/v7 .
|
||||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.16.0'
|
||||
- run: go test
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,3 +2,4 @@ config/
|
||||
data/
|
||||
.idea/
|
||||
Gokapi
|
||||
test/
|
||||
|
||||
10
Main.go
10
Main.go
@@ -31,7 +31,7 @@ func main() {
|
||||
configuration.Load()
|
||||
checkArguments()
|
||||
go storage.CleanUp(true)
|
||||
webserver.Start(&staticFolderEmbedded, &templateFolderEmbedded)
|
||||
webserver.Start(&StaticFolderEmbedded, &TemplateFolderEmbedded, true)
|
||||
}
|
||||
|
||||
// Checks for command line arguments that have to be parsed before loading the configuration
|
||||
@@ -59,15 +59,15 @@ func checkArguments() {
|
||||
}
|
||||
}
|
||||
|
||||
// Embedded version of the "static" folder
|
||||
// StaticFolderEmbedded is the embedded version of the "static" folder
|
||||
// This contains JS files, CSS, images etc
|
||||
//go:embed web/static
|
||||
var staticFolderEmbedded embed.FS
|
||||
var StaticFolderEmbedded embed.FS
|
||||
|
||||
// Embedded version of the "templates" folder
|
||||
// TemplateFolderEmbedded is the embedded version of the "templates" folder
|
||||
// This contains templates that Gokapi uses for creating the HTML output
|
||||
//go:embed web/templates
|
||||
var templateFolderEmbedded embed.FS
|
||||
var TemplateFolderEmbedded embed.FS
|
||||
|
||||
// ASCII art logo
|
||||
const logo = `
|
||||
|
||||
133
Main_test.go
Normal file
133
Main_test.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package main
|
||||
|
||||
/**
|
||||
Unit testing for whole project. At the moment coverage is low.
|
||||
*/
|
||||
|
||||
import (
|
||||
"Gokapi/internal/configuration"
|
||||
"Gokapi/internal/environment"
|
||||
"Gokapi/internal/webserver"
|
||||
"bytes"
|
||||
"html/template"
|
||||
"io/fs"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func loadConfig() {
|
||||
os.Setenv("GOKAPI_CONFIG_DIR", "test")
|
||||
os.Mkdir("test", 0777)
|
||||
os.WriteFile("test/config.json", configTestFile, 0777)
|
||||
configuration.Load()
|
||||
}
|
||||
|
||||
func isEqualString(t *testing.T, got, want string) {
|
||||
if got != want {
|
||||
t.Errorf("Assertion failed, got: %s, want: %s.", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func isEqualBool(t *testing.T, got, want bool) {
|
||||
if got != want {
|
||||
t.Errorf("Assertion failed, got: %t, want: %t.", got, want)
|
||||
}
|
||||
}
|
||||
func isEqualInt(t *testing.T, got, want int) {
|
||||
if got != want {
|
||||
t.Errorf("Assertion failed, got: %d, want: %d.", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigLoad(t *testing.T) {
|
||||
loadConfig()
|
||||
isEqualString(t, configuration.Environment.ConfigDir, "test")
|
||||
isEqualString(t, configuration.ServerSettings.Port, "127.0.0.1:53843")
|
||||
isEqualString(t, configuration.ServerSettings.AdminName, "test")
|
||||
isEqualString(t, configuration.ServerSettings.AdminPassword, "10340aece68aa4fb14507ae45b05506026f276cf")
|
||||
isEqualString(t, configuration.ServerSettings.ServerUrl, "http://127.0.0.1:53843/")
|
||||
isEqualString(t, configuration.ServerSettings.AdminPassword, "10340aece68aa4fb14507ae45b05506026f276cf")
|
||||
isEqualString(t, configuration.HashPassword("testtest", false), "10340aece68aa4fb14507ae45b05506026f276cf")
|
||||
}
|
||||
|
||||
func testHttpPage(t *testing.T, testUrl, requiredContent string, isHtml bool, authCookie string) {
|
||||
client := &http.Client{}
|
||||
|
||||
req, err := http.NewRequest("GET", testUrl, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if authCookie != "" {
|
||||
req.Header.Set("Cookie", "session_token="+authCookie)
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
t.Errorf("Status %d != 200", resp.StatusCode)
|
||||
}
|
||||
bs, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if isHtml && !bytes.Contains(bs, []byte("</html>")) {
|
||||
t.Error(testUrl + ": Incorrect response")
|
||||
}
|
||||
if !bytes.Contains(bs, []byte(requiredContent)) {
|
||||
t.Error(testUrl + ": Incorrect response. Got:\n" + string(bs))
|
||||
}
|
||||
resp.Body.Close()
|
||||
}
|
||||
|
||||
func TestWebserver(t *testing.T) {
|
||||
loadConfig()
|
||||
go webserver.Start(&StaticFolderEmbedded, &TemplateFolderEmbedded, false)
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
// Index redirect
|
||||
testHttpPage(t, "http://localhost:53843/", "<html><head><meta http-equiv=\"Refresh\" content=\"0; URL=./index\"></head></html>", true, "")
|
||||
// CSS file
|
||||
testHttpPage(t, "http://localhost:53843/css/cover.css", ".btn-secondary:hover", false, "")
|
||||
// Login page
|
||||
testHttpPage(t, "http://localhost:53843/login", "id=\"uname_hidden\"", true, "")
|
||||
// Admin without auth
|
||||
testHttpPage(t, "http://localhost:53843/admin", "URL=./login\"", true, "")
|
||||
// Admin with auth
|
||||
testHttpPage(t, "http://localhost:53843/admin", "Downloads remaining", true, "GubBwU9KVuuRmOTjUvlKSIl9MyBLumuql9NAHFps8hc0UdumD8lD7mdPRuK01ouU9rZ5a4JiWUeB5aJ")
|
||||
// Admin with invalid auth
|
||||
testHttpPage(t, "http://localhost:53843/admin", "URL=./login\"", true, "invalid")
|
||||
}
|
||||
|
||||
func TestEmbedFs(t *testing.T) {
|
||||
templates, err := template.ParseFS(TemplateFolderEmbedded, "web/templates/*.tmpl")
|
||||
if err != nil {
|
||||
t.Error("Unable to read templates")
|
||||
}
|
||||
if !strings.Contains(templates.DefinedTemplates(), "app_name") {
|
||||
t.Error("Unable to parse templates")
|
||||
}
|
||||
_, err = fs.Stat(StaticFolderEmbedded, "web/static/expired.png")
|
||||
if err != nil {
|
||||
t.Error("Static webdir incomplete")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvLoad(t *testing.T) {
|
||||
os.Setenv("GOKAPI_CONFIG_DIR", "test")
|
||||
os.Setenv("GOKAPI_CONFIG_FILE", "test2")
|
||||
os.Setenv("GOKAPI_LOCALHOST", "yes")
|
||||
os.Setenv("GOKAPI_LENGTH_ID", "7")
|
||||
env := environment.New()
|
||||
isEqualString(t, env.ConfigPath, "test/test2")
|
||||
isEqualString(t, env.WebserverLocalhost, environment.IsTrue)
|
||||
isEqualInt(t, env.LengthId, 7)
|
||||
os.Setenv("GOKAPI_LENGTH_ID", "3")
|
||||
env = environment.New()
|
||||
isEqualInt(t, env.LengthId, 5)
|
||||
|
||||
}
|
||||
|
||||
var configTestFile = []byte(`{"Port":"127.0.0.1:53843","AdminName":"test","AdminPassword":"10340aece68aa4fb14507ae45b05506026f276cf","ServerUrl":"http://127.0.0.1:53843/","DefaultDownloads":3,"DefaultExpiry":20,"DefaultPassword":"123","RedirectUrl":"https://test.com/","Sessions":{"GubBwU9KVuuRmOTjUvlKSIl9MyBLumuql9NAHFps8hc0UdumD8lD7mdPRuK01ouU9rZ5a4JiWUeB5aJ":{"RenewAt":2147483646,"ValidUntil":2147483646}},"Files":{},"Hotlinks":{},"ConfigVersion":4,"SaltAdmin":"LW6fW4Pjv8GtdWVLSZD66gYEev6NAaXxOVBw7C","SaltFiles":"lL5wMTtnVCn5TPbpRaSe4vAQodWW0hgk00WCZE","LengthId":0,"DataDir":"test/data"}`)
|
||||
21
go.sum
21
go.sum
@@ -1,15 +1,15 @@
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -17,6 +17,7 @@ golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXR
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7 h1:EBZoQjiKKPaLbPrbpssUfuHtwM6KV/vb4U85g/cigFY=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -32,7 +32,7 @@ var imageExpiredPicture []byte
|
||||
const expiredFile = "static/expired.png"
|
||||
|
||||
// Start the webserver on the port set in the config
|
||||
func Start(staticFolderEmbedded, templateFolderEmbedded *embed.FS) {
|
||||
func Start(staticFolderEmbedded, templateFolderEmbedded *embed.FS, verbose bool) {
|
||||
initTemplates(*templateFolderEmbedded)
|
||||
webserverDir, _ := fs.Sub(*staticFolderEmbedded, "web/static")
|
||||
var err error
|
||||
@@ -57,8 +57,10 @@ func Start(staticFolderEmbedded, templateFolderEmbedded *embed.FS) {
|
||||
http.HandleFunc("/delete", deleteFile)
|
||||
http.HandleFunc("/downloadFile", downloadFile)
|
||||
http.HandleFunc("/forgotpw", forgotPassword)
|
||||
fmt.Println("Binding webserver to " + configuration.ServerSettings.Port)
|
||||
fmt.Println("Webserver can be accessed at " + configuration.ServerSettings.ServerUrl + "admin")
|
||||
if verbose {
|
||||
fmt.Println("Binding webserver to " + configuration.ServerSettings.Port)
|
||||
fmt.Println("Webserver can be accessed at " + configuration.ServerSettings.ServerUrl + "admin")
|
||||
}
|
||||
srv := &http.Server{
|
||||
Addr: configuration.ServerSettings.Port,
|
||||
ReadTimeout: timeOutWebserver,
|
||||
@@ -84,7 +86,7 @@ func initTemplates(templateFolderEmbedded embed.FS) {
|
||||
|
||||
// Sends a redirect HTTP output to the client. Variable url is used to redirect to ./url
|
||||
func redirect(w http.ResponseWriter, url string) {
|
||||
_, _ = fmt.Fprint(w, "<head><meta http-equiv=\"Refresh\" content=\"0; URL=./"+url+"\"></head>")
|
||||
_, _ = fmt.Fprint(w, "<html><head><meta http-equiv=\"Refresh\" content=\"0; URL=./"+url+"\"></head></html>")
|
||||
}
|
||||
|
||||
// Handling of /logout
|
||||
|
||||
@@ -1 +1 @@
|
||||
<head><meta http-equiv="Refresh" content="0; URL=./index"></head>
|
||||
<html><head><meta http-equiv="Refresh" content="0; URL=./index"></head></html>
|
||||
|
||||
Reference in New Issue
Block a user