diff --git a/README.md b/README.md
index e951d43..62e4bb8 100644
--- a/README.md
+++ b/README.md
@@ -193,6 +193,7 @@ The `endpoint` is the **Cenophane** server running somewhere and the
- upd: https://docs.gofiber.io/guide/error-handling/ to always use json output
- upctl: get rid of HandleResponse(), used only once anyway
- add form so that public users can upload
+- use Writer for output.go so we can unit test the stuff in there
diff --git a/upctl/Makefile b/upctl/Makefile
index 8c45681..dbadb30 100644
--- a/upctl/Makefile
+++ b/upctl/Makefile
@@ -33,7 +33,7 @@ all: buildlocal
buildlocal:
- go build -ldflags "-X 'github.com/tlinden/up/upctl/cfg.VERSION=$(VERSION)'"
+ go build -ldflags "-X 'github.com/tlinden/cenophane/upctl/cfg.VERSION=$(VERSION)'"
release:
./mkrel.sh $(tool) $(version)
@@ -48,7 +48,6 @@ clean:
test:
go test -v ./...
- bash t/test.sh
singletest:
@echo "Call like this: ''make singletest TEST=TestX1 MOD=lib"
diff --git a/upctl/cfg/config.go b/upctl/cfg/config.go
index 3115293..85cf230 100644
--- a/upctl/cfg/config.go
+++ b/upctl/cfg/config.go
@@ -30,13 +30,19 @@ type Config struct {
Endpoint string
Debug bool
Retries int
- Apikey string
+ Silent bool
+
+ // used for authentication
+ Apikey string
// upload
Expire string
- // list
+ // used for filtering (list command)
Apicontext string
+
+ // required to intercept requests using httpmock in tests
+ Mock bool
}
func Getversion() string {
diff --git a/upctl/cmd/delete.go b/upctl/cmd/delete.go
index 53e067c..74d079d 100644
--- a/upctl/cmd/delete.go
+++ b/upctl/cmd/delete.go
@@ -19,8 +19,8 @@ package cmd
import (
"errors"
"github.com/spf13/cobra"
- "github.com/tlinden/up/upctl/cfg"
- "github.com/tlinden/up/upctl/lib"
+ "github.com/tlinden/cenophane/upctl/cfg"
+ "github.com/tlinden/cenophane/upctl/lib"
)
func DeleteCommand(conf *cfg.Config) *cobra.Command {
diff --git a/upctl/cmd/describe.go b/upctl/cmd/describe.go
index 70858da..f38a1a7 100644
--- a/upctl/cmd/describe.go
+++ b/upctl/cmd/describe.go
@@ -19,8 +19,8 @@ package cmd
import (
"errors"
"github.com/spf13/cobra"
- "github.com/tlinden/up/upctl/cfg"
- "github.com/tlinden/up/upctl/lib"
+ "github.com/tlinden/cenophane/upctl/cfg"
+ "github.com/tlinden/cenophane/upctl/lib"
)
func DescribeCommand(conf *cfg.Config) *cobra.Command {
diff --git a/upctl/cmd/download.go b/upctl/cmd/download.go
index f322011..ed12624 100644
--- a/upctl/cmd/download.go
+++ b/upctl/cmd/download.go
@@ -19,8 +19,8 @@ package cmd
import (
"errors"
"github.com/spf13/cobra"
- "github.com/tlinden/up/upctl/cfg"
- "github.com/tlinden/up/upctl/lib"
+ "github.com/tlinden/cenophane/upctl/cfg"
+ "github.com/tlinden/cenophane/upctl/lib"
)
func DownloadCommand(conf *cfg.Config) *cobra.Command {
diff --git a/upctl/cmd/list.go b/upctl/cmd/list.go
index d141196..4d9ac65 100644
--- a/upctl/cmd/list.go
+++ b/upctl/cmd/list.go
@@ -18,8 +18,8 @@ package cmd
import (
"github.com/spf13/cobra"
- "github.com/tlinden/up/upctl/cfg"
- "github.com/tlinden/up/upctl/lib"
+ "github.com/tlinden/cenophane/upctl/cfg"
+ "github.com/tlinden/cenophane/upctl/lib"
)
func ListCommand(conf *cfg.Config) *cobra.Command {
diff --git a/upctl/cmd/root.go b/upctl/cmd/root.go
index 1fcf178..d1f953d 100644
--- a/upctl/cmd/root.go
+++ b/upctl/cmd/root.go
@@ -22,7 +22,7 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
- "github.com/tlinden/up/upctl/cfg"
+ "github.com/tlinden/cenophane/upctl/cfg"
"os"
"strings"
)
@@ -81,6 +81,7 @@ func Execute() {
// options
rootCmd.PersistentFlags().BoolVarP(&ShowVersion, "version", "v", false, "Print program version")
rootCmd.PersistentFlags().BoolVarP(&conf.Debug, "debug", "d", false, "Enable debugging")
+ rootCmd.PersistentFlags().BoolVarP(&conf.Silent, "silent", "s", false, "Disable progress bar and other noise")
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "custom config file")
rootCmd.PersistentFlags().IntVarP(&conf.Retries, "retries", "r", 3, "How often shall we retry to access our endpoint")
rootCmd.PersistentFlags().StringVarP(&conf.Endpoint, "endpoint", "p", "http://localhost:8080/api/v1", "upload api endpoint url")
diff --git a/upctl/cmd/upload.go b/upctl/cmd/upload.go
index 79cb168..a271692 100644
--- a/upctl/cmd/upload.go
+++ b/upctl/cmd/upload.go
@@ -19,8 +19,8 @@ package cmd
import (
"errors"
"github.com/spf13/cobra"
- "github.com/tlinden/up/upctl/cfg"
- "github.com/tlinden/up/upctl/lib"
+ "github.com/tlinden/cenophane/upctl/cfg"
+ "github.com/tlinden/cenophane/upctl/lib"
)
func UploadCommand(conf *cfg.Config) *cobra.Command {
diff --git a/upctl/go.mod b/upctl/go.mod
index 154e9f3..6b4ff8d 100644
--- a/upctl/go.mod
+++ b/upctl/go.mod
@@ -1,9 +1,10 @@
-module github.com/tlinden/up/upctl
+module github.com/tlinden/cenophane/upctl
go 1.18
require (
github.com/imroc/req/v3 v3.32.0
+ github.com/jarcoal/httpmock v1.3.0
github.com/olekukonko/tablewriter v0.0.5
github.com/schollz/progressbar/v3 v3.13.1
github.com/spf13/cobra v1.6.1
diff --git a/upctl/go.sum b/upctl/go.sum
index d07f735..d75a6e1 100644
--- a/upctl/go.sum
+++ b/upctl/go.sum
@@ -139,6 +139,8 @@ github.com/imroc/req/v3 v3.32.0 h1:jDGm2pVE8e/PExrJTvxEjOmgItVBJqvt3YjTUtZKyQM=
github.com/imroc/req/v3 v3.32.0/go.mod h1:cZ+7C3L/AYOr4tLGG16hZF90F1WzAdAdzt1xFSlizXY=
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc=
+github.com/jarcoal/httpmock v1.3.0/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
@@ -155,6 +157,7 @@ github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
diff --git a/upctl/lib/client.go b/upctl/lib/client.go
index 004addc..b8befac 100644
--- a/upctl/lib/client.go
+++ b/upctl/lib/client.go
@@ -23,9 +23,10 @@ import (
"fmt"
//"github.com/alecthomas/repr"
"github.com/imroc/req/v3"
+ "github.com/jarcoal/httpmock"
"github.com/schollz/progressbar/v3"
"github.com/tlinden/cenophane/common"
- "github.com/tlinden/up/upctl/cfg"
+ "github.com/tlinden/cenophane/upctl/cfg"
"mime"
"os"
"path/filepath"
@@ -79,6 +80,11 @@ func Setup(c *cfg.Config, path string) *Request {
client.SetCommonBearerAuthToken(c.Apikey)
}
+ if c.Mock {
+ // intercept, used by unit tests
+ httpmock.ActivateNonDefault(client.GetClient())
+ }
+
return &Request{Url: c.Endpoint + path, R: R}
}
@@ -123,19 +129,21 @@ func UploadFiles(c *cfg.Config, args []string) error {
return err
}
- // progres bar
- bar := progressbar.Default(100)
- var left float64
+ if !c.Silent {
+ // progres bar
+ bar := progressbar.Default(100)
+ var left float64
+ rq.R.SetUploadCallbackWithInterval(func(info req.UploadInfo) {
+ left = float64(info.UploadedSize) / float64(info.FileSize) * 100.0
+ bar.Add(int(left))
+ }, 10*time.Millisecond)
+ }
// actual post w/ settings
resp, err := rq.R.
SetFormData(map[string]string{
"expire": c.Expire,
}).
- SetUploadCallbackWithInterval(func(info req.UploadInfo) {
- left = float64(info.UploadedSize) / float64(info.FileSize) * 100.0
- bar.Add(int(left))
- }, 10*time.Millisecond).
Post(rq.Url)
if err != nil {
diff --git a/upctl/lib/client_test.go b/upctl/lib/client_test.go
new file mode 100644
index 0000000..578f38e
--- /dev/null
+++ b/upctl/lib/client_test.go
@@ -0,0 +1,137 @@
+/*
+Copyright © 2023 Thomas von Dein
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+package lib
+
+import (
+ //"github.com/alecthomas/repr"
+ "fmt"
+ "github.com/jarcoal/httpmock"
+ "github.com/tlinden/cenophane/upctl/cfg"
+ "net/http"
+ "testing"
+)
+
+const endpoint string = "http://localhost:8080/api/v1"
+
+type Unit struct {
+ name string
+ apikey string // set to something else than "token" to fail auth
+ wantfail bool // true: expect to fail
+ files []string // path relative to ./t/
+ sendcode int // for httpmock
+ sendjson string // struct to respond with
+ route string // dito
+ method string // method to use
+}
+
+// simulate our cenophane server
+func Intercept(tt Unit) {
+ httpmock.RegisterResponder(tt.method, endpoint+tt.route,
+ func(request *http.Request) (*http.Response, error) {
+ respbody := fmt.Sprintf(tt.sendjson)
+ resp := httpmock.NewStringResponse(tt.sendcode, respbody)
+ resp.Header.Set("Content-Type", "application/json; charset=utf-8")
+ return resp, nil
+ })
+}
+
+func TestUploadFiles(t *testing.T) {
+ conf := &cfg.Config{
+ Mock: true,
+ Apikey: "token",
+ Endpoint: endpoint,
+ Silent: true,
+ }
+
+ tests := []Unit{
+ {
+ name: "upload-file",
+ apikey: "token",
+ wantfail: false,
+ route: "/file/",
+ sendcode: 200,
+ sendjson: `{"success": true}`,
+ files: []string{"../t/t1"}, // pwd is lib/ !
+ method: "POST",
+ },
+ {
+ name: "upload-nonexistent-file",
+ apikey: "token",
+ wantfail: true,
+ route: "/file/",
+ sendcode: 200,
+ sendjson: `{"success": false}`,
+ files: []string{"../t/none"},
+ method: "POST",
+ },
+ {
+ name: "upload-unauth",
+ apikey: "token",
+ wantfail: true,
+ route: "/file/",
+ sendcode: 403,
+ sendjson: `{"success": false}`,
+ files: []string{"../t/t1"},
+ method: "POST",
+ },
+ }
+
+ for _, tt := range tests {
+ testname := fmt.Sprintf("UploadFiles-%s-%t", tt.name, tt.wantfail)
+ Intercept(tt)
+ err := UploadFiles(conf, tt.files)
+
+ if err != nil && !tt.wantfail {
+ t.Errorf("%s failed! wantfail: %t, error: %s", testname, tt.wantfail, err.Error())
+ }
+ }
+}
+
+func TestList(t *testing.T) {
+ conf := &cfg.Config{
+ Mock: true,
+ Apikey: "token",
+ Endpoint: endpoint,
+ Silent: true,
+ }
+
+ listing := `{"uploads":[{"id":"c8dh","expire":"asap","file":"t1","members":["t1"],"uploaded":1679318969.6434112,"context":"foo","url":""}],"success":true,"message":"","code":200}`
+ tests := []Unit{
+ {
+ name: "list",
+ apikey: "token",
+ wantfail: false,
+ route: "/list/",
+ sendcode: 200,
+ sendjson: listing,
+ files: []string{},
+ method: "GET",
+ },
+ }
+
+ for _, tt := range tests {
+ testname := fmt.Sprintf("List-%s-%t", tt.name, tt.wantfail)
+ Intercept(tt)
+ err := List(conf, []string{})
+
+ if err != nil && !tt.wantfail {
+ t.Errorf("%s failed! wantfail: %t, error: %s", testname, tt.wantfail, err.Error())
+ }
+ }
+
+}
diff --git a/upctl/main.go b/upctl/main.go
index 1552c1b..c11a498 100644
--- a/upctl/main.go
+++ b/upctl/main.go
@@ -18,7 +18,7 @@ along with this program. If not, see .
package main
import (
- "github.com/tlinden/up/upctl/cmd"
+ "github.com/tlinden/cenophane/upctl/cmd"
)
func main() {
diff --git a/upctl/t/t1 b/upctl/t/t1
new file mode 100644
index 0000000..7c0bf85
--- /dev/null
+++ b/upctl/t/t1
@@ -0,0 +1 @@
+Mon Mar 20 12:16:26 PM CET 2023