1 package webserver_test
2
3 import (
4 "context"
5 "encoding/json"
6 "fmt"
7 "io"
8 "net/http"
9 "net/http/httptest"
10 "os"
11 "strings"
12 "testing"
13
14 "github.com/cybertec-postgresql/pgwatch/v3/internal/webserver"
15 "github.com/stretchr/testify/assert"
16 )
17
18 type Credentials struct {
19 User string `json:"user"`
20 Password string `json:"password"`
21 }
22
23 type ReadyBool bool
24
25 func (ready *ReadyBool) Ready() bool {
26 return bool(*ready)
27 }
28
29 func TestWebDisableOpt(t *testing.T) {
30 var ready ReadyBool
31 restsrv, err := webserver.Init(context.Background(), webserver.CmdOpts{WebDisable: "all"}, os.DirFS("../webui/build"), nil, nil, &ready)
32 assert.Nil(t, restsrv, "no webserver should be started")
33 assert.NoError(t, err)
34
35 restsrv, err = webserver.Init(context.Background(), webserver.CmdOpts{WebAddr: "127.0.0.1:8079", WebDisable: "ui"}, os.DirFS("../webui/build"), nil, nil, &ready)
36 assert.NotNil(t, restsrv)
37 assert.NoError(t, err)
38 r, err := http.Get("http://localhost:8079/")
39 assert.NoError(t, err)
40 assert.Equal(t, http.StatusNotFound, r.StatusCode, "no webui should be served")
41 r, err = http.Get("http://localhost:8079/liveness")
42 assert.NoError(t, err)
43 assert.Equal(t, http.StatusOK, r.StatusCode, "rest api should be served though")
44
45 restsrv, err = webserver.Init(context.Background(), webserver.CmdOpts{WebAddr: "127.0.0.1:8079"}, os.DirFS("../webui/build"), nil, nil, &ready)
46 assert.Nil(t, restsrv)
47 assert.Error(t, err, "port should be in use")
48 }
49
50 func TestHealth(t *testing.T) {
51 var ready ReadyBool
52 ctx, cancel := context.WithCancel(context.Background())
53 restsrv, _ := webserver.Init(ctx, webserver.CmdOpts{WebAddr: "127.0.0.1:8080"}, os.DirFS("../webui/build"), nil, nil, &ready)
54 assert.NotNil(t, restsrv)
55
56 r, err := http.Get("http://localhost:8080/liveness")
57 assert.NoError(t, err)
58 assert.Equal(t, http.StatusOK, r.StatusCode)
59
60 cancel()
61 r, err = http.Get("http://localhost:8080/liveness")
62 assert.NoError(t, err)
63 assert.Equal(t, http.StatusServiceUnavailable, r.StatusCode)
64
65 r, err = http.Get("http://localhost:8080/readiness")
66 assert.NoError(t, err)
67 assert.Equal(t, http.StatusServiceUnavailable, r.StatusCode)
68
69 ready = true
70 r, err = http.Get("http://localhost:8080/readiness")
71 assert.NoError(t, err)
72 assert.Equal(t, http.StatusOK, r.StatusCode)
73 }
74
75 func TestServerNoAuth(t *testing.T) {
76 host := "http://localhost:8081"
77 restsrv, _ := webserver.Init(context.Background(), webserver.CmdOpts{WebAddr: "localhost:8081"}, os.DirFS("../webui/build"), nil, nil, nil)
78 assert.NotNil(t, restsrv)
79 rr := httptest.NewRecorder()
80
81 reqMetric, err := http.NewRequest("GET", host+"/metric", nil)
82 restsrv.Handler.ServeHTTP(rr, reqMetric)
83 assert.Equal(t, err, nil)
84 assert.Equal(t, rr.Code, http.StatusUnauthorized, "REQUEST WITHOUT AUTHENTICATION")
85
86
87 reqDb, err := http.NewRequest("GET", host+"/db", nil)
88 assert.Equal(t, err, nil)
89 restsrv.Handler.ServeHTTP(rr, reqDb)
90 assert.Equal(t, rr.Code, http.StatusUnauthorized, "REQUEST WITHOUT AUTHENTICATION")
91
92
93 reqLog, err := http.NewRequest("GET", host+"/log", nil)
94 assert.Equal(t, err, nil)
95 restsrv.Handler.ServeHTTP(rr, reqLog)
96 assert.Equal(t, rr.Code, http.StatusUnauthorized, "REQUEST WITHOUT AUTHENTICATION")
97
98
99 reqConnect, err := http.NewRequest("GET", host+"/test-connect", nil)
100 assert.Equal(t, err, nil)
101 restsrv.Handler.ServeHTTP(rr, reqConnect)
102 assert.Equal(t, rr.Code, http.StatusUnauthorized, "REQUEST WITHOUT AUTHENTICATION")
103
104 }
105
106 func TestGetToken(t *testing.T) {
107 host := "http://localhost:8082"
108 restsrv, _ := webserver.Init(context.Background(), webserver.CmdOpts{WebAddr: "localhost:8082"}, os.DirFS("../webui/build"), nil, nil, nil)
109 rr := httptest.NewRecorder()
110
111 credentials := Credentials{
112 User: "admin",
113 Password: "admin",
114 }
115
116 payload, err := json.Marshal(credentials)
117 if err != nil {
118 fmt.Println("Error marshaling ", err)
119 }
120
121 reqToken, err := http.NewRequest("POST", host+"/login", strings.NewReader(string(payload)))
122 assert.Equal(t, err, nil)
123
124 restsrv.Handler.ServeHTTP(rr, reqToken)
125
126 assert.Equal(t, rr.Code, http.StatusOK, "TOKEN RESPONSE OK")
127
128 token, err := io.ReadAll(rr.Body)
129 fmt.Println(string(token))
130 assert.Equal(t, err, nil)
131 assert.NotEqual(t, token, nil)
132
133 }
134