Skip to content

Commit

Permalink
Added custom Marshaller for Device struct, since some IoT-Agent versi…
Browse files Browse the repository at this point in the history
…ons don't exccept a string as a ExplicitAttrs
  • Loading branch information
fbuedding committed Mar 29, 2024
1 parent 2e83ce1 commit 2782bcc
Show file tree
Hide file tree
Showing 3 changed files with 294 additions and 1 deletion.
41 changes: 41 additions & 0 deletions iota-types.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package iotagentsdk

import (
"encoding/json"
"fmt"
"net/http"
"strings"
"time"

"github.com/niemeyer/golang/src/pkg/container/vector"
Expand Down Expand Up @@ -140,6 +143,44 @@ type Device struct {
PayloadType string `json:"payloadType,omitempty" form:"payloadType"`
}

func (d *Device) MarshalJSON() ([]byte, error) {
type Alias Device
switch v := d.ExplicitAttrs.(type) {
case string:
tmp := strings.ToLower(v)
tmp = strings.TrimSpace(tmp)
tmp = strings.Trim(tmp, "\t")
if tmp == "true" || tmp == "false" {
return json.Marshal(&struct {
ExplicitAttrs bool `json:"explicitAttrs" form:"explicitAttrs"`
*Alias
}{
ExplicitAttrs: tmp == "true",
Alias: (*Alias)(d),
})
}

return json.Marshal(&struct {
ExplicitAttrs string `json:"explicitAttrs,omitempty" form:"explicitAttrs"`
*Alias
}{
ExplicitAttrs: v,
Alias: (*Alias)(d),
})
case bool:
return json.Marshal(&struct {
ExplicitAttrs bool `json:"explicitAttrs" form:"explicitAttrs"`
*Alias
}{
ExplicitAttrs: v,
Alias: (*Alias)(d),
})

default:
return nil, fmt.Errorf("ExplicitAttrs must be a string or a bool")
}
}

type MissingFields struct {
Fields vector.StringVector
Message string
Expand Down
252 changes: 252 additions & 0 deletions iota-types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
package iotagentsdk

import (
"reflect"
"testing"
)

func TestDevice_MarshalJSON(t *testing.T) {
type fields struct {
Id DeciveId
Service string
ServicePath string
EntityName string
EntityType string
Timezone string
Timestamp *bool
Apikey Apikey
Endpoint string
Protocol string
Transport string
Attributes []Attribute
Commands []Command
Lazy []LazyAttribute
StaticAttributes []StaticAttribute
InternalAttributes []interface{}
ExplicitAttrs any
NgsiVersion string
PayloadType string
}
tests := []struct {
name string
fields fields
want []byte
wantErr bool
}{
{
name: "Test true as string",
fields: fields{
Id: "",
Service: "",
ServicePath: "",
EntityName: "",
EntityType: "",
Timezone: "",
Timestamp: nil,
Apikey: "",
Endpoint: "",
Protocol: "",
Transport: "",
Attributes: []Attribute{},
Commands: []Command{},
Lazy: []LazyAttribute{},
StaticAttributes: []StaticAttribute{},
InternalAttributes: []interface{}{},
ExplicitAttrs: "true",
NgsiVersion: "",
PayloadType: "",
},
want: []byte(`{"explicitAttrs":true}`),
wantErr: false,
},
{
name: "Test false as string",
fields: fields{
Id: "",
Service: "",
ServicePath: "",
EntityName: "",
EntityType: "",
Timezone: "",
Timestamp: nil,
Apikey: "",
Endpoint: "",
Protocol: "",
Transport: "",
Attributes: []Attribute{},
Commands: []Command{},
Lazy: []LazyAttribute{},
StaticAttributes: []StaticAttribute{},
InternalAttributes: []interface{}{},
ExplicitAttrs: "false",
NgsiVersion: "",
PayloadType: "",
},
want: []byte(`{"explicitAttrs":false}`),
wantErr: false,
},
{
name: "Test True with spaces and tabs as string",
fields: fields{
Id: "",
Service: "",
ServicePath: "",
EntityName: "",
EntityType: "",
Timezone: "",
Timestamp: nil,
Apikey: "",
Endpoint: "",
Protocol: "",
Transport: "",
Attributes: []Attribute{},
Commands: []Command{},
Lazy: []LazyAttribute{},
StaticAttributes: []StaticAttribute{},
InternalAttributes: []interface{}{},
ExplicitAttrs: " True ",
NgsiVersion: "",
PayloadType: "",
},
want: []byte(`{"explicitAttrs":true}`),
wantErr: false,
},
{
name: "test bool",
fields: fields{
Id: "",
Service: "",
ServicePath: "",
EntityName: "",
EntityType: "",
Timezone: "",
Timestamp: nil,
Apikey: "",
Endpoint: "",
Protocol: "",
Transport: "",
Attributes: []Attribute{},
Commands: []Command{},
Lazy: []LazyAttribute{},
StaticAttributes: []StaticAttribute{},
InternalAttributes: []interface{}{},
ExplicitAttrs: true,
NgsiVersion: "",
PayloadType: "",
},
want: []byte(`{"explicitAttrs":true}`),
wantErr: false,
},
{
name: "test a string which is not a bool",
fields: fields{
Id: "",
Service: "",
ServicePath: "",
EntityName: "",
EntityType: "",
Timezone: "",
Timestamp: nil,
Apikey: "",
Endpoint: "",
Protocol: "",
Transport: "",
Attributes: []Attribute{},
Commands: []Command{},
Lazy: []LazyAttribute{},
StaticAttributes: []StaticAttribute{},
InternalAttributes: []interface{}{},
ExplicitAttrs: "test",
NgsiVersion: "",
PayloadType: "",
},
want: []byte(`{"explicitAttrs":"test"}`),
wantErr: false,
},
{
name: "Test empty string",
fields: fields{
Id: "",
Service: "",
ServicePath: "",
EntityName: "",
EntityType: "",
Timezone: "",
Timestamp: nil,
Apikey: "",
Endpoint: "",
Protocol: "",
Transport: "",
Attributes: []Attribute{},
Commands: []Command{},
Lazy: []LazyAttribute{},
StaticAttributes: []StaticAttribute{},
InternalAttributes: []interface{}{},
ExplicitAttrs: "",
NgsiVersion: "",
PayloadType: "",
},
want: []byte(`{}`),
wantErr: false,
},
{
name: "Test wrong type",
fields: fields{
Id: "",
Service: "",
ServicePath: "",
EntityName: "",
EntityType: "",
Timezone: "",
Timestamp: nil,
Apikey: "",
Endpoint: "",
Protocol: "",
Transport: "",
Attributes: []Attribute{},
Commands: []Command{},
Lazy: []LazyAttribute{},
StaticAttributes: []StaticAttribute{},
InternalAttributes: []interface{}{},
ExplicitAttrs: 1,
NgsiVersion: "",
PayloadType: "",
},
want: nil,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
d := &Device{
Id: tt.fields.Id,
Service: tt.fields.Service,
ServicePath: tt.fields.ServicePath,
EntityName: tt.fields.EntityName,
EntityType: tt.fields.EntityType,
Timezone: tt.fields.Timezone,
Timestamp: tt.fields.Timestamp,
Apikey: tt.fields.Apikey,
Endpoint: tt.fields.Endpoint,
Protocol: tt.fields.Protocol,
Transport: tt.fields.Transport,
Attributes: tt.fields.Attributes,
Commands: tt.fields.Commands,
Lazy: tt.fields.Lazy,
StaticAttributes: tt.fields.StaticAttributes,
InternalAttributes: tt.fields.InternalAttributes,
ExplicitAttrs: tt.fields.ExplicitAttrs,
NgsiVersion: tt.fields.NgsiVersion,
PayloadType: tt.fields.PayloadType,
}
got, err := d.MarshalJSON()
if (err != nil) != tt.wantErr {
t.Errorf("Device.MarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("Device.MarshalJSON() = %v, want %v", string(got), string(tt.want))
}
})
}
}
2 changes: 1 addition & 1 deletion main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func TestMain(m *testing.M) {
Lazy: []i.LazyAttribute{},
StaticAttributes: []i.StaticAttribute{},
InternalAttributes: []interface{}{},
ExplicitAttrs: true,
ExplicitAttrs: "true",
NgsiVersion: "",
PayloadType: "",
}
Expand Down

0 comments on commit 2782bcc

Please sign in to comment.