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 }