package rpc import ( "encoding/json" "testing" "github.com/stretchr/testify/require" ) func TestDeferredDecoding(t *testing.T) { rawMsg := `{"dinetrpc" : 1, "time": 1234, "req":"config:set", "id":1, "device:uid": "1337", "params": {"uid":100, "value":2}}` msg := &Msg{} err := json.Unmarshal([]byte(rawMsg), msg) require.Nil(t, err) require.False(t, msg.Params.IsEmpty()) require.True(t, msg.Result.IsEmpty()) def := msg.Params.(*deferredDecoder) require.Equal(t, decoderDataTypeJSON, def.dataType) cp := &ConfigParam{} err = msg.Params.Unmarshal(cp) require.Nil(t, err) require.Equal(t, float64(2), cp.Value.(float64)) require.Equal(t, uint16(100), cp.UID) // remarshall the data with the deferredDecoder in it ret, err := json.Marshal(msg) require.Nil(t, err) require.JSONEq(t, rawMsg, string(ret)) } func TestDecodeCustomType(t *testing.T) { rawMsg := `{"dinetrpc" : 1, "time": 1234, "req":"config:set", "id":2, "device:uid": "1337", "params": {"uid":1, "value":2}}` msg := &Msg{Params: &ConfigParam{}} // immediately attach ConfigParam err := json.Unmarshal([]byte(rawMsg), msg) require.Nil(t, err) require.False(t, msg.Params.IsEmpty()) require.True(t, msg.Result.IsEmpty()) // after unmarshall it should still be ConfigParam cp := msg.Params.(*ConfigParam) require.Equal(t, float64(2), cp.Value.(float64)) require.Equal(t, uint16(1), cp.UID) } func TestFaultyParamDecoding(t *testing.T) { cases := []struct { name string rawMsg string }{ {"no params", `{"dinetrpc" : 1, "time": 1234, "req":"config:set", "id":3, "device:uid": "1337"}`}, {"null params", `{"dinetrpc" : 1, "time": 1234, "req":"config:set", "id":4, "device:uid": "1337", "params": null}`}, } for _, c := range cases { // Transfer tc to local variable for fixing schope c := c t.Run(c.name, func(t *testing.T) { msg := &Msg{} err := json.Unmarshal([]byte(c.rawMsg), msg) require.Nil(t, err) require.True(t, msg.Params.IsEmpty()) require.True(t, msg.Result.IsEmpty()) def := msg.Params.(*deferredDecoder) require.Nil(t, def.unmarshaller) cp := &ConfigParam{} err = msg.Params.Unmarshal(cp) require.Equal(t, ErrMsgNoData, err) }) } }