1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-10 07:25:37 -05:00
Files
DankMaterialShell/backend/internal/server/network/handlers_test.go
2025-11-12 17:18:45 -05:00

264 lines
6.0 KiB
Go

package network
import (
"bytes"
"encoding/json"
"net"
"testing"
"github.com/AvengeMedia/DankMaterialShell/backend/internal/server/models"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type mockNetConn struct {
net.Conn
readBuf *bytes.Buffer
writeBuf *bytes.Buffer
closed bool
}
func newMockNetConn() *mockNetConn {
return &mockNetConn{
readBuf: &bytes.Buffer{},
writeBuf: &bytes.Buffer{},
}
}
func (m *mockNetConn) Read(b []byte) (n int, err error) {
return m.readBuf.Read(b)
}
func (m *mockNetConn) Write(b []byte) (n int, err error) {
return m.writeBuf.Write(b)
}
func (m *mockNetConn) Close() error {
m.closed = true
return nil
}
func TestRespondError_Network(t *testing.T) {
conn := newMockNetConn()
models.RespondError(conn, 123, "test error")
var resp models.Response[any]
err := json.NewDecoder(conn.writeBuf).Decode(&resp)
require.NoError(t, err)
assert.Equal(t, 123, resp.ID)
assert.Equal(t, "test error", resp.Error)
assert.Nil(t, resp.Result)
}
func TestRespond_Network(t *testing.T) {
conn := newMockNetConn()
result := SuccessResult{Success: true, Message: "test"}
models.Respond(conn, 123, result)
var resp models.Response[SuccessResult]
err := json.NewDecoder(conn.writeBuf).Decode(&resp)
require.NoError(t, err)
assert.Equal(t, 123, resp.ID)
assert.Empty(t, resp.Error)
require.NotNil(t, resp.Result)
assert.True(t, resp.Result.Success)
assert.Equal(t, "test", resp.Result.Message)
}
func TestHandleGetState(t *testing.T) {
manager := &Manager{
state: &NetworkState{
NetworkStatus: StatusWiFi,
WiFiSSID: "TestNetwork",
WiFiConnected: true,
},
}
conn := newMockNetConn()
req := Request{ID: 123, Method: "network.getState"}
handleGetState(conn, req, manager)
var resp models.Response[NetworkState]
err := json.NewDecoder(conn.writeBuf).Decode(&resp)
require.NoError(t, err)
assert.Equal(t, 123, resp.ID)
assert.Empty(t, resp.Error)
require.NotNil(t, resp.Result)
assert.Equal(t, StatusWiFi, resp.Result.NetworkStatus)
assert.Equal(t, "TestNetwork", resp.Result.WiFiSSID)
}
func TestHandleGetWiFiNetworks(t *testing.T) {
manager := &Manager{
state: &NetworkState{
WiFiNetworks: []WiFiNetwork{
{SSID: "Network1", Signal: 90},
{SSID: "Network2", Signal: 80},
},
},
}
conn := newMockNetConn()
req := Request{ID: 123, Method: "network.wifi.networks"}
handleGetWiFiNetworks(conn, req, manager)
var resp models.Response[[]WiFiNetwork]
err := json.NewDecoder(conn.writeBuf).Decode(&resp)
require.NoError(t, err)
assert.Equal(t, 123, resp.ID)
assert.Empty(t, resp.Error)
require.NotNil(t, resp.Result)
assert.Len(t, *resp.Result, 2)
assert.Equal(t, "Network1", (*resp.Result)[0].SSID)
}
func TestHandleConnectWiFi(t *testing.T) {
t.Run("missing ssid parameter", func(t *testing.T) {
manager := &Manager{
state: &NetworkState{},
}
conn := newMockNetConn()
req := Request{
ID: 123,
Method: "network.wifi.connect",
Params: map[string]interface{}{},
}
handleConnectWiFi(conn, req, manager)
var resp models.Response[any]
err := json.NewDecoder(conn.writeBuf).Decode(&resp)
require.NoError(t, err)
assert.Equal(t, 123, resp.ID)
assert.Contains(t, resp.Error, "missing or invalid 'ssid' parameter")
})
}
func TestHandleSetPreference(t *testing.T) {
t.Run("missing preference parameter", func(t *testing.T) {
manager := &Manager{
state: &NetworkState{},
}
conn := newMockNetConn()
req := Request{
ID: 123,
Method: "network.preference.set",
Params: map[string]interface{}{},
}
handleSetPreference(conn, req, manager)
var resp models.Response[any]
err := json.NewDecoder(conn.writeBuf).Decode(&resp)
require.NoError(t, err)
assert.Equal(t, 123, resp.ID)
assert.Contains(t, resp.Error, "missing or invalid 'preference' parameter")
})
}
func TestHandleGetNetworkInfo(t *testing.T) {
t.Run("missing ssid parameter", func(t *testing.T) {
manager := &Manager{
state: &NetworkState{},
}
conn := newMockNetConn()
req := Request{
ID: 123,
Method: "network.info",
Params: map[string]interface{}{},
}
handleGetNetworkInfo(conn, req, manager)
var resp models.Response[any]
err := json.NewDecoder(conn.writeBuf).Decode(&resp)
require.NoError(t, err)
assert.Equal(t, 123, resp.ID)
assert.Contains(t, resp.Error, "missing or invalid 'ssid' parameter")
})
}
func TestHandleRequest(t *testing.T) {
manager := &Manager{
state: &NetworkState{
NetworkStatus: StatusWiFi,
},
}
t.Run("unknown method", func(t *testing.T) {
conn := newMockNetConn()
req := Request{
ID: 123,
Method: "network.unknown",
}
HandleRequest(conn, req, manager)
var resp models.Response[any]
err := json.NewDecoder(conn.writeBuf).Decode(&resp)
require.NoError(t, err)
assert.Equal(t, 123, resp.ID)
assert.Contains(t, resp.Error, "unknown method")
})
t.Run("valid method - getState", func(t *testing.T) {
conn := newMockNetConn()
req := Request{
ID: 123,
Method: "network.getState",
}
HandleRequest(conn, req, manager)
var resp models.Response[NetworkState]
err := json.NewDecoder(conn.writeBuf).Decode(&resp)
require.NoError(t, err)
assert.Equal(t, 123, resp.ID)
assert.Empty(t, resp.Error)
})
}
func TestHandleSubscribe(t *testing.T) {
// This test is complex due to the streaming nature of subscriptions
// Better suited as an integration test
t.Skip("Subscription test requires connection lifecycle management - integration test needed")
}
func TestManager_Subscribe_Unsubscribe(t *testing.T) {
manager := &Manager{
state: &NetworkState{},
subscribers: make(map[string]chan NetworkState),
}
t.Run("subscribe creates channel", func(t *testing.T) {
ch := manager.Subscribe("client1")
assert.NotNil(t, ch)
assert.Len(t, manager.subscribers, 1)
})
t.Run("unsubscribe removes channel", func(t *testing.T) {
manager.Unsubscribe("client1")
assert.Len(t, manager.subscribers, 0)
})
t.Run("unsubscribe non-existent client is safe", func(t *testing.T) {
assert.NotPanics(t, func() {
manager.Unsubscribe("non-existent")
})
})
}