package rpc import ( "encoding/json" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "src.dualinventive.com/go/dinet/ditime" ) func TestSplitClassMethod(t *testing.T) { // On a single invoke class method are cached m := &Msg{ClassMethod: ClassMethodConfigSet} assert.Equal(t, ClassConfig, m.Class()) assert.Equal(t, "set", m.method) // Try to get method and check if class is also cached m.class = "" m.method = "" assert.Equal(t, "set", m.Method()) assert.Equal(t, "config", m.class) m.class = "" m.method = "" // Verify submethods are part of the method string m = &Msg{ClassMethod: ClassMethodDeviceUserData} assert.Equal(t, ClassDevice, m.Class()) assert.Equal(t, "user:data", m.Method()) } func TestError(t *testing.T) { // Empty message is no not an error m := &Msg{} assert.False(t, m.IsError()) // Error set when the message is not MsgTypeReply is not an error m.Error = GetError(ETimeout) assert.False(t, m.IsError()) // Set message type to MsgTypeReply m.Type = MsgTypeReply assert.True(t, m.IsError()) } func TestString(t *testing.T) { // Zero message m := &Msg{} assert.Equal(t, "Jan 1 01:00:00.000 ", m.String()) // Message with DeviceUID, MsgTypeRequest, Time zero uid, err := GenerateDeviceUID(DeviceUIDPrefixMock, "1") assert.Nil(t, err) m.DeviceUID = uid m.Type = MsgTypeReply assert.Equal(t, "Jan 1 01:00:00.000 device:ff000000000000000000000000000001 rep ", m.String()) m.ClassMethod = ClassMethodSensorData m.DeviceUID = "" m.ProjectID = 10 m.UserID = 11 m.Type = MsgTypePublish m.Time = 1234567890 m.Result = NewResult([]map[string]string{{"hoi": "hallo"}}) assert.Equal(t, `Jan 15 07:56:07.890 project:10 user:11 pub sensor:data [{"hoi":"hallo"}]`, m.String()) m.Type = MsgTypeRequest assert.Equal(t, `Jan 15 07:56:07.890 project:10 user:11 req sensor:data `, m.String()) } func TestValid(t *testing.T) { testUID := "01234567890123456789012345678901" tests := []struct { name string msg *Msg err error }{ { "Missing dinet rpc", &Msg{ ID: 1, Time: ditime.Now(), Type: MsgTypeRequest, ClassMethod: ClassMethodDevicePing, DeviceUID: testUID, }, ErrMsgInvalidDinetrpc, }, { "Missing Dev, proj and user ID", &Msg{ Dinetrpc: CurrentDinetrpc, ID: 1, Time: ditime.Now(), Type: MsgTypeRequest, ClassMethod: ClassMethodDevicePing, }, ErrMsgEmptyDeviceProjectUser, }, { "No class method", &Msg{ Dinetrpc: CurrentDinetrpc, ID: 1, Time: ditime.Now(), Type: MsgTypeRequest, DeviceUID: testUID, }, ErrMsgInvalidClassMethod, }, { "Invalid DeviceUID", &Msg{ Dinetrpc: CurrentDinetrpc, ID: 1, Time: ditime.Now(), Type: MsgTypeRequest, ClassMethod: ClassMethodDevicePing, DeviceUID: "invalid", }, ErrMsgInvalidDeviceUID, }, { "Error object contains ok", &Msg{ Dinetrpc: CurrentDinetrpc, ID: 1, Time: ditime.Now(), Type: MsgTypeReply, ClassMethod: ClassMethodDevicePing, DeviceUID: testUID, Error: &Error{ Code: Ok, Descr: Ok.String(), }, }, ErrMsgErrorWithOk, }, { "Missing time", &Msg{ Dinetrpc: CurrentDinetrpc, ID: 1, Type: MsgTypeRequest, ClassMethod: ClassMethodDevicePing, DeviceUID: testUID, }, ErrMsgEmptyTime, }, } for _, tc := range tests { // Transfer tc to local variable for fixing schope tc := tc t.Run(tc.name, func(t *testing.T) { err := tc.msg.Valid() require.NotNil(t, err) invalidMsgErr, ok := err.(*InvalidMsgError) require.True(t, ok) require.Equal(t, tc.err, invalidMsgErr.Reason) require.Equal(t, tc.err.Error(), invalidMsgErr.Error()) }) } } func TestAutofillFields(t *testing.T) { msg := Msg{Type: MsgTypeRequest, ClassMethod: ClassMethodConfigGet} msg2 := Msg{} b, err := json.Marshal(&msg) require.Nil(t, err) require.Nil(t, json.Unmarshal(b, &msg2)) require.Equal(t, string(msg.Type), string(msg2.Type)) // check that a time is set require.NotEqual(t, 0, msg2.Time) // check that the ID is set require.NotEqual(t, uint32(0), msg2.ID) // check that dinetrpc is set require.Equal(t, CurrentDinetrpc, msg2.Dinetrpc) msg = Msg{Type: MsgTypePublish, ID: 1000, ClassMethod: ClassMethodSensorData} b, err = json.Marshal(&msg) require.Nil(t, err) // clear the message msg2 = Msg{} require.Nil(t, json.Unmarshal(b, &msg2)) require.Equal(t, string(msg.Type), string(msg2.Type)) // check that a time is set require.NotEqual(t, 0, msg2.Time) // check that the ID is NOT set require.Equal(t, uint32(0), msg2.ID) // check that dinetrpc is set require.Equal(t, CurrentDinetrpc, msg2.Dinetrpc) }