...

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

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

     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  	// cors OPTIONS
    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  	// test request metrics
    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  	// test request database
    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  	// test request
   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  	// request metrics
   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