198 lines
4.9 KiB
Go
198 lines
4.9 KiB
Go
package onvif
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestNewClient(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
endpoint string
|
|
wantError bool
|
|
}{
|
|
{
|
|
name: "valid http endpoint",
|
|
endpoint: "http://192.168.1.100/onvif/device_service",
|
|
wantError: false,
|
|
},
|
|
{
|
|
name: "valid https endpoint",
|
|
endpoint: "https://camera.example.com/onvif",
|
|
wantError: false,
|
|
},
|
|
{
|
|
name: "invalid endpoint",
|
|
endpoint: "not a url",
|
|
wantError: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
client, err := NewClient(tt.endpoint)
|
|
if (err != nil) != tt.wantError {
|
|
t.Errorf("NewClient() error = %v, wantError %v", err, tt.wantError)
|
|
return
|
|
}
|
|
if !tt.wantError && client == nil {
|
|
t.Error("NewClient() returned nil client")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestClientOptions(t *testing.T) {
|
|
endpoint := "http://192.168.1.100/onvif"
|
|
|
|
t.Run("WithCredentials", func(t *testing.T) {
|
|
username := "admin"
|
|
password := "test123"
|
|
|
|
client, err := NewClient(endpoint, WithCredentials(username, password))
|
|
if err != nil {
|
|
t.Fatalf("NewClient() error = %v", err)
|
|
}
|
|
|
|
gotUser, gotPass := client.GetCredentials()
|
|
if gotUser != username || gotPass != password {
|
|
t.Errorf("GetCredentials() = (%v, %v), want (%v, %v)",
|
|
gotUser, gotPass, username, password)
|
|
}
|
|
})
|
|
|
|
t.Run("WithTimeout", func(t *testing.T) {
|
|
timeout := 10 * time.Second
|
|
client, err := NewClient(endpoint, WithTimeout(timeout))
|
|
if err != nil {
|
|
t.Fatalf("NewClient() error = %v", err)
|
|
}
|
|
|
|
if client.httpClient.Timeout != timeout {
|
|
t.Errorf("HTTP client timeout = %v, want %v",
|
|
client.httpClient.Timeout, timeout)
|
|
}
|
|
})
|
|
|
|
t.Run("WithHTTPClient", func(t *testing.T) {
|
|
customClient := &http.Client{
|
|
Timeout: 5 * time.Second,
|
|
}
|
|
|
|
client, err := NewClient(endpoint, WithHTTPClient(customClient))
|
|
if err != nil {
|
|
t.Fatalf("NewClient() error = %v", err)
|
|
}
|
|
|
|
if client.httpClient != customClient {
|
|
t.Error("Custom HTTP client not set")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestClientEndpoint(t *testing.T) {
|
|
endpoint := "http://192.168.1.100/onvif"
|
|
client, err := NewClient(endpoint)
|
|
if err != nil {
|
|
t.Fatalf("NewClient() error = %v", err)
|
|
}
|
|
|
|
if got := client.Endpoint(); got != endpoint {
|
|
t.Errorf("Endpoint() = %v, want %v", got, endpoint)
|
|
}
|
|
}
|
|
|
|
func TestClientSetCredentials(t *testing.T) {
|
|
client, err := NewClient("http://192.168.1.100/onvif")
|
|
if err != nil {
|
|
t.Fatalf("NewClient() error = %v", err)
|
|
}
|
|
|
|
username := "newuser"
|
|
password := "newpass"
|
|
|
|
client.SetCredentials(username, password)
|
|
|
|
gotUser, gotPass := client.GetCredentials()
|
|
if gotUser != username || gotPass != password {
|
|
t.Errorf("After SetCredentials(), GetCredentials() = (%v, %v), want (%v, %v)",
|
|
gotUser, gotPass, username, password)
|
|
}
|
|
}
|
|
|
|
func TestGetDeviceInformationWithMockServer(t *testing.T) {
|
|
// Mock SOAP response
|
|
mockResponse := `<?xml version="1.0" encoding="UTF-8"?>
|
|
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
|
|
<s:Body>
|
|
<tds:GetDeviceInformationResponse>
|
|
<tds:Manufacturer>TestManufacturer</tds:Manufacturer>
|
|
<tds:Model>TestModel</tds:Model>
|
|
<tds:FirmwareVersion>1.0.0</tds:FirmwareVersion>
|
|
<tds:SerialNumber>123456</tds:SerialNumber>
|
|
<tds:HardwareId>HW001</tds:HardwareId>
|
|
</tds:GetDeviceInformationResponse>
|
|
</s:Body>
|
|
</s:Envelope>`
|
|
|
|
// Create mock server
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/soap+xml")
|
|
w.WriteHeader(http.StatusOK)
|
|
w.Write([]byte(mockResponse))
|
|
}))
|
|
defer server.Close()
|
|
|
|
// Create client
|
|
client, err := NewClient(server.URL)
|
|
if err != nil {
|
|
t.Fatalf("NewClient() error = %v", err)
|
|
}
|
|
|
|
// Note: This test demonstrates the structure but won't work without
|
|
// proper SOAP response parsing in the actual implementation
|
|
ctx := context.Background()
|
|
_, err = client.GetDeviceInformation(ctx)
|
|
|
|
// For now, we expect this to work with the mock server
|
|
// In a complete implementation, you would verify the response
|
|
if err != nil {
|
|
t.Logf("GetDeviceInformation() returned error: %v (expected with mock)", err)
|
|
}
|
|
}
|
|
|
|
func TestONVIFError(t *testing.T) {
|
|
err := NewONVIFError("Sender", "InvalidArgs", "Invalid parameter value")
|
|
|
|
if err.Code != "Sender" {
|
|
t.Errorf("Code = %v, want %v", err.Code, "Sender")
|
|
}
|
|
|
|
if err.Reason != "InvalidArgs" {
|
|
t.Errorf("Reason = %v, want %v", err.Reason, "InvalidArgs")
|
|
}
|
|
|
|
expectedError := "ONVIF error [Sender]: InvalidArgs - Invalid parameter value"
|
|
if err.Error() != expectedError {
|
|
t.Errorf("Error() = %v, want %v", err.Error(), expectedError)
|
|
}
|
|
|
|
if !IsONVIFError(err) {
|
|
t.Error("IsONVIFError() returned false for ONVIF error")
|
|
}
|
|
}
|
|
|
|
func BenchmarkNewClient(b *testing.B) {
|
|
endpoint := "http://192.168.1.100/onvif"
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err := NewClient(endpoint)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
}
|