package onvif
import (
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
func newMockDeviceWiFiServer() *httptest.Server {
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/soap+xml")
// Parse request to determine which operation
buf := make([]byte, r.ContentLength)
_, _ = r.Body.Read(buf)
requestBody := string(buf)
var response string
switch {
case strings.Contains(requestBody, "GetDot11Capabilities"):
response = `
true
true
false
false
false
`
case strings.Contains(requestBody, "GetDot11Status"):
response = `
TestNetwork
00:11:22:33:44:55
CCMP
CCMP
Good
dot11-config-001
`
case strings.Contains(requestBody, "GetDot1XConfiguration") && !strings.Contains(requestBody, "GetDot1XConfigurations"):
response = `
dot1x-config-001
device@example.com
`
case strings.Contains(requestBody, "GetDot1XConfigurations"):
response = `
dot1x-config-001
device1@example.com
dot1x-config-002
device2@example.com
`
case strings.Contains(requestBody, "SetDot1XConfiguration"):
response = `
`
case strings.Contains(requestBody, "CreateDot1XConfiguration"):
response = `
`
case strings.Contains(requestBody, "DeleteDot1XConfiguration"):
response = `
`
case strings.Contains(requestBody, "ScanAvailableDot11Networks"):
response = `
Network1
00:11:22:33:44:55
PSK
CCMP
CCMP
Very Good
Network2
AA:BB:CC:DD:EE:FF
Dot1X
CCMP
CCMP
Good
`
default:
response = `
SOAP-ENV:Receiver
Unknown operation
`
}
_, _ = w.Write([]byte(response))
}))
}
func TestGetDot11Capabilities(t *testing.T) {
server := newMockDeviceWiFiServer()
defer server.Close()
client, err := NewClient(server.URL)
if err != nil {
t.Fatalf("NewClient failed: %v", err)
}
ctx := context.Background()
caps, err := client.GetDot11Capabilities(ctx)
if err != nil {
t.Fatalf("GetDot11Capabilities failed: %v", err)
}
if !caps.TKIP {
t.Error("Expected TKIP to be supported")
}
if !caps.ScanAvailableNetworks {
t.Error("Expected ScanAvailableNetworks to be supported")
}
if caps.MultipleConfiguration {
t.Error("Expected MultipleConfiguration to be false")
}
if caps.WEP {
t.Error("Expected WEP to be false")
}
}
func TestGetDot11Status(t *testing.T) {
server := newMockDeviceWiFiServer()
defer server.Close()
client, err := NewClient(server.URL)
if err != nil {
t.Fatalf("NewClient failed: %v", err)
}
ctx := context.Background()
status, err := client.GetDot11Status(ctx, "wifi0")
if err != nil {
t.Fatalf("GetDot11Status failed: %v", err)
}
if status.SSID != "TestNetwork" {
t.Errorf("Expected SSID 'TestNetwork', got '%s'", status.SSID)
}
if status.BSSID != "00:11:22:33:44:55" {
t.Errorf("Expected BSSID '00:11:22:33:44:55', got '%s'", status.BSSID)
}
if status.PairCipher != Dot11CipherCCMP {
t.Errorf("Expected PairCipher 'CCMP', got '%s'", status.PairCipher)
}
if status.GroupCipher != Dot11CipherCCMP {
t.Errorf("Expected GroupCipher 'CCMP', got '%s'", status.GroupCipher)
}
if status.SignalStrength != Dot11SignalGood {
t.Errorf("Expected SignalStrength 'Good', got '%s'", status.SignalStrength)
}
if status.ActiveConfigAlias != "dot11-config-001" {
t.Errorf("Expected ActiveConfigAlias 'dot11-config-001', got '%s'", status.ActiveConfigAlias)
}
}
func TestGetDot1XConfiguration(t *testing.T) {
server := newMockDeviceWiFiServer()
defer server.Close()
client, err := NewClient(server.URL)
if err != nil {
t.Fatalf("NewClient failed: %v", err)
}
ctx := context.Background()
config, err := client.GetDot1XConfiguration(ctx, "dot1x-config-001")
if err != nil {
t.Fatalf("GetDot1XConfiguration failed: %v", err)
}
if config.Dot1XConfigurationToken != "dot1x-config-001" {
t.Errorf("Expected Dot1XConfigurationToken 'dot1x-config-001', got '%s'", config.Dot1XConfigurationToken)
}
if config.Identity != "device@example.com" {
t.Errorf("Expected Identity 'device@example.com', got '%s'", config.Identity)
}
}
func TestGetDot1XConfigurations(t *testing.T) {
server := newMockDeviceWiFiServer()
defer server.Close()
client, err := NewClient(server.URL)
if err != nil {
t.Fatalf("NewClient failed: %v", err)
}
ctx := context.Background()
configs, err := client.GetDot1XConfigurations(ctx)
if err != nil {
t.Fatalf("GetDot1XConfigurations failed: %v", err)
}
if len(configs) != 2 {
t.Fatalf("Expected 2 configurations, got %d", len(configs))
}
if configs[0].Dot1XConfigurationToken != "dot1x-config-001" {
t.Errorf("Expected first config token 'dot1x-config-001', got '%s'", configs[0].Dot1XConfigurationToken)
}
if configs[0].Identity != "device1@example.com" {
t.Errorf("Expected first identity 'device1@example.com', got '%s'", configs[0].Identity)
}
if configs[1].Dot1XConfigurationToken != "dot1x-config-002" {
t.Errorf("Expected second config token 'dot1x-config-002', got '%s'", configs[1].Dot1XConfigurationToken)
}
if configs[1].Identity != "device2@example.com" {
t.Errorf("Expected second identity 'device2@example.com', got '%s'", configs[1].Identity)
}
}
func TestSetDot1XConfiguration(t *testing.T) {
server := newMockDeviceWiFiServer()
defer server.Close()
client, err := NewClient(server.URL)
if err != nil {
t.Fatalf("NewClient failed: %v", err)
}
ctx := context.Background()
config := &Dot1XConfiguration{
Dot1XConfigurationToken: "dot1x-config-001",
Identity: "updated@example.com",
}
err = client.SetDot1XConfiguration(ctx, config)
if err != nil {
t.Fatalf("SetDot1XConfiguration failed: %v", err)
}
}
func TestCreateDot1XConfiguration(t *testing.T) {
server := newMockDeviceWiFiServer()
defer server.Close()
client, err := NewClient(server.URL)
if err != nil {
t.Fatalf("NewClient failed: %v", err)
}
ctx := context.Background()
config := &Dot1XConfiguration{
Dot1XConfigurationToken: "dot1x-config-new",
Identity: "new@example.com",
}
err = client.CreateDot1XConfiguration(ctx, config)
if err != nil {
t.Fatalf("CreateDot1XConfiguration failed: %v", err)
}
}
func TestDeleteDot1XConfiguration(t *testing.T) {
server := newMockDeviceWiFiServer()
defer server.Close()
client, err := NewClient(server.URL)
if err != nil {
t.Fatalf("NewClient failed: %v", err)
}
ctx := context.Background()
err = client.DeleteDot1XConfiguration(ctx, "dot1x-config-001")
if err != nil {
t.Fatalf("DeleteDot1XConfiguration failed: %v", err)
}
}
func TestScanAvailableDot11Networks(t *testing.T) {
server := newMockDeviceWiFiServer()
defer server.Close()
client, err := NewClient(server.URL)
if err != nil {
t.Fatalf("NewClient failed: %v", err)
}
ctx := context.Background()
networks, err := client.ScanAvailableDot11Networks(ctx, "wifi0")
if err != nil {
t.Fatalf("ScanAvailableDot11Networks failed: %v", err)
}
if len(networks) != 2 {
t.Fatalf("Expected 2 networks, got %d", len(networks))
}
// Test first network
if networks[0].SSID != "Network1" {
t.Errorf("Expected first SSID 'Network1', got '%s'", networks[0].SSID)
}
if networks[0].BSSID != "00:11:22:33:44:55" {
t.Errorf("Expected first BSSID '00:11:22:33:44:55', got '%s'", networks[0].BSSID)
}
if len(networks[0].AuthAndMangementSuite) == 0 || networks[0].AuthAndMangementSuite[0] != Dot11AuthPSK {
t.Errorf("Expected first auth suite 'PSK'")
}
if len(networks[0].PairCipher) == 0 || networks[0].PairCipher[0] != Dot11CipherCCMP {
t.Errorf("Expected first pair cipher 'CCMP'")
}
if networks[0].SignalStrength != Dot11SignalVeryGood {
t.Errorf("Expected first signal strength 'VeryGood', got '%s'", networks[0].SignalStrength)
}
// Test second network
if networks[1].SSID != "Network2" {
t.Errorf("Expected second SSID 'Network2', got '%s'", networks[1].SSID)
}
if networks[1].BSSID != "AA:BB:CC:DD:EE:FF" {
t.Errorf("Expected second BSSID 'AA:BB:CC:DD:EE:FF', got '%s'", networks[1].BSSID)
}
if len(networks[1].AuthAndMangementSuite) == 0 || networks[1].AuthAndMangementSuite[0] != Dot11AuthDot1X {
t.Errorf("Expected second auth suite 'Dot1X'")
}
if networks[1].SignalStrength != Dot11SignalGood {
t.Errorf("Expected second signal strength 'Good', got '%s'", networks[1].SignalStrength)
}
}