package onvif
import (
"context"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
// Test device information from real camera:
// Manufacturer: Bosch
// Model: FLEXIDOME indoor 5100i IR
// Firmware: 8.71.0066
// Serial Number: 404754734001050102
// Hardware ID: F000B543
// TestGetMediaServiceCapabilities_Bosch tests GetMediaServiceCapabilities with real camera response.
func TestGetMediaServiceCapabilities_Bosch(t *testing.T) {
// Real SOAP response from Bosch FLEXIDOME indoor 5100i IR (FW: 8.71.0066)
// Note: Adapted to match the expected nested structure in the code
realResponse := `
`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Validate request
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("Failed to read request body: %v", err)
}
bodyStr := string(body)
// Validate SOAP request contains GetServiceCapabilities
if !strings.Contains(bodyStr, "GetServiceCapabilities") {
t.Errorf("Request should contain GetServiceCapabilities, got: %s", bodyStr)
}
if !strings.Contains(bodyStr, "http://www.onvif.org/ver10/media/wsdl") {
t.Errorf("Request should contain media namespace, got: %s", bodyStr)
}
// Return real camera response
w.Header().Set("Content-Type", "application/soap+xml")
w.WriteHeader(http.StatusOK)
w.Write([]byte(realResponse))
}))
defer server.Close()
client, err := NewClient(server.URL, WithCredentials("service", "Service.1234"))
if err != nil {
t.Fatalf("NewClient() failed: %v", err)
}
client.mediaEndpoint = server.URL
ctx := context.Background()
capabilities, err := client.GetMediaServiceCapabilities(ctx)
if err != nil {
t.Fatalf("GetMediaServiceCapabilities() failed: %v", err)
}
// Validate response matches real camera
if capabilities.MaximumNumberOfProfiles != 32 {
t.Errorf("Expected MaximumNumberOfProfiles=32 (Bosch FLEXIDOME), got %d", capabilities.MaximumNumberOfProfiles)
}
if !capabilities.RTPMulticast {
t.Error("Expected RTPMulticast=true (Bosch FLEXIDOME)")
}
if !capabilities.RTPRTSPTCP {
t.Error("Expected RTPRTSPTCP=true (Bosch FLEXIDOME)")
}
if capabilities.SnapshotURI {
t.Error("Expected SnapshotURI=false (Bosch FLEXIDOME)")
}
if !capabilities.Rotation {
t.Error("Expected Rotation=true (Bosch FLEXIDOME)")
}
}
// TestGetProfiles_Bosch tests GetProfiles with real camera response.
func TestGetProfiles_Bosch(t *testing.T) {
// Real SOAP response from Bosch FLEXIDOME indoor 5100i IR (FW: 8.71.0066)
realResponse := `
Profile_L1S1
Camera_1
4
1
Balanced 2 MP
1
H264
1920
1080
0
30
1
5200
`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Validate request
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("Failed to read request body: %v", err)
}
bodyStr := string(body)
// Validate SOAP request
if !strings.Contains(bodyStr, "GetProfiles") {
t.Errorf("Request should contain GetProfiles, got: %s", bodyStr)
}
// Return real camera response
w.Header().Set("Content-Type", "application/soap+xml")
w.WriteHeader(http.StatusOK)
w.Write([]byte(realResponse))
}))
defer server.Close()
client, err := NewClient(server.URL, WithCredentials("service", "Service.1234"))
if err != nil {
t.Fatalf("NewClient() failed: %v", err)
}
client.mediaEndpoint = server.URL
ctx := context.Background()
profiles, err := client.GetProfiles(ctx)
if err != nil {
t.Fatalf("GetProfiles() failed: %v", err)
}
// Validate response matches real camera
if len(profiles) == 0 {
t.Fatal("Expected at least one profile from Bosch FLEXIDOME")
}
if profiles[0].Token != "0" {
t.Errorf("Expected profile token=0 (Bosch FLEXIDOME), got %s", profiles[0].Token)
}
if profiles[0].Name != "Profile_L1S1" {
t.Errorf("Expected profile name=Profile_L1S1 (Bosch FLEXIDOME), got %s", profiles[0].Name)
}
if profiles[0].VideoEncoderConfiguration == nil {
t.Fatal("Expected VideoEncoderConfiguration from Bosch FLEXIDOME")
}
if profiles[0].VideoEncoderConfiguration.Token != "EncCfg_L1S1" {
t.Errorf("Expected encoder token=EncCfg_L1S1 (Bosch FLEXIDOME), got %s", profiles[0].VideoEncoderConfiguration.Token)
}
if profiles[0].VideoEncoderConfiguration.Encoding != "H264" {
t.Errorf("Expected encoding=H264 (Bosch FLEXIDOME), got %s", profiles[0].VideoEncoderConfiguration.Encoding)
}
if profiles[0].VideoEncoderConfiguration.Resolution.Width != 1920 {
t.Errorf("Expected width=1920 (Bosch FLEXIDOME), got %d", profiles[0].VideoEncoderConfiguration.Resolution.Width)
}
if profiles[0].VideoEncoderConfiguration.Resolution.Height != 1080 {
t.Errorf("Expected height=1080 (Bosch FLEXIDOME), got %d", profiles[0].VideoEncoderConfiguration.Resolution.Height)
}
}
// TestGetVideoSources_Bosch tests GetVideoSources with real camera response.
func TestGetVideoSources_Bosch(t *testing.T) {
// Real SOAP response from Bosch FLEXIDOME indoor 5100i IR (FW: 8.71.0066)
realResponse := `
30
1920
1080
`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("Failed to read request body: %v", err)
}
bodyStr := string(body)
if !strings.Contains(bodyStr, "GetVideoSources") {
t.Errorf("Request should contain GetVideoSources, got: %s", bodyStr)
}
w.Header().Set("Content-Type", "application/soap+xml")
w.WriteHeader(http.StatusOK)
w.Write([]byte(realResponse))
}))
defer server.Close()
client, err := NewClient(server.URL, WithCredentials("service", "Service.1234"))
if err != nil {
t.Fatalf("NewClient() failed: %v", err)
}
client.mediaEndpoint = server.URL
ctx := context.Background()
sources, err := client.GetVideoSources(ctx)
if err != nil {
t.Fatalf("GetVideoSources() failed: %v", err)
}
// Validate response matches real camera
if len(sources) == 0 {
t.Fatal("Expected at least one video source from Bosch FLEXIDOME")
}
if sources[0].Token != "1" {
t.Errorf("Expected source token=1 (Bosch FLEXIDOME), got %s", sources[0].Token)
}
if sources[0].Framerate != 30 {
t.Errorf("Expected framerate=30 (Bosch FLEXIDOME), got %f", sources[0].Framerate)
}
if sources[0].Resolution.Width != 1920 {
t.Errorf("Expected width=1920 (Bosch FLEXIDOME), got %d", sources[0].Resolution.Width)
}
if sources[0].Resolution.Height != 1080 {
t.Errorf("Expected height=1080 (Bosch FLEXIDOME), got %d", sources[0].Resolution.Height)
}
}
// TestGetAudioSources_Bosch tests GetAudioSources with real camera response.
func TestGetAudioSources_Bosch(t *testing.T) {
// Real SOAP response from Bosch FLEXIDOME indoor 5100i IR (FW: 8.71.0066)
realResponse := `
2
`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("Failed to read request body: %v", err)
}
bodyStr := string(body)
if !strings.Contains(bodyStr, "GetAudioSources") {
t.Errorf("Request should contain GetAudioSources, got: %s", bodyStr)
}
w.Header().Set("Content-Type", "application/soap+xml")
w.WriteHeader(http.StatusOK)
w.Write([]byte(realResponse))
}))
defer server.Close()
client, err := NewClient(server.URL, WithCredentials("service", "Service.1234"))
if err != nil {
t.Fatalf("NewClient() failed: %v", err)
}
client.mediaEndpoint = server.URL
ctx := context.Background()
sources, err := client.GetAudioSources(ctx)
if err != nil {
t.Fatalf("GetAudioSources() failed: %v", err)
}
// Validate response matches real camera
if len(sources) == 0 {
t.Fatal("Expected at least one audio source from Bosch FLEXIDOME")
}
if sources[0].Token != "1" {
t.Errorf("Expected source token=1 (Bosch FLEXIDOME), got %s", sources[0].Token)
}
if sources[0].Channels != 2 {
t.Errorf("Expected channels=2 (Bosch FLEXIDOME), got %d", sources[0].Channels)
}
}
// TestGetAudioOutputs_Bosch tests GetAudioOutputs with real camera response.
func TestGetAudioOutputs_Bosch(t *testing.T) {
// Real SOAP response from Bosch FLEXIDOME indoor 5100i IR (FW: 8.71.0066)
realResponse := `
`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("Failed to read request body: %v", err)
}
bodyStr := string(body)
if !strings.Contains(bodyStr, "GetAudioOutputs") {
t.Errorf("Request should contain GetAudioOutputs, got: %s", bodyStr)
}
w.Header().Set("Content-Type", "application/soap+xml")
w.WriteHeader(http.StatusOK)
w.Write([]byte(realResponse))
}))
defer server.Close()
client, err := NewClient(server.URL, WithCredentials("service", "Service.1234"))
if err != nil {
t.Fatalf("NewClient() failed: %v", err)
}
client.mediaEndpoint = server.URL
ctx := context.Background()
outputs, err := client.GetAudioOutputs(ctx)
if err != nil {
t.Fatalf("GetAudioOutputs() failed: %v", err)
}
// Validate response matches real camera
if len(outputs) == 0 {
t.Fatal("Expected at least one audio output from Bosch FLEXIDOME")
}
if outputs[0].Token != "AudioOut 1" {
t.Errorf("Expected output token=AudioOut 1 (Bosch FLEXIDOME), got %s", outputs[0].Token)
}
}
// TestGetStreamURI_Bosch tests GetStreamURI with real camera response.
func TestGetStreamURI_Bosch(t *testing.T) {
// Real SOAP response from Bosch FLEXIDOME indoor 5100i IR (FW: 8.71.0066)
realResponse := `
rtsp://192.168.1.201/rtsp_tunnel?p=0&line=1&inst=1&vcd=2
false
true
0
`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("Failed to read request body: %v", err)
}
bodyStr := string(body)
if !strings.Contains(bodyStr, "GetStreamUri") {
t.Errorf("Request should contain GetStreamUri, got: %s", bodyStr)
}
if !strings.Contains(bodyStr, "ProfileToken") {
t.Errorf("Request should contain ProfileToken, got: %s", bodyStr)
}
w.Header().Set("Content-Type", "application/soap+xml")
w.WriteHeader(http.StatusOK)
w.Write([]byte(realResponse))
}))
defer server.Close()
client, err := NewClient(server.URL, WithCredentials("service", "Service.1234"))
if err != nil {
t.Fatalf("NewClient() failed: %v", err)
}
client.mediaEndpoint = server.URL
ctx := context.Background()
uri, err := client.GetStreamURI(ctx, "0")
if err != nil {
t.Fatalf("GetStreamURI() failed: %v", err)
}
// Validate response matches real camera
if !strings.Contains(uri.URI, "rtsp://") {
t.Errorf("Expected RTSP URI from Bosch FLEXIDOME, got %s", uri.URI)
}
if !strings.Contains(uri.URI, "rtsp_tunnel") {
t.Errorf("Expected rtsp_tunnel in URI from Bosch FLEXIDOME, got %s", uri.URI)
}
if uri.InvalidAfterReboot != true {
t.Error("Expected InvalidAfterReboot=true from Bosch FLEXIDOME")
}
}
// TestGetSnapshotURI_Bosch tests GetSnapshotURI with real camera response.
func TestGetSnapshotURI_Bosch(t *testing.T) {
// Real SOAP response from Bosch FLEXIDOME indoor 5100i IR (FW: 8.71.0066)
realResponse := `
http://192.168.1.201/snap.jpg?JpegCam=1
false
true
0
`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("Failed to read request body: %v", err)
}
bodyStr := string(body)
if !strings.Contains(bodyStr, "GetSnapshotUri") {
t.Errorf("Request should contain GetSnapshotUri, got: %s", bodyStr)
}
w.Header().Set("Content-Type", "application/soap+xml")
w.WriteHeader(http.StatusOK)
w.Write([]byte(realResponse))
}))
defer server.Close()
client, err := NewClient(server.URL, WithCredentials("service", "Service.1234"))
if err != nil {
t.Fatalf("NewClient() failed: %v", err)
}
client.mediaEndpoint = server.URL
ctx := context.Background()
uri, err := client.GetSnapshotURI(ctx, "0")
if err != nil {
t.Fatalf("GetSnapshotURI() failed: %v", err)
}
// Validate response matches real camera
if !strings.Contains(uri.URI, "http://") {
t.Errorf("Expected HTTP URI from Bosch FLEXIDOME, got %s", uri.URI)
}
if !strings.Contains(uri.URI, "snap.jpg") {
t.Errorf("Expected snap.jpg in URI from Bosch FLEXIDOME, got %s", uri.URI)
}
if !strings.Contains(uri.URI, "JpegCam=1") {
t.Errorf("Expected JpegCam=1 in URI from Bosch FLEXIDOME, got %s", uri.URI)
}
}
// TestGetVideoEncoderConfiguration_Bosch tests GetVideoEncoderConfiguration with real camera response.
func TestGetVideoEncoderConfiguration_Bosch(t *testing.T) {
// Real SOAP response from Bosch FLEXIDOME indoor 5100i IR (FW: 8.71.0066)
realResponse := `
Balanced 2 MP
1
H264
1920
1080
0
30
1
5200
`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("Failed to read request body: %v", err)
}
bodyStr := string(body)
if !strings.Contains(bodyStr, "GetVideoEncoderConfiguration") {
t.Errorf("Request should contain GetVideoEncoderConfiguration, got: %s", bodyStr)
}
if !strings.Contains(bodyStr, "ConfigurationToken") {
t.Errorf("Request should contain ConfigurationToken, got: %s", bodyStr)
}
w.Header().Set("Content-Type", "application/soap+xml")
w.WriteHeader(http.StatusOK)
w.Write([]byte(realResponse))
}))
defer server.Close()
client, err := NewClient(server.URL, WithCredentials("service", "Service.1234"))
if err != nil {
t.Fatalf("NewClient() failed: %v", err)
}
client.mediaEndpoint = server.URL
ctx := context.Background()
config, err := client.GetVideoEncoderConfiguration(ctx, "EncCfg_L1S1")
if err != nil {
t.Fatalf("GetVideoEncoderConfiguration() failed: %v", err)
}
// Validate response matches real camera
if config.Token != "EncCfg_L1S1" {
t.Errorf("Expected token=EncCfg_L1S1 (Bosch FLEXIDOME), got %s", config.Token)
}
if config.Name != "Balanced 2 MP" {
t.Errorf("Expected name=Balanced 2 MP (Bosch FLEXIDOME), got %s", config.Name)
}
if config.Encoding != "H264" {
t.Errorf("Expected encoding=H264 (Bosch FLEXIDOME), got %s", config.Encoding)
}
if config.Resolution.Width != 1920 {
t.Errorf("Expected width=1920 (Bosch FLEXIDOME), got %d", config.Resolution.Width)
}
if config.Resolution.Height != 1080 {
t.Errorf("Expected height=1080 (Bosch FLEXIDOME), got %d", config.Resolution.Height)
}
if config.RateControl.FrameRateLimit != 30 {
t.Errorf("Expected FrameRateLimit=30 (Bosch FLEXIDOME), got %d", config.RateControl.FrameRateLimit)
}
if config.RateControl.BitrateLimit != 5200 {
t.Errorf("Expected BitrateLimit=5200 (Bosch FLEXIDOME), got %d", config.RateControl.BitrateLimit)
}
}
// TestGetVideoEncoderConfigurationOptions_Bosch tests GetVideoEncoderConfigurationOptions with real camera response.
func TestGetVideoEncoderConfigurationOptions_Bosch(t *testing.T) {
// Real SOAP response from Bosch FLEXIDOME indoor 5100i IR (FW: 8.71.0066)
realResponse := `
0
100
1920
1080
1
255
1
30
1
1
Main
`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("Failed to read request body: %v", err)
}
bodyStr := string(body)
if !strings.Contains(bodyStr, "GetVideoEncoderConfigurationOptions") {
t.Errorf("Request should contain GetVideoEncoderConfigurationOptions, got: %s", bodyStr)
}
w.Header().Set("Content-Type", "application/soap+xml")
w.WriteHeader(http.StatusOK)
w.Write([]byte(realResponse))
}))
defer server.Close()
client, err := NewClient(server.URL, WithCredentials("service", "Service.1234"))
if err != nil {
t.Fatalf("NewClient() failed: %v", err)
}
client.mediaEndpoint = server.URL
ctx := context.Background()
options, err := client.GetVideoEncoderConfigurationOptions(ctx, "EncCfg_L1S1")
if err != nil {
t.Fatalf("GetVideoEncoderConfigurationOptions() failed: %v", err)
}
// Validate response matches real camera
if options.QualityRange == nil {
t.Fatal("Expected QualityRange from Bosch FLEXIDOME")
}
if options.QualityRange.Min != 0 || options.QualityRange.Max != 100 {
t.Errorf("Expected QualityRange 0-100 (Bosch FLEXIDOME), got %f-%f", options.QualityRange.Min, options.QualityRange.Max)
}
if options.H264 == nil {
t.Fatal("Expected H264 options from Bosch FLEXIDOME")
}
if len(options.H264.ResolutionsAvailable) == 0 {
t.Fatal("Expected at least one resolution from Bosch FLEXIDOME")
}
if options.H264.ResolutionsAvailable[0].Width != 1920 {
t.Errorf("Expected resolution width=1920 (Bosch FLEXIDOME), got %d", options.H264.ResolutionsAvailable[0].Width)
}
if options.H264.FrameRateRange.Min != 1 || options.H264.FrameRateRange.Max != 30 {
t.Errorf("Expected FrameRateRange 1-30 (Bosch FLEXIDOME), got %f-%f", options.H264.FrameRateRange.Min, options.H264.FrameRateRange.Max)
}
if len(options.H264.H264ProfilesSupported) == 0 || options.H264.H264ProfilesSupported[0] != "Main" {
t.Errorf("Expected H264 profile=Main (Bosch FLEXIDOME), got %v", options.H264.H264ProfilesSupported)
}
}
// TestGetAudioEncoderConfigurationOptions_Bosch tests GetAudioEncoderConfigurationOptions with real camera response.
func TestGetAudioEncoderConfigurationOptions_Bosch(t *testing.T) {
// Real SOAP response from Bosch FLEXIDOME indoor 5100i IR (FW: 8.71.0066)
realResponse := `
`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("Failed to read request body: %v", err)
}
bodyStr := string(body)
if !strings.Contains(bodyStr, "GetAudioEncoderConfigurationOptions") {
t.Errorf("Request should contain GetAudioEncoderConfigurationOptions, got: %s", bodyStr)
}
w.Header().Set("Content-Type", "application/soap+xml")
w.WriteHeader(http.StatusOK)
w.Write([]byte(realResponse))
}))
defer server.Close()
client, err := NewClient(server.URL, WithCredentials("service", "Service.1234"))
if err != nil {
t.Fatalf("NewClient() failed: %v", err)
}
client.mediaEndpoint = server.URL
ctx := context.Background()
options, err := client.GetAudioEncoderConfigurationOptions(ctx, "", "")
if err != nil {
t.Fatalf("GetAudioEncoderConfigurationOptions() failed: %v", err)
}
// Validate response - Bosch FLEXIDOME returns empty options
if options == nil {
t.Fatal("Expected options struct from Bosch FLEXIDOME")
}
}
// TestGetAudioOutputConfigurationOptions_Bosch tests GetAudioOutputConfigurationOptions with real camera response.
func TestGetAudioOutputConfigurationOptions_Bosch(t *testing.T) {
// Real SOAP response from Bosch FLEXIDOME indoor 5100i IR (FW: 8.71.0066)
realResponse := `
AudioOut 1
`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("Failed to read request body: %v", err)
}
bodyStr := string(body)
if !strings.Contains(bodyStr, "GetAudioOutputConfigurationOptions") {
t.Errorf("Request should contain GetAudioOutputConfigurationOptions, got: %s", bodyStr)
}
w.Header().Set("Content-Type", "application/soap+xml")
w.WriteHeader(http.StatusOK)
w.Write([]byte(realResponse))
}))
defer server.Close()
client, err := NewClient(server.URL, WithCredentials("service", "Service.1234"))
if err != nil {
t.Fatalf("NewClient() failed: %v", err)
}
client.mediaEndpoint = server.URL
ctx := context.Background()
options, err := client.GetAudioOutputConfigurationOptions(ctx, "")
if err != nil {
t.Fatalf("GetAudioOutputConfigurationOptions() failed: %v", err)
}
// Validate response matches real camera
if len(options.OutputTokensAvailable) == 0 {
t.Fatal("Expected at least one output token from Bosch FLEXIDOME")
}
if options.OutputTokensAvailable[0] != "AudioOut 1" {
t.Errorf("Expected AudioOut 1 (Bosch FLEXIDOME), got %s", options.OutputTokensAvailable[0])
}
}
// TestGetMetadataConfigurationOptions_Bosch tests GetMetadataConfigurationOptions with real camera response.
func TestGetMetadataConfigurationOptions_Bosch(t *testing.T) {
// Real SOAP response from Bosch FLEXIDOME indoor 5100i IR (FW: 8.71.0066)
realResponse := `
false
false
`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("Failed to read request body: %v", err)
}
bodyStr := string(body)
if !strings.Contains(bodyStr, "GetMetadataConfigurationOptions") {
t.Errorf("Request should contain GetMetadataConfigurationOptions, got: %s", bodyStr)
}
w.Header().Set("Content-Type", "application/soap+xml")
w.WriteHeader(http.StatusOK)
w.Write([]byte(realResponse))
}))
defer server.Close()
client, err := NewClient(server.URL, WithCredentials("service", "Service.1234"))
if err != nil {
t.Fatalf("NewClient() failed: %v", err)
}
client.mediaEndpoint = server.URL
ctx := context.Background()
options, err := client.GetMetadataConfigurationOptions(ctx, "", "")
if err != nil {
t.Fatalf("GetMetadataConfigurationOptions() failed: %v", err)
}
// Validate response matches real camera
if options.PTZStatusFilterOptions == nil {
t.Fatal("Expected PTZStatusFilterOptions from Bosch FLEXIDOME")
}
if options.PTZStatusFilterOptions.Status != false {
t.Error("Expected Status=false from Bosch FLEXIDOME")
}
if options.PTZStatusFilterOptions.Position != false {
t.Error("Expected Position=false from Bosch FLEXIDOME")
}
}
// TestGetAudioDecoderConfigurationOptions_Bosch tests GetAudioDecoderConfigurationOptions with real camera response.
func TestGetAudioDecoderConfigurationOptions_Bosch(t *testing.T) {
// Real SOAP response from Bosch FLEXIDOME indoor 5100i IR (FW: 8.71.0066)
realResponse := `
`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("Failed to read request body: %v", err)
}
bodyStr := string(body)
if !strings.Contains(bodyStr, "GetAudioDecoderConfigurationOptions") {
t.Errorf("Request should contain GetAudioDecoderConfigurationOptions, got: %s", bodyStr)
}
w.Header().Set("Content-Type", "application/soap+xml")
w.WriteHeader(http.StatusOK)
w.Write([]byte(realResponse))
}))
defer server.Close()
client, err := NewClient(server.URL, WithCredentials("service", "Service.1234"))
if err != nil {
t.Fatalf("NewClient() failed: %v", err)
}
client.mediaEndpoint = server.URL
ctx := context.Background()
options, err := client.GetAudioDecoderConfigurationOptions(ctx, "")
if err != nil {
t.Fatalf("GetAudioDecoderConfigurationOptions() failed: %v", err)
}
// Validate response matches real camera
if options == nil {
t.Fatal("Expected options from Bosch FLEXIDOME")
}
if options.G711DecOptions == nil {
t.Error("Expected G711DecOptions from Bosch FLEXIDOME")
}
}
// TestSetSynchronizationPoint_Bosch tests SetSynchronizationPoint with real camera response.
func TestSetSynchronizationPoint_Bosch(t *testing.T) {
// Real SOAP response from Bosch FLEXIDOME indoor 5100i IR (FW: 8.71.0066)
realResponse := `
`
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("Failed to read request body: %v", err)
}
bodyStr := string(body)
if !strings.Contains(bodyStr, "SetSynchronizationPoint") {
t.Errorf("Request should contain SetSynchronizationPoint, got: %s", bodyStr)
}
if !strings.Contains(bodyStr, "ProfileToken") {
t.Errorf("Request should contain ProfileToken, got: %s", bodyStr)
}
w.Header().Set("Content-Type", "application/soap+xml")
w.WriteHeader(http.StatusOK)
w.Write([]byte(realResponse))
}))
defer server.Close()
client, err := NewClient(server.URL, WithCredentials("service", "Service.1234"))
if err != nil {
t.Fatalf("NewClient() failed: %v", err)
}
client.mediaEndpoint = server.URL
ctx := context.Background()
err = client.SetSynchronizationPoint(ctx, "0")
if err != nil {
t.Fatalf("SetSynchronizationPoint() failed: %v", err)
}
}