github.com/hyperledger/aries-framework-go@v0.3.2/pkg/ld/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 ld_test 8 9 import ( 10 "bytes" 11 "encoding/json" 12 "errors" 13 "io/ioutil" 14 "net/http" 15 "testing" 16 17 jsonld "github.com/piprate/json-gold/ld" 18 "github.com/stretchr/testify/require" 19 20 "github.com/hyperledger/aries-framework-go/pkg/doc/ldcontext/remote" 21 "github.com/hyperledger/aries-framework-go/pkg/internal/ldtestutil" 22 "github.com/hyperledger/aries-framework-go/pkg/ld" 23 mockldstore "github.com/hyperledger/aries-framework-go/pkg/mock/ld" 24 mockprovider "github.com/hyperledger/aries-framework-go/pkg/mock/provider" 25 mockstorage "github.com/hyperledger/aries-framework-go/pkg/mock/storage" 26 ldstore "github.com/hyperledger/aries-framework-go/pkg/store/ld" 27 "github.com/hyperledger/aries-framework-go/spi/storage" 28 ) 29 30 const sampleContextsResponse = `{ 31 "documents": [ 32 { 33 "url": "https://example.com/context.jsonld", 34 "content": { 35 "@context": "remote" 36 } 37 } 38 ] 39 }` 40 41 func TestDefaultService_AddContexts(t *testing.T) { 42 t.Run("Success", func(t *testing.T) { 43 store := mockldstore.NewMockContextStore() 44 45 svc := ld.New(createMockProvider(withContextStore(store))) 46 47 err := svc.AddContexts(ldtestutil.Contexts()) 48 49 require.NoError(t, err) 50 require.Len(t, store.Store.Store, len(ldtestutil.Contexts())) 51 }) 52 53 t.Run("Fail to add contexts", func(t *testing.T) { 54 store := mockldstore.NewMockContextStore() 55 store.ErrImport = errors.New("import error") 56 57 svc := ld.New(createMockProvider(withContextStore(store))) 58 59 err := svc.AddContexts(ldtestutil.Contexts()) 60 61 require.Error(t, err) 62 require.Contains(t, err.Error(), "add contexts") 63 }) 64 } 65 66 func TestDefaultService_AddRemoteProvider(t *testing.T) { 67 t.Run("Success", func(t *testing.T) { 68 httpClient := &mockHTTPClient{ 69 DoFunc: func(req *http.Request) (*http.Response, error) { 70 return &http.Response{ 71 StatusCode: http.StatusOK, 72 Body: ioutil.NopCloser(bytes.NewReader([]byte(sampleContextsResponse))), 73 }, nil 74 }, 75 } 76 77 contextStore := mockldstore.NewMockContextStore() 78 providerStore := mockldstore.NewMockRemoteProviderStore() 79 80 svc := ld.New(createMockProvider( 81 withContextStore(contextStore), 82 withRemoteProviderStore(providerStore), 83 )) 84 85 providerID, err := svc.AddRemoteProvider("endpoint", remote.WithHTTPClient(httpClient)) 86 87 require.NotEmpty(t, providerID) 88 require.NoError(t, err) 89 require.Equal(t, 1, len(providerStore.Store.Store)) 90 require.Equal(t, 1, len(contextStore.Store.Store)) 91 }) 92 93 t.Run("Fail to get contexts from remote provider", func(t *testing.T) { 94 httpClient := &mockHTTPClient{ 95 DoFunc: func(req *http.Request) (*http.Response, error) { 96 return &http.Response{ 97 StatusCode: http.StatusNotFound, 98 Body: ioutil.NopCloser(bytes.NewReader(nil)), 99 }, nil 100 }, 101 } 102 103 svc := ld.New(createMockProvider()) 104 105 providerID, err := svc.AddRemoteProvider("endpoint", remote.WithHTTPClient(httpClient)) 106 107 require.Empty(t, providerID) 108 require.Error(t, err) 109 require.Contains(t, err.Error(), "get contexts from remote provider") 110 }) 111 112 t.Run("Fail to save remote provider", func(t *testing.T) { 113 httpClient := &mockHTTPClient{ 114 DoFunc: func(req *http.Request) (*http.Response, error) { 115 return &http.Response{ 116 StatusCode: http.StatusOK, 117 Body: ioutil.NopCloser(bytes.NewReader([]byte(sampleContextsResponse))), 118 }, nil 119 }, 120 } 121 122 providerStore := mockldstore.NewMockRemoteProviderStore() 123 providerStore.ErrSave = errors.New("save error") 124 125 svc := ld.New(createMockProvider(withRemoteProviderStore(providerStore))) 126 127 providerID, err := svc.AddRemoteProvider("endpoint", remote.WithHTTPClient(httpClient)) 128 129 require.Empty(t, providerID) 130 require.Error(t, err) 131 require.Contains(t, err.Error(), "save remote provider") 132 }) 133 134 t.Run("Fail to import contexts", func(t *testing.T) { 135 httpClient := &mockHTTPClient{ 136 DoFunc: func(req *http.Request) (*http.Response, error) { 137 return &http.Response{ 138 StatusCode: http.StatusOK, 139 Body: ioutil.NopCloser(bytes.NewReader([]byte(sampleContextsResponse))), 140 }, nil 141 }, 142 } 143 144 contextStore := mockldstore.NewMockContextStore() 145 contextStore.ErrImport = errors.New("import error") 146 147 svc := ld.New(createMockProvider(withContextStore(contextStore))) 148 149 providerID, err := svc.AddRemoteProvider("endpoint", remote.WithHTTPClient(httpClient)) 150 151 require.Empty(t, providerID) 152 require.Error(t, err) 153 require.Contains(t, err.Error(), "import contexts") 154 }) 155 } 156 157 func TestDefaultService_RefreshAllRemoteProviders(t *testing.T) { 158 t.Run("Success", func(t *testing.T) { 159 httpClient := &mockHTTPClient{ 160 DoFunc: func(req *http.Request) (*http.Response, error) { 161 return &http.Response{ 162 StatusCode: http.StatusOK, 163 Body: ioutil.NopCloser(bytes.NewReader([]byte(sampleContextsResponse))), 164 }, nil 165 }, 166 } 167 168 contextStore := mockldstore.NewMockContextStore() 169 170 providerStore := mockldstore.NewMockRemoteProviderStore() 171 providerStore.Store.Store["id"] = mockstorage.DBEntry{ 172 Value: []byte("endpoint"), 173 Tags: []storage.Tag{{Name: ldstore.RemoteProviderRecordTag}}, 174 } 175 176 svc := ld.New(createMockProvider( 177 withContextStore(contextStore), 178 withRemoteProviderStore(providerStore), 179 )) 180 181 err := svc.RefreshRemoteProvider("id", remote.WithHTTPClient(httpClient)) 182 183 require.NoError(t, err) 184 require.Equal(t, 1, len(providerStore.Store.Store)) 185 require.Equal(t, 1, len(contextStore.Store.Store)) 186 }) 187 188 t.Run("Fail to get remote provider from store", func(t *testing.T) { 189 store := mockldstore.NewMockRemoteProviderStore() 190 store.ErrGet = errors.New("get error") 191 192 svc := ld.New(createMockProvider(withRemoteProviderStore(store))) 193 194 err := svc.RefreshRemoteProvider("id", remote.WithHTTPClient(&mockHTTPClient{})) 195 196 require.Error(t, err) 197 require.Contains(t, err.Error(), "get remote provider from store") 198 }) 199 200 t.Run("Fail to get contexts from remote provider", func(t *testing.T) { 201 httpClient := &mockHTTPClient{ 202 DoFunc: func(req *http.Request) (*http.Response, error) { 203 return &http.Response{ 204 StatusCode: http.StatusNotFound, 205 Body: ioutil.NopCloser(bytes.NewReader(nil)), 206 }, nil 207 }, 208 } 209 210 providerStore := mockldstore.NewMockRemoteProviderStore() 211 providerStore.Store.Store["id"] = mockstorage.DBEntry{ 212 Value: []byte("endpoint"), 213 Tags: []storage.Tag{{Name: ldstore.RemoteProviderRecordTag}}, 214 } 215 216 svc := ld.New(createMockProvider(withRemoteProviderStore(providerStore))) 217 218 err := svc.RefreshRemoteProvider("id", remote.WithHTTPClient(httpClient)) 219 220 require.Error(t, err) 221 require.Contains(t, err.Error(), "get contexts from remote provider") 222 }) 223 224 t.Run("Fail to import contexts", func(t *testing.T) { 225 httpClient := &mockHTTPClient{ 226 DoFunc: func(req *http.Request) (*http.Response, error) { 227 return &http.Response{ 228 StatusCode: http.StatusOK, 229 Body: ioutil.NopCloser(bytes.NewReader([]byte(sampleContextsResponse))), 230 }, nil 231 }, 232 } 233 234 contextStore := mockldstore.NewMockContextStore() 235 contextStore.ErrImport = errors.New("import error") 236 237 providerStore := mockldstore.NewMockRemoteProviderStore() 238 providerStore.Store.Store["id"] = mockstorage.DBEntry{ 239 Value: []byte("endpoint"), 240 Tags: []storage.Tag{{Name: ldstore.RemoteProviderRecordTag}}, 241 } 242 243 svc := ld.New(createMockProvider( 244 withContextStore(contextStore), 245 withRemoteProviderStore(providerStore), 246 )) 247 248 err := svc.RefreshRemoteProvider("id", remote.WithHTTPClient(httpClient)) 249 250 require.Error(t, err) 251 require.Contains(t, err.Error(), "import contexts") 252 }) 253 } 254 255 func TestDefaultService_DeleteRemoteProvider(t *testing.T) { 256 t.Run("Success", func(t *testing.T) { 257 httpClient := &mockHTTPClient{ 258 DoFunc: func(req *http.Request) (*http.Response, error) { 259 return &http.Response{ 260 StatusCode: http.StatusOK, 261 Body: ioutil.NopCloser(bytes.NewReader([]byte(sampleContextsResponse))), 262 }, nil 263 }, 264 } 265 266 document, err := jsonld.DocumentFromReader(bytes.NewReader([]byte(`{"@context": "remote"}`))) 267 require.NoError(t, err) 268 269 rd := jsonld.RemoteDocument{ 270 DocumentURL: "https://example.com/context.jsonld", 271 Document: document, 272 } 273 274 b, err := json.Marshal(rd) 275 require.NoError(t, err) 276 277 contextStore := mockldstore.NewMockContextStore() 278 contextStore.Store.Store[rd.DocumentURL] = mockstorage.DBEntry{ 279 Value: b, 280 Tags: []storage.Tag{{Name: ldstore.ContextRecordTag}}, 281 } 282 283 providerStore := mockldstore.NewMockRemoteProviderStore() 284 providerStore.Store.Store["id"] = mockstorage.DBEntry{ 285 Value: []byte("endpoint"), 286 Tags: []storage.Tag{{Name: ldstore.RemoteProviderRecordTag}}, 287 } 288 289 svc := ld.New(createMockProvider( 290 withContextStore(contextStore), 291 withRemoteProviderStore(providerStore), 292 )) 293 294 err = svc.DeleteRemoteProvider("id", remote.WithHTTPClient(httpClient)) 295 296 require.NoError(t, err) 297 require.Equal(t, 0, len(providerStore.Store.Store)) 298 require.Equal(t, 0, len(contextStore.Store.Store)) 299 }) 300 301 t.Run("Fail to get remote provider from store", func(t *testing.T) { 302 store := mockldstore.NewMockRemoteProviderStore() 303 store.ErrGet = errors.New("get error") 304 305 svc := ld.New(createMockProvider(withRemoteProviderStore(store))) 306 307 err := svc.DeleteRemoteProvider("id", remote.WithHTTPClient(&mockHTTPClient{})) 308 309 require.Error(t, err) 310 require.Contains(t, err.Error(), "get remote provider from store") 311 }) 312 313 t.Run("Fail to get contexts from remote provider", func(t *testing.T) { 314 httpClient := &mockHTTPClient{ 315 DoFunc: func(req *http.Request) (*http.Response, error) { 316 return &http.Response{ 317 StatusCode: http.StatusNotFound, 318 Body: ioutil.NopCloser(bytes.NewReader(nil)), 319 }, nil 320 }, 321 } 322 323 providerStore := mockldstore.NewMockRemoteProviderStore() 324 providerStore.Store.Store["id"] = mockstorage.DBEntry{ 325 Value: []byte("endpoint"), 326 Tags: []storage.Tag{{Name: ldstore.RemoteProviderRecordTag}}, 327 } 328 329 svc := ld.New(createMockProvider(withRemoteProviderStore(providerStore))) 330 331 err := svc.DeleteRemoteProvider("id", remote.WithHTTPClient(httpClient)) 332 333 require.Error(t, err) 334 require.Contains(t, err.Error(), "get contexts from remote provider") 335 }) 336 337 t.Run("Fail to delete contexts", func(t *testing.T) { 338 httpClient := &mockHTTPClient{ 339 DoFunc: func(req *http.Request) (*http.Response, error) { 340 return &http.Response{ 341 StatusCode: http.StatusOK, 342 Body: ioutil.NopCloser(bytes.NewReader([]byte(sampleContextsResponse))), 343 }, nil 344 }, 345 } 346 347 contextStore := mockldstore.NewMockContextStore() 348 contextStore.ErrDelete = errors.New("delete error") 349 350 providerStore := mockldstore.NewMockRemoteProviderStore() 351 providerStore.Store.Store["id"] = mockstorage.DBEntry{ 352 Value: []byte("endpoint"), 353 Tags: []storage.Tag{{Name: ldstore.RemoteProviderRecordTag}}, 354 } 355 356 svc := ld.New(createMockProvider( 357 withContextStore(contextStore), 358 withRemoteProviderStore(providerStore), 359 )) 360 361 err := svc.DeleteRemoteProvider("id", remote.WithHTTPClient(httpClient)) 362 363 require.Error(t, err) 364 require.Contains(t, err.Error(), "delete contexts") 365 }) 366 367 t.Run("Fail to delete remote provider record", func(t *testing.T) { 368 httpClient := &mockHTTPClient{ 369 DoFunc: func(req *http.Request) (*http.Response, error) { 370 return &http.Response{ 371 StatusCode: http.StatusOK, 372 Body: ioutil.NopCloser(bytes.NewReader([]byte(sampleContextsResponse))), 373 }, nil 374 }, 375 } 376 377 store := mockldstore.NewMockRemoteProviderStore() 378 store.Store.Store["id"] = mockstorage.DBEntry{ 379 Value: []byte("endpoint"), 380 Tags: []storage.Tag{{Name: ldstore.RemoteProviderRecordTag}}, 381 } 382 store.ErrDelete = errors.New("delete error") 383 384 svc := ld.New(createMockProvider(withRemoteProviderStore(store))) 385 386 err := svc.DeleteRemoteProvider("id", remote.WithHTTPClient(httpClient)) 387 388 require.Error(t, err) 389 require.Contains(t, err.Error(), "delete remote provider record:") 390 }) 391 } 392 393 func TestDefaultService_GetAllRemoteProviders(t *testing.T) { 394 t.Run("Success", func(t *testing.T) { 395 store := mockldstore.NewMockRemoteProviderStore() 396 store.Store.Store["id"] = mockstorage.DBEntry{ 397 Value: []byte("endpoint"), 398 Tags: []storage.Tag{{Name: ldstore.RemoteProviderRecordTag}}, 399 } 400 401 cmd := ld.New(createMockProvider(withRemoteProviderStore(store))) 402 403 providers, err := cmd.GetAllRemoteProviders() 404 405 require.NoError(t, err) 406 require.Equal(t, 1, len(providers)) 407 }) 408 409 t.Run("Fail to get remote provider records", func(t *testing.T) { 410 store := mockldstore.NewMockRemoteProviderStore() 411 store.ErrGetAll = errors.New("get all error") 412 413 cmd := ld.New(createMockProvider(withRemoteProviderStore(store))) 414 415 providers, err := cmd.GetAllRemoteProviders() 416 417 require.Nil(t, providers) 418 require.Error(t, err) 419 require.Contains(t, err.Error(), "get remote provider records") 420 }) 421 } 422 423 func TestDefaultService_RefreshRemoteProvider(t *testing.T) { 424 t.Run("Success", func(t *testing.T) { 425 httpClient := &mockHTTPClient{ 426 DoFunc: func(req *http.Request) (*http.Response, error) { 427 return &http.Response{ 428 StatusCode: http.StatusOK, 429 Body: ioutil.NopCloser(bytes.NewReader([]byte(sampleContextsResponse))), 430 }, nil 431 }, 432 } 433 434 contextStore := mockldstore.NewMockContextStore() 435 436 providerStore := mockldstore.NewMockRemoteProviderStore() 437 providerStore.Store.Store["id"] = mockstorage.DBEntry{ 438 Value: []byte("endpoint"), 439 Tags: []storage.Tag{{Name: ldstore.RemoteProviderRecordTag}}, 440 } 441 442 svc := ld.New(createMockProvider( 443 withContextStore(contextStore), 444 withRemoteProviderStore(providerStore), 445 )) 446 447 err := svc.RefreshAllRemoteProviders(remote.WithHTTPClient(httpClient)) 448 449 require.NoError(t, err) 450 require.Equal(t, 1, len(providerStore.Store.Store)) 451 require.Equal(t, 1, len(contextStore.Store.Store)) 452 }) 453 454 t.Run("Fail to get remote provider records", func(t *testing.T) { 455 store := mockldstore.NewMockRemoteProviderStore() 456 store.ErrGetAll = errors.New("get all error") 457 458 svc := ld.New(createMockProvider(withRemoteProviderStore(store))) 459 460 err := svc.RefreshAllRemoteProviders(remote.WithHTTPClient(&mockHTTPClient{})) 461 462 require.Error(t, err) 463 require.Contains(t, err.Error(), "get remote provider records") 464 }) 465 466 t.Run("Fail to get contexts from remote provider", func(t *testing.T) { 467 httpClient := &mockHTTPClient{ 468 DoFunc: func(req *http.Request) (*http.Response, error) { 469 return &http.Response{ 470 StatusCode: http.StatusNotFound, 471 Body: ioutil.NopCloser(bytes.NewReader(nil)), 472 }, nil 473 }, 474 } 475 476 store := mockldstore.NewMockRemoteProviderStore() 477 store.Store.Store["id"] = mockstorage.DBEntry{ 478 Value: []byte("endpoint"), 479 Tags: []storage.Tag{{Name: ldstore.RemoteProviderRecordTag}}, 480 } 481 482 svc := ld.New(createMockProvider(withRemoteProviderStore(store))) 483 484 err := svc.RefreshAllRemoteProviders(remote.WithHTTPClient(httpClient)) 485 486 require.Error(t, err) 487 require.Contains(t, err.Error(), "get contexts from remote provider") 488 }) 489 490 t.Run("Fail to import contexts", func(t *testing.T) { 491 httpClient := &mockHTTPClient{ 492 DoFunc: func(req *http.Request) (*http.Response, error) { 493 return &http.Response{ 494 StatusCode: http.StatusOK, 495 Body: ioutil.NopCloser(bytes.NewReader([]byte(sampleContextsResponse))), 496 }, nil 497 }, 498 } 499 500 store := mockldstore.NewMockContextStore() 501 store.ErrImport = errors.New("import error") 502 503 providerStore := mockldstore.NewMockRemoteProviderStore() 504 providerStore.Store.Store["id"] = mockstorage.DBEntry{ 505 Value: []byte("endpoint"), 506 Tags: []storage.Tag{{Name: ldstore.RemoteProviderRecordTag}}, 507 } 508 509 svc := ld.New(createMockProvider( 510 withContextStore(store), 511 withRemoteProviderStore(providerStore), 512 )) 513 514 err := svc.RefreshAllRemoteProviders(remote.WithHTTPClient(httpClient)) 515 516 require.Error(t, err) 517 require.Contains(t, err.Error(), "import contexts") 518 }) 519 } 520 521 type mockHTTPClient struct { 522 DoFunc func(req *http.Request) (*http.Response, error) 523 } 524 525 func (m *mockHTTPClient) Do(req *http.Request) (*http.Response, error) { 526 return m.DoFunc(req) 527 } 528 529 func createMockProvider(opts ...providerOptionFn) *mockprovider.Provider { 530 p := &mockprovider.Provider{ 531 ContextStoreValue: mockldstore.NewMockContextStore(), 532 RemoteProviderStoreValue: mockldstore.NewMockRemoteProviderStore(), 533 } 534 535 for i := range opts { 536 opts[i](p) 537 } 538 539 return p 540 } 541 542 type providerOptionFn func(opts *mockprovider.Provider) 543 544 func withContextStore(store ldstore.ContextStore) providerOptionFn { 545 return func(p *mockprovider.Provider) { 546 p.ContextStoreValue = store 547 } 548 } 549 550 func withRemoteProviderStore(store ldstore.RemoteProviderStore) providerOptionFn { 551 return func(p *mockprovider.Provider) { 552 p.RemoteProviderStoreValue = store 553 } 554 }