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) } }