Add camera test framework and initial tests for Bosch FLEXIDOME indoor 5100i IR
- Introduced a new directory `testdata/captures/` containing captured XML archives and README documentation for the camera test framework. - Added a mock server implementation to replay captured SOAP responses for testing. - Created automated tests for Bosch FLEXIDOME indoor 5100i IR using captured responses, validating device information, system date and time, capabilities, and profiles. - Implemented enhanced device features tests, covering hostname, DNS, NTP, network interfaces, scopes, and user management. - Added support for enhanced media and imaging features, including video and audio sources, and imaging options. - Updated types to include new configurations and options for network, imaging, and device capabilities.
This commit is contained in:
@@ -35,7 +35,7 @@ func (c *Client) GetDeviceInformation(ctx context.Context) (*DeviceInformation,
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetDeviceInformation failed: %w", err)
|
||||
}
|
||||
@@ -129,7 +129,7 @@ func (c *Client) GetCapabilities(ctx context.Context) (*Capabilities, error) {
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetCapabilities failed: %w", err)
|
||||
}
|
||||
@@ -250,7 +250,7 @@ func (c *Client) SystemReboot(ctx context.Context) (string, error) {
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return "", fmt.Errorf("SystemReboot failed: %w", err)
|
||||
}
|
||||
@@ -273,10 +273,432 @@ func (c *Client) GetSystemDateAndTime(ctx context.Context) (interface{}, error)
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetSystemDateAndTime failed: %w", err)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetHostname retrieves the device's hostname
|
||||
func (c *Client) GetHostname(ctx context.Context) (*HostnameInformation, error) {
|
||||
type GetHostname struct {
|
||||
XMLName xml.Name `xml:"tds:GetHostname"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
}
|
||||
|
||||
type GetHostnameResponse struct {
|
||||
XMLName xml.Name `xml:"GetHostnameResponse"`
|
||||
HostnameInformation struct {
|
||||
FromDHCP bool `xml:"FromDHCP"`
|
||||
Name string `xml:"Name"`
|
||||
} `xml:"HostnameInformation"`
|
||||
}
|
||||
|
||||
req := GetHostname{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
|
||||
var resp GetHostnameResponse
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetHostname failed: %w", err)
|
||||
}
|
||||
|
||||
return &HostnameInformation{
|
||||
FromDHCP: resp.HostnameInformation.FromDHCP,
|
||||
Name: resp.HostnameInformation.Name,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SetHostname sets the device's hostname
|
||||
func (c *Client) SetHostname(ctx context.Context, name string) error {
|
||||
type SetHostname struct {
|
||||
XMLName xml.Name `xml:"tds:SetHostname"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
Name string `xml:"tds:Name"`
|
||||
}
|
||||
|
||||
req := SetHostname{
|
||||
Xmlns: deviceNamespace,
|
||||
Name: name,
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
return fmt.Errorf("SetHostname failed: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetDNS retrieves DNS configuration
|
||||
func (c *Client) GetDNS(ctx context.Context) (*DNSInformation, error) {
|
||||
type GetDNS struct {
|
||||
XMLName xml.Name `xml:"tds:GetDNS"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
}
|
||||
|
||||
type GetDNSResponse struct {
|
||||
XMLName xml.Name `xml:"GetDNSResponse"`
|
||||
DNSInformation struct {
|
||||
FromDHCP bool `xml:"FromDHCP"`
|
||||
SearchDomain []string `xml:"SearchDomain"`
|
||||
DNSFromDHCP []struct {
|
||||
Type string `xml:"Type"`
|
||||
IPv4Address string `xml:"IPv4Address"`
|
||||
} `xml:"DNSFromDHCP"`
|
||||
DNSManual []struct {
|
||||
Type string `xml:"Type"`
|
||||
IPv4Address string `xml:"IPv4Address"`
|
||||
} `xml:"DNSManual"`
|
||||
} `xml:"DNSInformation"`
|
||||
}
|
||||
|
||||
req := GetDNS{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
|
||||
var resp GetDNSResponse
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetDNS failed: %w", err)
|
||||
}
|
||||
|
||||
dns := &DNSInformation{
|
||||
FromDHCP: resp.DNSInformation.FromDHCP,
|
||||
SearchDomain: resp.DNSInformation.SearchDomain,
|
||||
}
|
||||
|
||||
for _, d := range resp.DNSInformation.DNSFromDHCP {
|
||||
dns.DNSFromDHCP = append(dns.DNSFromDHCP, IPAddress{
|
||||
Type: d.Type,
|
||||
IPv4Address: d.IPv4Address,
|
||||
})
|
||||
}
|
||||
|
||||
for _, d := range resp.DNSInformation.DNSManual {
|
||||
dns.DNSManual = append(dns.DNSManual, IPAddress{
|
||||
Type: d.Type,
|
||||
IPv4Address: d.IPv4Address,
|
||||
})
|
||||
}
|
||||
|
||||
return dns, nil
|
||||
}
|
||||
|
||||
// GetNTP retrieves NTP configuration
|
||||
func (c *Client) GetNTP(ctx context.Context) (*NTPInformation, error) {
|
||||
type GetNTP struct {
|
||||
XMLName xml.Name `xml:"tds:GetNTP"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
}
|
||||
|
||||
type GetNTPResponse struct {
|
||||
XMLName xml.Name `xml:"GetNTPResponse"`
|
||||
NTPInformation struct {
|
||||
FromDHCP bool `xml:"FromDHCP"`
|
||||
NTPFromDHCP []struct {
|
||||
Type string `xml:"Type"`
|
||||
IPv4Address string `xml:"IPv4Address"`
|
||||
DNSname string `xml:"DNSname"`
|
||||
} `xml:"NTPFromDHCP"`
|
||||
NTPManual []struct {
|
||||
Type string `xml:"Type"`
|
||||
IPv4Address string `xml:"IPv4Address"`
|
||||
DNSname string `xml:"DNSname"`
|
||||
} `xml:"NTPManual"`
|
||||
} `xml:"NTPInformation"`
|
||||
}
|
||||
|
||||
req := GetNTP{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
|
||||
var resp GetNTPResponse
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetNTP failed: %w", err)
|
||||
}
|
||||
|
||||
ntp := &NTPInformation{
|
||||
FromDHCP: resp.NTPInformation.FromDHCP,
|
||||
}
|
||||
|
||||
for _, n := range resp.NTPInformation.NTPFromDHCP {
|
||||
ntp.NTPFromDHCP = append(ntp.NTPFromDHCP, NetworkHost{
|
||||
Type: n.Type,
|
||||
IPv4Address: n.IPv4Address,
|
||||
DNSname: n.DNSname,
|
||||
})
|
||||
}
|
||||
|
||||
for _, n := range resp.NTPInformation.NTPManual {
|
||||
ntp.NTPManual = append(ntp.NTPManual, NetworkHost{
|
||||
Type: n.Type,
|
||||
IPv4Address: n.IPv4Address,
|
||||
DNSname: n.DNSname,
|
||||
})
|
||||
}
|
||||
|
||||
return ntp, nil
|
||||
}
|
||||
|
||||
// GetNetworkInterfaces retrieves network interface configuration
|
||||
func (c *Client) GetNetworkInterfaces(ctx context.Context) ([]*NetworkInterface, error) {
|
||||
type GetNetworkInterfaces struct {
|
||||
XMLName xml.Name `xml:"tds:GetNetworkInterfaces"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
}
|
||||
|
||||
type GetNetworkInterfacesResponse struct {
|
||||
XMLName xml.Name `xml:"GetNetworkInterfacesResponse"`
|
||||
NetworkInterfaces []struct {
|
||||
Token string `xml:"token,attr"`
|
||||
Enabled bool `xml:"Enabled"`
|
||||
Info struct {
|
||||
Name string `xml:"Name"`
|
||||
HwAddress string `xml:"HwAddress"`
|
||||
MTU int `xml:"MTU"`
|
||||
} `xml:"Info"`
|
||||
IPv4 struct {
|
||||
Enabled bool `xml:"Enabled"`
|
||||
Config struct {
|
||||
Manual []struct {
|
||||
Address string `xml:"Address"`
|
||||
PrefixLength int `xml:"PrefixLength"`
|
||||
} `xml:"Manual"`
|
||||
DHCP bool `xml:"DHCP"`
|
||||
} `xml:"Config"`
|
||||
} `xml:"IPv4"`
|
||||
} `xml:"NetworkInterfaces"`
|
||||
}
|
||||
|
||||
req := GetNetworkInterfaces{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
|
||||
var resp GetNetworkInterfacesResponse
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetNetworkInterfaces failed: %w", err)
|
||||
}
|
||||
|
||||
interfaces := make([]*NetworkInterface, len(resp.NetworkInterfaces))
|
||||
for i, iface := range resp.NetworkInterfaces {
|
||||
ni := &NetworkInterface{
|
||||
Token: iface.Token,
|
||||
Enabled: iface.Enabled,
|
||||
Info: NetworkInterfaceInfo{
|
||||
Name: iface.Info.Name,
|
||||
HwAddress: iface.Info.HwAddress,
|
||||
MTU: iface.Info.MTU,
|
||||
},
|
||||
}
|
||||
|
||||
if iface.IPv4.Enabled {
|
||||
ni.IPv4 = &IPv4NetworkInterface{
|
||||
Enabled: iface.IPv4.Enabled,
|
||||
Config: IPv4Configuration{
|
||||
DHCP: iface.IPv4.Config.DHCP,
|
||||
},
|
||||
}
|
||||
|
||||
for _, m := range iface.IPv4.Config.Manual {
|
||||
ni.IPv4.Config.Manual = append(ni.IPv4.Config.Manual, PrefixedIPv4Address{
|
||||
Address: m.Address,
|
||||
PrefixLength: m.PrefixLength,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
interfaces[i] = ni
|
||||
}
|
||||
|
||||
return interfaces, nil
|
||||
}
|
||||
|
||||
// GetScopes retrieves configured scopes
|
||||
func (c *Client) GetScopes(ctx context.Context) ([]*Scope, error) {
|
||||
type GetScopes struct {
|
||||
XMLName xml.Name `xml:"tds:GetScopes"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
}
|
||||
|
||||
type GetScopesResponse struct {
|
||||
XMLName xml.Name `xml:"GetScopesResponse"`
|
||||
Scopes []struct {
|
||||
ScopeDef string `xml:"ScopeDef"`
|
||||
ScopeItem string `xml:"ScopeItem"`
|
||||
} `xml:"Scopes"`
|
||||
}
|
||||
|
||||
req := GetScopes{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
|
||||
var resp GetScopesResponse
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetScopes failed: %w", err)
|
||||
}
|
||||
|
||||
scopes := make([]*Scope, len(resp.Scopes))
|
||||
for i, s := range resp.Scopes {
|
||||
scopes[i] = &Scope{
|
||||
ScopeDef: s.ScopeDef,
|
||||
ScopeItem: s.ScopeItem,
|
||||
}
|
||||
}
|
||||
|
||||
return scopes, nil
|
||||
}
|
||||
|
||||
// GetUsers retrieves user accounts
|
||||
func (c *Client) GetUsers(ctx context.Context) ([]*User, error) {
|
||||
type GetUsers struct {
|
||||
XMLName xml.Name `xml:"tds:GetUsers"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
}
|
||||
|
||||
type GetUsersResponse struct {
|
||||
XMLName xml.Name `xml:"GetUsersResponse"`
|
||||
User []struct {
|
||||
Username string `xml:"Username"`
|
||||
UserLevel string `xml:"UserLevel"`
|
||||
} `xml:"User"`
|
||||
}
|
||||
|
||||
req := GetUsers{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
|
||||
var resp GetUsersResponse
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, &resp); err != nil {
|
||||
return nil, fmt.Errorf("GetUsers failed: %w", err)
|
||||
}
|
||||
|
||||
users := make([]*User, len(resp.User))
|
||||
for i, u := range resp.User {
|
||||
users[i] = &User{
|
||||
Username: u.Username,
|
||||
UserLevel: u.UserLevel,
|
||||
}
|
||||
}
|
||||
|
||||
return users, nil
|
||||
}
|
||||
|
||||
// CreateUsers creates new user accounts
|
||||
func (c *Client) CreateUsers(ctx context.Context, users []*User) error {
|
||||
type CreateUsers struct {
|
||||
XMLName xml.Name `xml:"tds:CreateUsers"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
User []struct {
|
||||
Username string `xml:"tds:Username"`
|
||||
Password string `xml:"tds:Password"`
|
||||
UserLevel string `xml:"tds:UserLevel"`
|
||||
} `xml:"tds:User"`
|
||||
}
|
||||
|
||||
req := CreateUsers{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
|
||||
for _, user := range users {
|
||||
req.User = append(req.User, struct {
|
||||
Username string `xml:"tds:Username"`
|
||||
Password string `xml:"tds:Password"`
|
||||
UserLevel string `xml:"tds:UserLevel"`
|
||||
}{
|
||||
Username: user.Username,
|
||||
Password: user.Password,
|
||||
UserLevel: user.UserLevel,
|
||||
})
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
return fmt.Errorf("CreateUsers failed: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteUsers deletes user accounts
|
||||
func (c *Client) DeleteUsers(ctx context.Context, usernames []string) error {
|
||||
type DeleteUsers struct {
|
||||
XMLName xml.Name `xml:"tds:DeleteUsers"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
Username []string `xml:"tds:Username"`
|
||||
}
|
||||
|
||||
req := DeleteUsers{
|
||||
Xmlns: deviceNamespace,
|
||||
Username: usernames,
|
||||
}
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
return fmt.Errorf("DeleteUsers failed: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetUser modifies an existing user account
|
||||
func (c *Client) SetUser(ctx context.Context, user *User) error {
|
||||
type SetUser struct {
|
||||
XMLName xml.Name `xml:"tds:SetUser"`
|
||||
Xmlns string `xml:"xmlns:tds,attr"`
|
||||
User struct {
|
||||
Username string `xml:"tds:Username"`
|
||||
Password *string `xml:"tds:Password,omitempty"`
|
||||
UserLevel string `xml:"tds:UserLevel"`
|
||||
} `xml:"tds:User"`
|
||||
}
|
||||
|
||||
req := SetUser{
|
||||
Xmlns: deviceNamespace,
|
||||
}
|
||||
req.User.Username = user.Username
|
||||
if user.Password != "" {
|
||||
req.User.Password = &user.Password
|
||||
}
|
||||
req.User.UserLevel = user.UserLevel
|
||||
|
||||
username, password := c.GetCredentials()
|
||||
soapClient := soap.NewClient(c.httpClient, username, password)
|
||||
|
||||
if err := soapClient.Call(ctx, c.endpoint, "", req, nil); err != nil {
|
||||
return fmt.Errorf("SetUser failed: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user