mirror of
https://codeberg.org/scip/ephemerup.git
synced 2025-12-17 04:30:57 +01:00
fix mod name, added tests
This commit is contained in:
@@ -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
|
- upd: https://docs.gofiber.io/guide/error-handling/ to always use json output
|
||||||
- upctl: get rid of HandleResponse(), used only once anyway
|
- upctl: get rid of HandleResponse(), used only once anyway
|
||||||
- add form so that public users can upload
|
- add form so that public users can upload
|
||||||
|
- use Writer for output.go so we can unit test the stuff in there
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ all: buildlocal
|
|||||||
|
|
||||||
|
|
||||||
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:
|
release:
|
||||||
./mkrel.sh $(tool) $(version)
|
./mkrel.sh $(tool) $(version)
|
||||||
@@ -48,7 +48,6 @@ clean:
|
|||||||
|
|
||||||
test:
|
test:
|
||||||
go test -v ./...
|
go test -v ./...
|
||||||
bash t/test.sh
|
|
||||||
|
|
||||||
singletest:
|
singletest:
|
||||||
@echo "Call like this: ''make singletest TEST=TestX1 MOD=lib"
|
@echo "Call like this: ''make singletest TEST=TestX1 MOD=lib"
|
||||||
|
|||||||
@@ -30,13 +30,19 @@ type Config struct {
|
|||||||
Endpoint string
|
Endpoint string
|
||||||
Debug bool
|
Debug bool
|
||||||
Retries int
|
Retries int
|
||||||
Apikey string
|
Silent bool
|
||||||
|
|
||||||
|
// used for authentication
|
||||||
|
Apikey string
|
||||||
|
|
||||||
// upload
|
// upload
|
||||||
Expire string
|
Expire string
|
||||||
|
|
||||||
// list
|
// used for filtering (list command)
|
||||||
Apicontext string
|
Apicontext string
|
||||||
|
|
||||||
|
// required to intercept requests using httpmock in tests
|
||||||
|
Mock bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func Getversion() string {
|
func Getversion() string {
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/tlinden/up/upctl/cfg"
|
"github.com/tlinden/cenophane/upctl/cfg"
|
||||||
"github.com/tlinden/up/upctl/lib"
|
"github.com/tlinden/cenophane/upctl/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func DeleteCommand(conf *cfg.Config) *cobra.Command {
|
func DeleteCommand(conf *cfg.Config) *cobra.Command {
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/tlinden/up/upctl/cfg"
|
"github.com/tlinden/cenophane/upctl/cfg"
|
||||||
"github.com/tlinden/up/upctl/lib"
|
"github.com/tlinden/cenophane/upctl/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func DescribeCommand(conf *cfg.Config) *cobra.Command {
|
func DescribeCommand(conf *cfg.Config) *cobra.Command {
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/tlinden/up/upctl/cfg"
|
"github.com/tlinden/cenophane/upctl/cfg"
|
||||||
"github.com/tlinden/up/upctl/lib"
|
"github.com/tlinden/cenophane/upctl/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func DownloadCommand(conf *cfg.Config) *cobra.Command {
|
func DownloadCommand(conf *cfg.Config) *cobra.Command {
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/tlinden/up/upctl/cfg"
|
"github.com/tlinden/cenophane/upctl/cfg"
|
||||||
"github.com/tlinden/up/upctl/lib"
|
"github.com/tlinden/cenophane/upctl/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ListCommand(conf *cfg.Config) *cobra.Command {
|
func ListCommand(conf *cfg.Config) *cobra.Command {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"github.com/tlinden/up/upctl/cfg"
|
"github.com/tlinden/cenophane/upctl/cfg"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -81,6 +81,7 @@ func Execute() {
|
|||||||
// options
|
// options
|
||||||
rootCmd.PersistentFlags().BoolVarP(&ShowVersion, "version", "v", false, "Print program version")
|
rootCmd.PersistentFlags().BoolVarP(&ShowVersion, "version", "v", false, "Print program version")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&conf.Debug, "debug", "d", false, "Enable debugging")
|
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().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().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")
|
rootCmd.PersistentFlags().StringVarP(&conf.Endpoint, "endpoint", "p", "http://localhost:8080/api/v1", "upload api endpoint url")
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/tlinden/up/upctl/cfg"
|
"github.com/tlinden/cenophane/upctl/cfg"
|
||||||
"github.com/tlinden/up/upctl/lib"
|
"github.com/tlinden/cenophane/upctl/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func UploadCommand(conf *cfg.Config) *cobra.Command {
|
func UploadCommand(conf *cfg.Config) *cobra.Command {
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
module github.com/tlinden/up/upctl
|
module github.com/tlinden/cenophane/upctl
|
||||||
|
|
||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/imroc/req/v3 v3.32.0
|
github.com/imroc/req/v3 v3.32.0
|
||||||
|
github.com/jarcoal/httpmock v1.3.0
|
||||||
github.com/olekukonko/tablewriter v0.0.5
|
github.com/olekukonko/tablewriter v0.0.5
|
||||||
github.com/schollz/progressbar/v3 v3.13.1
|
github.com/schollz/progressbar/v3 v3.13.1
|
||||||
github.com/spf13/cobra v1.6.1
|
github.com/spf13/cobra v1.6.1
|
||||||
|
|||||||
@@ -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/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 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
||||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
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.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/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=
|
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.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 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||||
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
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 h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
|
||||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
|
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
|||||||
@@ -23,9 +23,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
//"github.com/alecthomas/repr"
|
//"github.com/alecthomas/repr"
|
||||||
"github.com/imroc/req/v3"
|
"github.com/imroc/req/v3"
|
||||||
|
"github.com/jarcoal/httpmock"
|
||||||
"github.com/schollz/progressbar/v3"
|
"github.com/schollz/progressbar/v3"
|
||||||
"github.com/tlinden/cenophane/common"
|
"github.com/tlinden/cenophane/common"
|
||||||
"github.com/tlinden/up/upctl/cfg"
|
"github.com/tlinden/cenophane/upctl/cfg"
|
||||||
"mime"
|
"mime"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -79,6 +80,11 @@ func Setup(c *cfg.Config, path string) *Request {
|
|||||||
client.SetCommonBearerAuthToken(c.Apikey)
|
client.SetCommonBearerAuthToken(c.Apikey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.Mock {
|
||||||
|
// intercept, used by unit tests
|
||||||
|
httpmock.ActivateNonDefault(client.GetClient())
|
||||||
|
}
|
||||||
|
|
||||||
return &Request{Url: c.Endpoint + path, R: R}
|
return &Request{Url: c.Endpoint + path, R: R}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -123,19 +129,21 @@ func UploadFiles(c *cfg.Config, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// progres bar
|
if !c.Silent {
|
||||||
bar := progressbar.Default(100)
|
// progres bar
|
||||||
var left float64
|
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
|
// actual post w/ settings
|
||||||
resp, err := rq.R.
|
resp, err := rq.R.
|
||||||
SetFormData(map[string]string{
|
SetFormData(map[string]string{
|
||||||
"expire": c.Expire,
|
"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)
|
Post(rq.Url)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
137
upctl/lib/client_test.go
Normal file
137
upctl/lib/client_test.go
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/tlinden/up/upctl/cmd"
|
"github.com/tlinden/cenophane/upctl/cmd"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|||||||
1
upctl/t/t1
Normal file
1
upctl/t/t1
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Mon Mar 20 12:16:26 PM CET 2023
|
||||||
Reference in New Issue
Block a user