1 package webserver_test
2
3 import (
4 "context"
5 "fmt"
6 "io"
7 "net/http"
8 "net/http/httptest"
9 "strings"
10 "testing"
11
12 jsoniter "github.com/json-iterator/go"
13
14 "github.com/cybertec-postgresql/pgwatch/v5/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"}, 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"}, 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"}, 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"}, 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"}, nil, nil, nil)
78 assert.NotNil(t, restsrv)
79 rr := httptest.NewRecorder()
80
81 reqOpts, err := http.NewRequest("OPTIONS", host, nil)
82 assert.NoError(t, err)
83 restsrv.Handler.ServeHTTP(rr, reqOpts)
84 assert.Equal(t, http.StatusOK, rr.Code)
85
86
87 rr = httptest.NewRecorder()
88 reqMetric, err := http.NewRequest("GET", host+"/metric", nil)
89 restsrv.Handler.ServeHTTP(rr, reqMetric)
90 assert.NoError(t, err)
91 assert.Equal(t, http.StatusUnauthorized, rr.Code, "REQUEST WITHOUT AUTHENTICATION")
92
93
94 rr = httptest.NewRecorder()
95 reqDb, err := http.NewRequest("GET", host+"/source", nil)
96 assert.NoError(t, err)
97 restsrv.Handler.ServeHTTP(rr, reqDb)
98 assert.Equal(t, http.StatusUnauthorized, rr.Code, "REQUEST WITHOUT AUTHENTICATION")
99
100
101 rr = httptest.NewRecorder()
102 reqLog, err := http.NewRequest("GET", host+"/log", nil)
103 assert.NoError(t, err)
104 restsrv.Handler.ServeHTTP(rr, reqLog)
105 assert.Equal(t, http.StatusUnauthorized, rr.Code, "REQUEST WITHOUT AUTHENTICATION")
106
107
108 rr = httptest.NewRecorder()
109 reqConnect, err := http.NewRequest("GET", host+"/test-connect", nil)
110 assert.NoError(t, err)
111 restsrv.Handler.ServeHTTP(rr, reqConnect)
112 assert.Equal(t, http.StatusUnauthorized, rr.Code, "REQUEST WITHOUT AUTHENTICATION")
113
114 }
115
116 func TestGetToken(t *testing.T) {
117 host := "http://localhost:8082"
118 restsrv, _ := webserver.Init(context.Background(), webserver.CmdOpts{WebAddr: "localhost:8082"}, nil, nil, nil)
119 rr := httptest.NewRecorder()
120
121 credentials := Credentials{
122 User: "admin",
123 Password: "admin",
124 }
125
126 payload, err := jsoniter.ConfigFastest.Marshal(credentials)
127 if err != nil {
128 fmt.Println("Error marshaling ", err)
129 }
130
131 reqToken, err := http.NewRequest("POST", host+"/login", strings.NewReader(string(payload)))
132 assert.Equal(t, err, nil)
133
134 restsrv.Handler.ServeHTTP(rr, reqToken)
135
136 assert.Equal(t, rr.Code, http.StatusOK, "TOKEN RESPONSE OK")
137
138 token, err := io.ReadAll(rr.Body)
139 fmt.Println(string(token))
140 assert.Equal(t, err, nil)
141 assert.NotEqual(t, token, nil)
142
143 }
144