...

Source file src/github.com/cybertec-postgresql/pgwatch/v6/internal/webserver/server_test.go

Documentation: github.com/cybertec-postgresql/pgwatch/v6/internal/webserver

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