github.com/hyperledger/aries-framework-go@v0.3.2/pkg/didcomm/common/service/service_test.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package service
     8  
     9  import (
    10  	"encoding/json"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/stretchr/testify/require"
    15  
    16  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
    17  )
    18  
    19  func TestParseDIDCommMsgMap(t *testing.T) {
    20  	tests := []struct {
    21  		name    string
    22  		payload []byte
    23  		err     string
    24  	}{{
    25  		name: "No payload",
    26  		err:  "invalid payload data format: unexpected end of JSON input",
    27  	}, {
    28  		name:    "Happy path",
    29  		payload: []byte(`{"@id":"ID"}`),
    30  		err:     "",
    31  	}, {
    32  		name:    "Empty payload (JSON)",
    33  		payload: []byte(`{}`),
    34  		err:     "",
    35  	}, {
    36  		name:    "Array payload",
    37  		payload: []byte(`[]`),
    38  		err:     `invalid payload data format: json: cannot unmarshal array into Go value of type map[string]interface`,
    39  	}, {
    40  		name:    "Type",
    41  		payload: []byte(`{"@type":"type"}`),
    42  		err:     "",
    43  	}}
    44  
    45  	t.Parallel()
    46  
    47  	for _, test := range tests {
    48  		tc := test
    49  		t.Run(tc.name, func(t *testing.T) {
    50  			val, err := ParseDIDCommMsgMap(tc.payload)
    51  			if err != nil {
    52  				require.Contains(t, err.Error(), tc.err)
    53  				require.Nil(t, val)
    54  			} else {
    55  				require.NotNil(t, val)
    56  			}
    57  		})
    58  	}
    59  }
    60  
    61  func TestNewDIDCommMsgMap(t *testing.T) {
    62  	tests := []struct {
    63  		name     string
    64  		payload  interface{}
    65  		expected DIDCommMsgMap
    66  		err      string
    67  	}{
    68  		{
    69  			name: "Thread decorator",
    70  			payload: struct {
    71  				Time    time.Time
    72  				Threads []decorator.Thread
    73  				Thread  decorator.Thread
    74  			}{
    75  				Threads: []decorator.Thread{{
    76  					ID:             "test",
    77  					ReceivedOrders: map[string]int{"order": 1},
    78  				}},
    79  				Thread: decorator.Thread{
    80  					ID:             "test",
    81  					ReceivedOrders: map[string]int{"order": 1},
    82  				},
    83  			},
    84  			expected: DIDCommMsgMap{
    85  				jsonMetadata: map[string]interface{}{},
    86  				"Thread": map[string]interface{}{
    87  					"received_orders": map[string]interface{}{"order": 1},
    88  					"thid":            "test",
    89  				},
    90  				"Threads": []interface{}{map[string]interface{}{
    91  					"received_orders": map[string]interface{}{"order": 1},
    92  					"thid":            "test",
    93  				}},
    94  				"Time": time.Time{},
    95  			},
    96  		},
    97  		{
    98  			name: "Ignore",
    99  			payload: struct {
   100  				Ignore string `json:"-"`
   101  			}{
   102  				Ignore: "Ignore",
   103  			},
   104  			expected: DIDCommMsgMap{
   105  				jsonMetadata: map[string]interface{}{},
   106  			},
   107  		},
   108  		{
   109  			name: "Build-in",
   110  			payload: struct {
   111  				decorator.Thread
   112  			}{
   113  				Thread: decorator.Thread{
   114  					ID:             "test",
   115  					ReceivedOrders: map[string]int{"order": 1},
   116  				},
   117  			},
   118  			expected: DIDCommMsgMap{
   119  				jsonMetadata:      map[string]interface{}{},
   120  				"received_orders": map[string]interface{}{"order": 1},
   121  				"thid":            "test",
   122  			},
   123  		},
   124  		{
   125  			name: "Build-in with pointer",
   126  			payload: struct {
   127  				*decorator.Thread
   128  			}{
   129  				Thread: &decorator.Thread{
   130  					ID:             "test",
   131  					ReceivedOrders: map[string]int{"order": 1},
   132  				},
   133  			},
   134  			expected: DIDCommMsgMap{
   135  				jsonMetadata:      map[string]interface{}{},
   136  				"received_orders": map[string]interface{}{"order": 1},
   137  				"thid":            "test",
   138  			},
   139  		},
   140  		{
   141  			name: "Build-in with JSON tag",
   142  			payload: struct {
   143  				*decorator.Thread `json:"~thread"`
   144  			}{
   145  				Thread: &decorator.Thread{
   146  					ID:             "test",
   147  					ReceivedOrders: map[string]int{"order": 1},
   148  				},
   149  			},
   150  			expected: DIDCommMsgMap{
   151  				jsonMetadata: map[string]interface{}{},
   152  				"~thread": map[string]interface{}{
   153  					"received_orders": map[string]interface{}{"order": 1},
   154  					"thid":            "test",
   155  				},
   156  			},
   157  		},
   158  	}
   159  
   160  	for _, test := range tests {
   161  		tc := test
   162  		t.Run(tc.name, func(t *testing.T) {
   163  			val := NewDIDCommMsgMap(tc.payload)
   164  			require.Equal(t, tc.expected, val)
   165  
   166  			eRes, err := json.Marshal(tc.payload)
   167  			require.NoError(t, err)
   168  
   169  			vRes, err := json.Marshal(val)
   170  			require.NoError(t, err)
   171  
   172  			eResMap := make(map[string]interface{})
   173  			require.NoError(t, json.Unmarshal(eRes, &eResMap))
   174  
   175  			vResMap := make(map[string]interface{})
   176  			require.NoError(t, json.Unmarshal(vRes, &vResMap))
   177  
   178  			require.Equal(t, eResMap, vResMap)
   179  		})
   180  	}
   181  
   182  	idTests := []struct {
   183  		name    string
   184  		payload interface{}
   185  		version Version
   186  	}{
   187  		{
   188  			name: "v1 with ID",
   189  			payload: struct {
   190  				ID   string `json:"@id"`
   191  				Type string `json:"@type"`
   192  			}{
   193  				ID:   "foobar",
   194  				Type: "blahblah",
   195  			},
   196  			version: V1,
   197  		},
   198  		{
   199  			name: "v2 with ID",
   200  			payload: struct {
   201  				ID   string `json:"id"`
   202  				Type string `json:"type"`
   203  			}{
   204  				ID:   "foobar",
   205  				Type: "blahblah",
   206  			},
   207  			version: V2,
   208  		},
   209  		{
   210  			name: "v1 without ID",
   211  			payload: struct {
   212  				Type string `json:"@type"`
   213  			}{
   214  				Type: "blahblah",
   215  			},
   216  			version: V1,
   217  		},
   218  		{
   219  			name: "v2 without ID",
   220  			payload: struct {
   221  				Type string `json:"type"`
   222  			}{
   223  				Type: "blahblah",
   224  			},
   225  			version: V2,
   226  		},
   227  	}
   228  
   229  	for _, tc := range idTests {
   230  		t.Run(tc.name, func(t *testing.T) {
   231  			msg := NewDIDCommMsgMap(tc.payload)
   232  
   233  			_, hasIDV1 := msg["@id"]
   234  			_, hasIDV2 := msg["id"]
   235  
   236  			isV2, err := IsDIDCommV2(&msg)
   237  			require.NoError(t, err)
   238  
   239  			switch tc.version {
   240  			case V1:
   241  				require.True(t, hasIDV1)
   242  				require.False(t, hasIDV2)
   243  				require.False(t, isV2)
   244  			case V2:
   245  				require.False(t, hasIDV1)
   246  				require.True(t, hasIDV2)
   247  				require.True(t, isV2)
   248  			}
   249  		})
   250  	}
   251  }
   252  
   253  func TestDIDCommMsg_ThreadID(t *testing.T) {
   254  	tests := []struct {
   255  		name string
   256  		msg  DIDCommMsgMap
   257  		val  string
   258  		err  string
   259  	}{{
   260  		name: "No header",
   261  		msg:  nil,
   262  		err:  ErrInvalidMessage.Error(),
   263  	}, {
   264  		name: "old ID without Thread ID",
   265  		msg:  DIDCommMsgMap{jsonIDV1: "ID"},
   266  		val:  "ID",
   267  		err:  "",
   268  	}, {
   269  		name: "ID without Thread ID",
   270  		msg:  DIDCommMsgMap{jsonIDV2: "ID"},
   271  		val:  "ID",
   272  		err:  "",
   273  	}, {
   274  		name: "Thread ID",
   275  		msg:  DIDCommMsgMap{jsonThreadID: "tID"},
   276  		val:  "",
   277  		err:  ErrInvalidMessage.Error(),
   278  	}, {
   279  		name: "Thread ID with ID",
   280  		msg:  DIDCommMsgMap{jsonIDV2: "ID", jsonThreadID: "tID"},
   281  		val:  "tID",
   282  		err:  "",
   283  	}, {
   284  		name: "Thread ID with old ID",
   285  		msg:  DIDCommMsgMap{jsonIDV1: "ID", jsonThreadID: "tID"},
   286  		val:  "ID",
   287  		err:  "",
   288  	}, {
   289  		name: "Thread ID with old ID",
   290  		msg:  DIDCommMsgMap{jsonIDV1: "ID", jsonThread: map[string]interface{}{jsonThreadID: "thID"}},
   291  		val:  "thID",
   292  		err:  "",
   293  	}, {
   294  		name: "Thread ID with ID",
   295  		msg:  DIDCommMsgMap{jsonIDV2: "ID", jsonThread: map[string]interface{}{jsonThreadID: "thID"}},
   296  		val:  "",
   297  		err:  ErrInvalidMessage.Error(),
   298  	}, {
   299  		name: "Thread ID without ID",
   300  		msg:  DIDCommMsgMap{jsonThread: map[string]interface{}{jsonThreadID: "thID"}},
   301  		val:  "",
   302  		err:  ErrInvalidMessage.Error(),
   303  	}, {
   304  		name: "No Thread ID and ID",
   305  		msg:  DIDCommMsgMap{},
   306  		val:  "",
   307  		err:  ErrThreadIDNotFound.Error(),
   308  	}}
   309  
   310  	t.Parallel()
   311  
   312  	for _, test := range tests {
   313  		tc := test
   314  		t.Run(tc.name, func(t *testing.T) {
   315  			val, err := tc.msg.ThreadID()
   316  			if err != nil {
   317  				require.Contains(t, err.Error(), tc.err)
   318  			}
   319  			require.Equal(t, tc.val, val)
   320  		})
   321  	}
   322  }