Files

80 lines
2.7 KiB
Go

package api
import (
"encoding/json"
"net/http"
"net/http/httptest"
"strconv"
"testing"
"github.com/gin-gonic/gin"
"vpn-platform/backend/internal/core"
"vpn-platform/backend/internal/model"
"vpn-platform/backend/internal/store"
)
type stateTestProtocol struct{}
func (stateTestProtocol) Name() string { return "state-test" }
func (stateTestProtocol) DisplayName() string { return "state-test" }
func (stateTestProtocol) Validate(cfg map[string]interface{}) (map[string]interface{}, error) {
return cfg, nil
}
func (stateTestProtocol) Create(*model.Tunnel) error { return nil }
func (stateTestProtocol) Start(*model.Tunnel) error { return nil }
func (stateTestProtocol) Stop(*model.Tunnel) error { return nil }
func (stateTestProtocol) Status(*model.Tunnel) (core.Status, error) { return core.Status{}, nil }
func (stateTestProtocol) GenerateClientConfig(*model.Tunnel) (string, error) { return "", nil }
func (stateTestProtocol) Delete(*model.Tunnel) error { return nil }
func (stateTestProtocol) Available() (bool, string) { return true, "" }
func TestStartStopDropsStaleRuntimeSnapshot(t *testing.T) {
oldDB := store.DB
t.Cleanup(func() { store.DB = oldDB })
if err := store.Init(t.TempDir()); err != nil {
t.Fatal(err)
}
line := model.Tunnel{Name: "snapshot", Protocol: "state-test", State: "running", Config: "{}"}
if err := store.DB.Create(&line).Error; err != nil {
t.Fatal(err)
}
mgr := core.NewManager()
mgr.Register(stateTestProtocol{})
s := NewServer(mgr)
for _, tc := range []struct{ operation, oldState, wantState string }{
{"stop", "running", "stopped"},
{"start", "stopped", "running"},
} {
mgr.SetStatus(line.ID, core.Status{State: tc.oldState})
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Params = gin.Params{{Key: "id", Value: strconv.FormatUint(uint64(line.ID), 10)}}
if tc.operation == "stop" {
s.stopTunnel(c)
} else {
s.startTunnel(c)
}
if w.Code != http.StatusOK {
t.Fatalf("%s returned %d: %s", tc.operation, w.Code, w.Body.String())
}
if _, ok := mgr.GetStatus(line.ID); ok {
t.Fatalf("%s left the old runtime status cached", tc.operation)
}
listResponse := httptest.NewRecorder()
listContext, _ := gin.CreateTestContext(listResponse)
s.listTunnels(listContext)
var rows []struct {
State string `json:"state"`
Runtime *core.Status `json:"runtime"`
}
if err := json.Unmarshal(listResponse.Body.Bytes(), &rows); err != nil {
t.Fatal(err)
}
if len(rows) != 1 || rows[0].State != tc.wantState || rows[0].Runtime != nil {
t.Fatalf("%s list returned stale state: %+v", tc.operation, rows)
}
}
}