refactor: improve media service client methods and clean up test files
- Introduced helper methods `getMediaEndpoint` and `getMediaSoapClient` in the media client for better code reuse and clarity. - Updated various media service methods to utilize the new helper methods, enhancing maintainability. - Cleaned up test files by standardizing formatting and removing unnecessary blank lines for improved readability.
This commit is contained in:
@@ -11,6 +11,20 @@ import (
|
||||
// Media service namespace
|
||||
const mediaNamespace = "http://www.onvif.org/ver10/media/wsdl"
|
||||
|
||||
// getMediaEndpoint returns the media endpoint, falling back to the default endpoint if not set.
|
||||
func (c *Client) getMediaEndpoint() string {
|
||||
if c.mediaEndpoint != "" {
|
||||
return c.mediaEndpoint
|
||||
}
|
||||
return c.endpoint
|
||||
}
|
||||
|
||||
// getMediaSoapClient creates a new SOAP client for media operations.
|
||||
func (c *Client) getMediaSoapClient() *soap.Client {
|
||||
username, password := c.GetCredentials()
|
||||
return soap.NewClient(c.httpClient, username, password)
|
||||
}
|
||||
|
||||
// GetProfiles retrieves all media profiles
|
||||
func (c *Client) GetProfiles(ctx context.Context) ([]*Profile, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
@@ -2046,13 +2060,8 @@ func (c *Client) GetMetadataConfigurationOptions(ctx context.Context, configurat
|
||||
}
|
||||
|
||||
// GetAudioOutputConfiguration retrieves audio output configuration
|
||||
//
|
||||
//nolint:dupl // Similar structure to GetAudioSourceConfiguration but different types and operations
|
||||
func (c *Client) GetAudioOutputConfiguration(ctx context.Context, configurationToken string) (*AudioOutputConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetAudioOutputConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:GetAudioOutputConfiguration"`
|
||||
@@ -2076,9 +2085,7 @@ func (c *Client) GetAudioOutputConfiguration(ctx context.Context, configurationT
|
||||
}
|
||||
|
||||
var resp GetAudioOutputConfigurationResponse
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
soapClient := c.getMediaSoapClient()
|
||||
|
||||
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetAudioOutputConfiguration failed: %w", err)
|
||||
@@ -2703,10 +2710,7 @@ func (c *Client) GetVideoSourceConfiguration(ctx context.Context, configurationT
|
||||
|
||||
// GetAudioSourceConfiguration retrieves a specific audio source configuration
|
||||
func (c *Client) GetAudioSourceConfiguration(ctx context.Context, configurationToken string) (*AudioSourceConfiguration, error) {
|
||||
endpoint := c.mediaEndpoint
|
||||
if endpoint == "" {
|
||||
endpoint = c.endpoint
|
||||
}
|
||||
endpoint := c.getMediaEndpoint()
|
||||
|
||||
type GetAudioSourceConfiguration struct {
|
||||
XMLName xml.Name `xml:"trt:GetAudioSourceConfiguration"`
|
||||
@@ -2730,9 +2734,7 @@ func (c *Client) GetAudioSourceConfiguration(ctx context.Context, configurationT
|
||||
}
|
||||
|
||||
var resp GetAudioSourceConfigurationResponse
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
soapClient := c.getMediaSoapClient()
|
||||
|
||||
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetAudioSourceConfiguration failed: %w", err)
|
||||
|
||||
+1
-2
@@ -35,7 +35,7 @@ func TestGetProfiles(t *testing.T) {
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client, err := NewClient(server.URL+"/onvif/media_service")
|
||||
client, err := NewClient(server.URL + "/onvif/media_service")
|
||||
if err != nil {
|
||||
t.Fatalf("NewClient() failed: %v", err)
|
||||
}
|
||||
@@ -1487,4 +1487,3 @@ func TestGetOSDOptions(t *testing.T) {
|
||||
t.Errorf("Expected MaximumNumberOfOSDs 10, got %d", options.MaximumNumberOfOSDs)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@ func TestHandleGetDeviceInformation(t *testing.T) {
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
got string
|
||||
want string
|
||||
name string
|
||||
got string
|
||||
want string
|
||||
}{
|
||||
{"Manufacturer", deviceResp.Manufacturer, config.DeviceInfo.Manufacturer},
|
||||
{"Model", deviceResp.Model, config.DeviceInfo.Model},
|
||||
@@ -206,8 +206,8 @@ func TestCapabilitiesStructure(t *testing.T) {
|
||||
XAddr: "http://localhost:8080/onvif/media_service",
|
||||
StreamingCapabilities: &StreamingCapabilities{
|
||||
RTPMulticast: true,
|
||||
RTP_TCP: true,
|
||||
RTP_RTSP_TCP: true,
|
||||
RTP_TCP: true,
|
||||
RTP_RTSP_TCP: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -236,8 +236,8 @@ func TestMediaCapabilitiesStructure(t *testing.T) {
|
||||
XAddr: "http://localhost:8080/onvif/media_service",
|
||||
StreamingCapabilities: &StreamingCapabilities{
|
||||
RTPMulticast: true,
|
||||
RTP_TCP: true,
|
||||
RTP_RTSP_TCP: true,
|
||||
RTP_TCP: true,
|
||||
RTP_RTSP_TCP: true,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -362,8 +362,8 @@ func TestGetCapabilitiesResponse(t *testing.T) {
|
||||
XAddr: "http://localhost:8080/media",
|
||||
StreamingCapabilities: &StreamingCapabilities{
|
||||
RTPMulticast: true,
|
||||
RTP_TCP: true,
|
||||
RTP_RTSP_TCP: true,
|
||||
RTP_TCP: true,
|
||||
RTP_RTSP_TCP: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
+38
-38
@@ -217,28 +217,28 @@ func TestImagingSettings(t *testing.T) {
|
||||
|
||||
func TestBacklightCompensation(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
comp BacklightCompensation
|
||||
name string
|
||||
comp BacklightCompensation
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "Backlight ON",
|
||||
comp: BacklightCompensation{Mode: "ON", Level: 50},
|
||||
name: "Backlight ON",
|
||||
comp: BacklightCompensation{Mode: "ON", Level: 50},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "Backlight OFF",
|
||||
comp: BacklightCompensation{Mode: "OFF", Level: 0},
|
||||
name: "Backlight OFF",
|
||||
comp: BacklightCompensation{Mode: "OFF", Level: 0},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "Invalid mode",
|
||||
comp: BacklightCompensation{Mode: "INVALID", Level: 50},
|
||||
name: "Invalid mode",
|
||||
comp: BacklightCompensation{Mode: "INVALID", Level: 50},
|
||||
expectValid: false,
|
||||
},
|
||||
{
|
||||
name: "Level out of range",
|
||||
comp: BacklightCompensation{Mode: "ON", Level: 150},
|
||||
name: "Level out of range",
|
||||
comp: BacklightCompensation{Mode: "ON", Level: 150},
|
||||
expectValid: false,
|
||||
},
|
||||
}
|
||||
@@ -256,27 +256,27 @@ func TestBacklightCompensation(t *testing.T) {
|
||||
|
||||
func TestExposureSettings(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
exposure ExposureSettings
|
||||
name string
|
||||
exposure ExposureSettings
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "Valid AUTO exposure",
|
||||
exposure: ExposureSettings{
|
||||
Mode: "AUTO",
|
||||
Priority: "FrameRate",
|
||||
Mode: "AUTO",
|
||||
Priority: "FrameRate",
|
||||
MinExposure: 1,
|
||||
MaxExposure: 10000,
|
||||
Gain: 50,
|
||||
Gain: 50,
|
||||
},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "Valid MANUAL exposure",
|
||||
exposure: ExposureSettings{
|
||||
Mode: "MANUAL",
|
||||
Mode: "MANUAL",
|
||||
ExposureTime: 100,
|
||||
Gain: 50,
|
||||
Gain: 50,
|
||||
},
|
||||
expectValid: true,
|
||||
},
|
||||
@@ -301,17 +301,17 @@ func TestExposureSettings(t *testing.T) {
|
||||
|
||||
func TestFocusSettings(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
focus FocusSettings
|
||||
name string
|
||||
focus FocusSettings
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "Valid AUTO focus",
|
||||
focus: FocusSettings{
|
||||
AutoFocusMode: "AUTO",
|
||||
DefaultSpeed: 0.5,
|
||||
NearLimit: 0,
|
||||
FarLimit: 1,
|
||||
DefaultSpeed: 0.5,
|
||||
NearLimit: 0,
|
||||
FarLimit: 1,
|
||||
},
|
||||
expectValid: true,
|
||||
},
|
||||
@@ -319,8 +319,8 @@ func TestFocusSettings(t *testing.T) {
|
||||
name: "Valid MANUAL focus",
|
||||
focus: FocusSettings{
|
||||
AutoFocusMode: "MANUAL",
|
||||
DefaultSpeed: 0.5,
|
||||
CurrentPos: 0.5,
|
||||
DefaultSpeed: 0.5,
|
||||
CurrentPos: 0.5,
|
||||
},
|
||||
expectValid: true,
|
||||
},
|
||||
@@ -345,14 +345,14 @@ func TestFocusSettings(t *testing.T) {
|
||||
|
||||
func TestWhiteBalanceSettings(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
name string
|
||||
whiteBalance WhiteBalanceSettings
|
||||
expectValid bool
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "Valid AUTO white balance",
|
||||
whiteBalance: WhiteBalanceSettings{
|
||||
Mode: "AUTO",
|
||||
Mode: "AUTO",
|
||||
CrGain: 128,
|
||||
CbGain: 128,
|
||||
},
|
||||
@@ -361,7 +361,7 @@ func TestWhiteBalanceSettings(t *testing.T) {
|
||||
{
|
||||
name: "Valid MANUAL white balance",
|
||||
whiteBalance: WhiteBalanceSettings{
|
||||
Mode: "MANUAL",
|
||||
Mode: "MANUAL",
|
||||
CrGain: 100,
|
||||
CbGain: 120,
|
||||
},
|
||||
@@ -370,7 +370,7 @@ func TestWhiteBalanceSettings(t *testing.T) {
|
||||
{
|
||||
name: "Gain out of range",
|
||||
whiteBalance: WhiteBalanceSettings{
|
||||
Mode: "AUTO",
|
||||
Mode: "AUTO",
|
||||
CrGain: 300,
|
||||
CbGain: 128,
|
||||
},
|
||||
@@ -393,23 +393,23 @@ func TestWhiteBalanceSettings(t *testing.T) {
|
||||
|
||||
func TestWideDynamicRange(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
wdr WDRSettings
|
||||
name string
|
||||
wdr WDRSettings
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "WDR ON",
|
||||
wdr: WDRSettings{Mode: "ON", Level: 50},
|
||||
name: "WDR ON",
|
||||
wdr: WDRSettings{Mode: "ON", Level: 50},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "WDR OFF",
|
||||
wdr: WDRSettings{Mode: "OFF", Level: 0},
|
||||
name: "WDR OFF",
|
||||
wdr: WDRSettings{Mode: "OFF", Level: 0},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "Invalid mode",
|
||||
wdr: WDRSettings{Mode: "INVALID", Level: 50},
|
||||
name: "Invalid mode",
|
||||
wdr: WDRSettings{Mode: "INVALID", Level: 50},
|
||||
expectValid: false,
|
||||
},
|
||||
}
|
||||
@@ -509,7 +509,7 @@ func TestSetImagingSettingsEdgeCases(t *testing.T) {
|
||||
}
|
||||
|
||||
resp, err := server.HandleSetImagingSettings(&setReq)
|
||||
|
||||
|
||||
if err == nil && resp != nil {
|
||||
t.Logf("SetImagingSettings with nil settings succeeded")
|
||||
}
|
||||
|
||||
+27
-27
@@ -174,9 +174,9 @@ func TestVideoEncoderConfigurationStructure(t *testing.T) {
|
||||
Quality: 80,
|
||||
Resolution: VideoResolution{Width: 1920, Height: 1080},
|
||||
RateControl: &VideoRateControl{
|
||||
FrameRateLimit: 30,
|
||||
FrameRateLimit: 30,
|
||||
EncodingInterval: 1,
|
||||
BitrateLimit: 2048,
|
||||
BitrateLimit: 2048,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -225,28 +225,28 @@ func TestGetProfilesResponseXML(t *testing.T) {
|
||||
|
||||
func TestIntRectangle(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
rect IntRectangle
|
||||
name string
|
||||
rect IntRectangle
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "Valid rectangle",
|
||||
rect: IntRectangle{X: 0, Y: 0, Width: 100, Height: 100},
|
||||
name: "Valid rectangle",
|
||||
rect: IntRectangle{X: 0, Y: 0, Width: 100, Height: 100},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "Zero width",
|
||||
rect: IntRectangle{X: 0, Y: 0, Width: 0, Height: 100},
|
||||
name: "Zero width",
|
||||
rect: IntRectangle{X: 0, Y: 0, Width: 0, Height: 100},
|
||||
expectValid: false,
|
||||
},
|
||||
{
|
||||
name: "Zero height",
|
||||
rect: IntRectangle{X: 0, Y: 0, Width: 100, Height: 0},
|
||||
name: "Zero height",
|
||||
rect: IntRectangle{X: 0, Y: 0, Width: 100, Height: 0},
|
||||
expectValid: false,
|
||||
},
|
||||
{
|
||||
name: "Negative dimensions",
|
||||
rect: IntRectangle{X: -10, Y: -10, Width: 100, Height: 100},
|
||||
name: "Negative dimensions",
|
||||
rect: IntRectangle{X: -10, Y: -10, Width: 100, Height: 100},
|
||||
expectValid: true, // Negative coordinates may be valid
|
||||
},
|
||||
}
|
||||
@@ -263,33 +263,33 @@ func TestIntRectangle(t *testing.T) {
|
||||
|
||||
func TestVideoResolution(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
resolution VideoResolution
|
||||
name string
|
||||
resolution VideoResolution
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "1080p",
|
||||
resolution: VideoResolution{Width: 1920, Height: 1080},
|
||||
name: "1080p",
|
||||
resolution: VideoResolution{Width: 1920, Height: 1080},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "720p",
|
||||
resolution: VideoResolution{Width: 1280, Height: 720},
|
||||
name: "720p",
|
||||
resolution: VideoResolution{Width: 1280, Height: 720},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "VGA",
|
||||
resolution: VideoResolution{Width: 640, Height: 480},
|
||||
name: "VGA",
|
||||
resolution: VideoResolution{Width: 640, Height: 480},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "4K",
|
||||
resolution: VideoResolution{Width: 3840, Height: 2160},
|
||||
name: "4K",
|
||||
resolution: VideoResolution{Width: 3840, Height: 2160},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "Zero width",
|
||||
resolution: VideoResolution{Width: 0, Height: 1080},
|
||||
name: "Zero width",
|
||||
resolution: VideoResolution{Width: 0, Height: 1080},
|
||||
expectValid: false,
|
||||
},
|
||||
}
|
||||
@@ -306,9 +306,9 @@ func TestVideoResolution(t *testing.T) {
|
||||
|
||||
func TestMulticastConfiguration(t *testing.T) {
|
||||
cfg := MulticastConfiguration{
|
||||
Address: IPAddress{IPv4Address: "239.255.255.250"},
|
||||
Port: 1900,
|
||||
TTL: 128,
|
||||
Address: IPAddress{IPv4Address: "239.255.255.250"},
|
||||
Port: 1900,
|
||||
TTL: 128,
|
||||
AutoStart: true,
|
||||
}
|
||||
|
||||
|
||||
+20
-20
@@ -265,28 +265,28 @@ func _DisabledTestHandleStop(t *testing.T) {
|
||||
|
||||
func TestPTZPosition(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
position PTZPosition
|
||||
name string
|
||||
position PTZPosition
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "Valid center position",
|
||||
position: PTZPosition{Pan: 0, Tilt: 0, Zoom: 0},
|
||||
name: "Valid center position",
|
||||
position: PTZPosition{Pan: 0, Tilt: 0, Zoom: 0},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "Position with pan",
|
||||
position: PTZPosition{Pan: 45, Tilt: 0, Zoom: 0},
|
||||
name: "Position with pan",
|
||||
position: PTZPosition{Pan: 45, Tilt: 0, Zoom: 0},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "Position with zoom",
|
||||
position: PTZPosition{Pan: 0, Tilt: 0, Zoom: 5},
|
||||
name: "Position with zoom",
|
||||
position: PTZPosition{Pan: 0, Tilt: 0, Zoom: 5},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "Full position",
|
||||
position: PTZPosition{Pan: 180, Tilt: 45, Zoom: 10},
|
||||
name: "Full position",
|
||||
position: PTZPosition{Pan: 180, Tilt: 45, Zoom: 10},
|
||||
expectValid: true,
|
||||
},
|
||||
}
|
||||
@@ -328,23 +328,23 @@ func TestPTZSpeed(t *testing.T) {
|
||||
tilt := 0.5
|
||||
zoom := 0.5
|
||||
tests := []struct {
|
||||
name string
|
||||
speed PTZVector
|
||||
name string
|
||||
speed PTZVector
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "Valid speed",
|
||||
speed: PTZVector{PanTilt: &Vector2D{X: pan, Y: tilt}, Zoom: &Vector1D{X: zoom}},
|
||||
name: "Valid speed",
|
||||
speed: PTZVector{PanTilt: &Vector2D{X: pan, Y: tilt}, Zoom: &Vector1D{X: zoom}},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "High speed",
|
||||
speed: PTZVector{PanTilt: &Vector2D{X: 1.0, Y: 1.0}, Zoom: &Vector1D{X: 1.0}},
|
||||
name: "High speed",
|
||||
speed: PTZVector{PanTilt: &Vector2D{X: 1.0, Y: 1.0}, Zoom: &Vector1D{X: 1.0}},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "Zero speed",
|
||||
speed: PTZVector{PanTilt: &Vector2D{X: 0, Y: 0}, Zoom: &Vector1D{X: 0}},
|
||||
name: "Zero speed",
|
||||
speed: PTZVector{PanTilt: &Vector2D{X: 0, Y: 0}, Zoom: &Vector1D{X: 0}},
|
||||
expectValid: true,
|
||||
},
|
||||
}
|
||||
@@ -438,7 +438,7 @@ func TestPTZMovementOperations(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
resp, err := tt.handler([]byte(tt.reqXML))
|
||||
|
||||
|
||||
// These may fail due to XML namespace issues, but we're testing the handler exists
|
||||
if resp == nil && err == nil {
|
||||
t.Logf("%s: got nil response and nil error", tt.name)
|
||||
@@ -501,7 +501,7 @@ func TestPTZStateTransitions(t *testing.T) {
|
||||
|
||||
// Verify position can be updated
|
||||
ptzState.LastUpdate = time.Now()
|
||||
|
||||
|
||||
updatedState, _ := server.GetPTZState(profileToken)
|
||||
if updatedState == nil {
|
||||
t.Fatal("Updated PTZ state is nil")
|
||||
|
||||
@@ -271,9 +271,9 @@ func TestGetImagingState(t *testing.T) {
|
||||
videoSourceToken := config.Profiles[0].VideoSource.Token
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
token string
|
||||
expectOk bool
|
||||
name string
|
||||
token string
|
||||
expectOk bool
|
||||
checkFunc func(*ImagingState) error
|
||||
}{
|
||||
{
|
||||
@@ -436,11 +436,11 @@ func TestServerInfoMethod(t *testing.T) {
|
||||
server, _ := New(config)
|
||||
|
||||
info := server.ServerInfo()
|
||||
|
||||
|
||||
if info == "" {
|
||||
t.Fatal("ServerInfo() returned empty string")
|
||||
}
|
||||
|
||||
|
||||
// ServerInfo returns a formatted string with server information
|
||||
if !strings.Contains(info, "127.0.0.1") && !strings.Contains(info, "localhost") {
|
||||
t.Logf("ServerInfo may not contain host: %s", info)
|
||||
|
||||
@@ -125,8 +125,8 @@ func TestExtractAction(t *testing.T) {
|
||||
handler := NewHandler("", "")
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
soapBody string
|
||||
name string
|
||||
soapBody string
|
||||
expectedAction string
|
||||
}{
|
||||
{
|
||||
|
||||
+57
-57
@@ -10,7 +10,7 @@ func TestDefaultConfig(t *testing.T) {
|
||||
config := DefaultConfig()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
name string
|
||||
checkFunc func(*Config) error
|
||||
}{
|
||||
{
|
||||
@@ -131,28 +131,28 @@ func TestDefaultConfig(t *testing.T) {
|
||||
|
||||
func TestResolution(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
resolution Resolution
|
||||
name string
|
||||
resolution Resolution
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "Valid resolution 1920x1080",
|
||||
resolution: Resolution{Width: 1920, Height: 1080},
|
||||
name: "Valid resolution 1920x1080",
|
||||
resolution: Resolution{Width: 1920, Height: 1080},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "Valid resolution 640x480",
|
||||
resolution: Resolution{Width: 640, Height: 480},
|
||||
name: "Valid resolution 640x480",
|
||||
resolution: Resolution{Width: 640, Height: 480},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "Zero width",
|
||||
resolution: Resolution{Width: 0, Height: 1080},
|
||||
name: "Zero width",
|
||||
resolution: Resolution{Width: 0, Height: 1080},
|
||||
expectValid: false,
|
||||
},
|
||||
{
|
||||
name: "Zero height",
|
||||
resolution: Resolution{Width: 1920, Height: 0},
|
||||
name: "Zero height",
|
||||
resolution: Resolution{Width: 1920, Height: 0},
|
||||
expectValid: false,
|
||||
},
|
||||
}
|
||||
@@ -160,7 +160,7 @@ func TestResolution(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if (tt.resolution.Width > 0 && tt.resolution.Height > 0) != tt.expectValid {
|
||||
t.Errorf("Resolution validation failed: Width=%d, Height=%d",
|
||||
t.Errorf("Resolution validation failed: Width=%d, Height=%d",
|
||||
tt.resolution.Width, tt.resolution.Height)
|
||||
}
|
||||
})
|
||||
@@ -219,23 +219,23 @@ func TestRange(t *testing.T) {
|
||||
|
||||
func TestBounds(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
bounds Bounds
|
||||
name string
|
||||
bounds Bounds
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "Valid bounds",
|
||||
bounds: Bounds{X: 0, Y: 0, Width: 1920, Height: 1080},
|
||||
name: "Valid bounds",
|
||||
bounds: Bounds{X: 0, Y: 0, Width: 1920, Height: 1080},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "Zero width",
|
||||
bounds: Bounds{X: 0, Y: 0, Width: 0, Height: 1080},
|
||||
name: "Zero width",
|
||||
bounds: Bounds{X: 0, Y: 0, Width: 0, Height: 1080},
|
||||
expectValid: false,
|
||||
},
|
||||
{
|
||||
name: "Negative coordinates",
|
||||
bounds: Bounds{X: -10, Y: -10, Width: 1920, Height: 1080},
|
||||
name: "Negative coordinates",
|
||||
bounds: Bounds{X: -10, Y: -10, Width: 1920, Height: 1080},
|
||||
expectValid: true, // Negative coordinates may be valid in some cases
|
||||
},
|
||||
}
|
||||
@@ -252,8 +252,8 @@ func TestBounds(t *testing.T) {
|
||||
|
||||
func TestPreset(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
preset Preset
|
||||
name string
|
||||
preset Preset
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
@@ -277,7 +277,7 @@ func TestPreset(t *testing.T) {
|
||||
name: "Preset with empty name",
|
||||
preset: Preset{
|
||||
Token: "preset_1",
|
||||
Name: "",
|
||||
Name: "",
|
||||
},
|
||||
expectValid: false,
|
||||
},
|
||||
@@ -287,7 +287,7 @@ func TestPreset(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
isValid := tt.preset.Token != "" && tt.preset.Name != ""
|
||||
if isValid != tt.expectValid {
|
||||
t.Errorf("Preset validation failed: Token=%s, Name=%s",
|
||||
t.Errorf("Preset validation failed: Token=%s, Name=%s",
|
||||
tt.preset.Token, tt.preset.Name)
|
||||
}
|
||||
})
|
||||
@@ -346,9 +346,9 @@ func TestPTZConfig(t *testing.T) {
|
||||
|
||||
func TestVideoEncoderConfig(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
name string
|
||||
encoderConfig VideoEncoderConfig
|
||||
expectValid bool
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "Valid H264 encoder",
|
||||
@@ -406,7 +406,7 @@ func TestVideoEncoderConfig(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
isValid := tt.encoderConfig.Encoding != "" &&
|
||||
isValid := tt.encoderConfig.Encoding != "" &&
|
||||
tt.encoderConfig.Quality >= 0 && tt.encoderConfig.Quality <= 100 &&
|
||||
tt.encoderConfig.Resolution.Width > 0 && tt.encoderConfig.Resolution.Height > 0
|
||||
if isValid != tt.expectValid {
|
||||
@@ -418,9 +418,9 @@ func TestVideoEncoderConfig(t *testing.T) {
|
||||
|
||||
func TestProfileConfig(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
name string
|
||||
profileConfig ProfileConfig
|
||||
expectValid bool
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "Valid profile config",
|
||||
@@ -475,7 +475,7 @@ func TestSnapshotConfig(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
snapshotConfig SnapshotConfig
|
||||
expectValid bool
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "Valid snapshot config",
|
||||
@@ -509,7 +509,7 @@ func TestSnapshotConfig(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Snapshot config is valid if it has resolution and quality when enabled
|
||||
isValid := !tt.snapshotConfig.Enabled ||
|
||||
isValid := !tt.snapshotConfig.Enabled ||
|
||||
(tt.snapshotConfig.Resolution.Width > 0 && tt.snapshotConfig.Resolution.Height > 0)
|
||||
if isValid != tt.expectValid {
|
||||
t.Errorf("Snapshot validation failed: Enabled=%v, Resolution=%dx%d",
|
||||
@@ -545,10 +545,10 @@ func TestServiceEndpoints(t *testing.T) {
|
||||
{
|
||||
name: "Default endpoints",
|
||||
config: &Config{
|
||||
Host: "192.168.1.100",
|
||||
Port: 8080,
|
||||
BasePath: "/onvif",
|
||||
SupportPTZ: true,
|
||||
Host: "192.168.1.100",
|
||||
Port: 8080,
|
||||
BasePath: "/onvif",
|
||||
SupportPTZ: true,
|
||||
SupportEvents: true,
|
||||
},
|
||||
host: "",
|
||||
@@ -557,10 +557,10 @@ func TestServiceEndpoints(t *testing.T) {
|
||||
{
|
||||
name: "Custom host",
|
||||
config: &Config{
|
||||
Host: "192.168.1.100",
|
||||
Port: 8080,
|
||||
BasePath: "/onvif",
|
||||
SupportPTZ: false,
|
||||
Host: "192.168.1.100",
|
||||
Port: 8080,
|
||||
BasePath: "/onvif",
|
||||
SupportPTZ: false,
|
||||
SupportEvents: false,
|
||||
},
|
||||
host: "custom.example.com",
|
||||
@@ -569,9 +569,9 @@ func TestServiceEndpoints(t *testing.T) {
|
||||
{
|
||||
name: "Port 80",
|
||||
config: &Config{
|
||||
Host: "localhost",
|
||||
Port: 80,
|
||||
BasePath: "/onvif",
|
||||
Host: "localhost",
|
||||
Port: 80,
|
||||
BasePath: "/onvif",
|
||||
SupportPTZ: true,
|
||||
},
|
||||
host: "",
|
||||
@@ -602,7 +602,7 @@ func TestServiceEndpoints(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
endpoints := tt.config.ServiceEndpoints(tt.host)
|
||||
|
||||
|
||||
for _, svc := range tt.expectServices {
|
||||
if _, ok := endpoints[svc]; !ok {
|
||||
t.Errorf("Missing endpoint: %s", svc)
|
||||
@@ -621,15 +621,15 @@ func TestServiceEndpoints(t *testing.T) {
|
||||
|
||||
func TestServiceEndpointsURL(t *testing.T) {
|
||||
config := &Config{
|
||||
Host: "example.com",
|
||||
Port: 9000,
|
||||
BasePath: "/services",
|
||||
SupportPTZ: true,
|
||||
Host: "example.com",
|
||||
Port: 9000,
|
||||
BasePath: "/services",
|
||||
SupportPTZ: true,
|
||||
SupportEvents: true,
|
||||
}
|
||||
|
||||
endpoints := config.ServiceEndpoints("example.com")
|
||||
|
||||
|
||||
expectedDeviceURL := "http://example.com:9000/services/device_service"
|
||||
if endpoints["device"] != expectedDeviceURL {
|
||||
t.Errorf("Device endpoint mismatch: got %s, want %s", endpoints["device"], expectedDeviceURL)
|
||||
@@ -639,27 +639,27 @@ func TestServiceEndpointsURL(t *testing.T) {
|
||||
func TestToONVIFProfile(t *testing.T) {
|
||||
profile := &ProfileConfig{
|
||||
Token: "profile_1",
|
||||
Name: "HD Profile",
|
||||
Name: "HD Profile",
|
||||
VideoSource: VideoSourceConfig{
|
||||
Token: "source_1",
|
||||
Framerate: 30,
|
||||
Token: "source_1",
|
||||
Framerate: 30,
|
||||
Resolution: Resolution{Width: 1920, Height: 1080},
|
||||
},
|
||||
VideoEncoder: VideoEncoderConfig{
|
||||
Encoding: "H264",
|
||||
Bitrate: 4096,
|
||||
Framerate: 30,
|
||||
Encoding: "H264",
|
||||
Bitrate: 4096,
|
||||
Framerate: 30,
|
||||
Resolution: Resolution{Width: 1920, Height: 1080},
|
||||
},
|
||||
Snapshot: SnapshotConfig{
|
||||
Enabled: true,
|
||||
Enabled: true,
|
||||
Resolution: Resolution{Width: 1920, Height: 1080},
|
||||
Quality: 85.0,
|
||||
Quality: 85.0,
|
||||
},
|
||||
}
|
||||
|
||||
onvifProfile := profile.ToONVIFProfile()
|
||||
|
||||
|
||||
if onvifProfile.Token != "profile_1" {
|
||||
t.Errorf("Profile token mismatch: got %s", onvifProfile.Token)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user