Files
ClusterCanvas/service/internal/api/network_handlers_test.go
T
Squid 2605c3b346 Add users and network settings tabs with admin protections.
List and delete accounts with last-admin and Administrators-group guards, and expose editable network settings via the configuration UI.
2026-07-18 15:18:01 +02:00

154 lines
4.5 KiB
Go

package api
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"codeberg.org/SquidSE/ClusterCanvas/service/internal/settings"
)
type networkResponseTest struct {
Network settings.NetworkSettings `json:"network"`
}
func TestNetworkGetReturnsDefaults(t *testing.T) {
configDir := t.TempDir()
cookie := seedCompletedSetup(t, configDir)
router := NewRouter(configDir)
request := withSession(httptest.NewRequest(http.MethodGet, "/api/v1/network", nil), cookie)
recorder := httptest.NewRecorder()
router.ServeHTTP(recorder, request)
if recorder.Code != http.StatusOK {
t.Fatalf("expected status %d, got %d body=%s", http.StatusOK, recorder.Code, recorder.Body.String())
}
var payload networkResponseTest
if err := json.NewDecoder(recorder.Body).Decode(&payload); err != nil {
t.Fatalf("decode response: %v", err)
}
if payload.Network.ListenAddress != "0.0.0.0" {
t.Fatalf("expected listen_address 0.0.0.0, got %q", payload.Network.ListenAddress)
}
if payload.Network.AccessMode != settings.AccessModeOpen {
t.Fatalf("expected access_mode open, got %q", payload.Network.AccessMode)
}
}
func TestNetworkPutPersistsValidSettings(t *testing.T) {
configDir := t.TempDir()
cookie := seedCompletedSetup(t, configDir)
router := NewRouter(configDir)
body := []byte(`{
"network": {
"listen_address": "127.0.0.1",
"public_hostname": "",
"access_mode": "open",
"rules": []
}
}`)
request := withSession(httptest.NewRequest(http.MethodPut, "/api/v1/network", bytes.NewReader(body)), cookie)
recorder := httptest.NewRecorder()
router.ServeHTTP(recorder, request)
if recorder.Code != http.StatusOK {
t.Fatalf("expected status %d, got %d body=%s", http.StatusOK, recorder.Code, recorder.Body.String())
}
getReq := withSession(httptest.NewRequest(http.MethodGet, "/api/v1/network", nil), cookie)
getRec := httptest.NewRecorder()
router.ServeHTTP(getRec, getReq)
if getRec.Code != http.StatusOK {
t.Fatalf("expected status %d, got %d", http.StatusOK, getRec.Code)
}
var payload networkResponseTest
if err := json.NewDecoder(getRec.Body).Decode(&payload); err != nil {
t.Fatalf("decode response: %v", err)
}
if payload.Network.ListenAddress != "127.0.0.1" {
t.Fatalf("expected listen_address 127.0.0.1, got %q", payload.Network.ListenAddress)
}
}
func TestNetworkPutRejectsInvalidAccessMode(t *testing.T) {
configDir := t.TempDir()
cookie := seedCompletedSetup(t, configDir)
router := NewRouter(configDir)
body := []byte(`{
"network": {
"listen_address": "0.0.0.0",
"public_hostname": "",
"access_mode": "maybe",
"rules": []
}
}`)
request := withSession(httptest.NewRequest(http.MethodPut, "/api/v1/network", bytes.NewReader(body)), cookie)
recorder := httptest.NewRecorder()
router.ServeHTTP(recorder, request)
if recorder.Code != http.StatusBadRequest {
t.Fatalf("expected status %d, got %d", http.StatusBadRequest, recorder.Code)
}
}
func TestNetworkPutRejectsLockout(t *testing.T) {
configDir := t.TempDir()
cookie := seedCompletedSetup(t, configDir)
router := NewRouter(configDir)
body := []byte(`{
"network": {
"listen_address": "0.0.0.0",
"public_hostname": "",
"access_mode": "whitelist",
"rules": ["10.0.0.0/8"]
}
}`)
request := withSession(httptest.NewRequest(http.MethodPut, "/api/v1/network", bytes.NewReader(body)), cookie)
request.RemoteAddr = "192.168.1.50:12345"
recorder := httptest.NewRecorder()
router.ServeHTTP(recorder, request)
if recorder.Code != http.StatusBadRequest {
t.Fatalf("expected status %d, got %d body=%s", http.StatusBadRequest, recorder.Code, recorder.Body.String())
}
var payload apiErrorResponseTest
if err := json.NewDecoder(recorder.Body).Decode(&payload); err != nil {
t.Fatalf("decode response: %v", err)
}
if payload.Error == "" {
t.Fatal("expected lockout error message")
}
}
func TestNetworkPutAllowsWhitelistIncludingClient(t *testing.T) {
configDir := t.TempDir()
cookie := seedCompletedSetup(t, configDir)
router := NewRouter(configDir)
body := []byte(`{
"network": {
"listen_address": "0.0.0.0",
"public_hostname": "",
"access_mode": "whitelist",
"rules": ["192.168.1.50"]
}
}`)
request := withSession(httptest.NewRequest(http.MethodPut, "/api/v1/network", bytes.NewReader(body)), cookie)
request.RemoteAddr = "192.168.1.50:12345"
recorder := httptest.NewRecorder()
router.ServeHTTP(recorder, request)
if recorder.Code != http.StatusOK {
t.Fatalf("expected status %d, got %d body=%s", http.StatusOK, recorder.Code, recorder.Body.String())
}
}