github.com/hyperledger/aries-framework-go@v0.3.2/pkg/wallet/contents_test.go (about) 1 /* 2 Copyright SecureKey Technologies Inc. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package wallet 8 9 import ( 10 "errors" 11 "fmt" 12 "testing" 13 "time" 14 15 "github.com/google/uuid" 16 "github.com/stretchr/testify/require" 17 18 "github.com/hyperledger/aries-framework-go/component/storage/edv" 19 "github.com/hyperledger/aries-framework-go/internal/testdata" 20 "github.com/hyperledger/aries-framework-go/pkg/doc/ld" 21 vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr" 22 "github.com/hyperledger/aries-framework-go/pkg/internal/ldtestutil" 23 "github.com/hyperledger/aries-framework-go/pkg/kms" 24 mockkms "github.com/hyperledger/aries-framework-go/pkg/mock/kms" 25 mockstorage "github.com/hyperledger/aries-framework-go/pkg/mock/storage" 26 "github.com/hyperledger/aries-framework-go/pkg/mock/vdr" 27 "github.com/hyperledger/aries-framework-go/spi/storage" 28 ) 29 30 const ( 31 sampleContenttErr = "sample content err" 32 sampleContentValid = `{ 33 "@context": ["https://w3id.org/wallet/v1"], 34 "id": "did:example:123456789abcdefghi", 35 "type": "Person", 36 "name": "John Smith", 37 "image": "https://via.placeholder.com/150", 38 "description" : "Professional software developer for Acme Corp.", 39 "tags": ["professional", "person"], 40 "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"] 41 }` 42 sampleContentNoID = `{ 43 "@context": ["https://w3id.org/wallet/v1"], 44 "type": "Person", 45 "name": "John Smith", 46 "image": "https://via.placeholder.com/150", 47 "description" : "Professional software developer for Acme Corp.", 48 "tags": ["professional", "person"], 49 "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"] 50 }` 51 sampleContentInvalid = `{ 52 "@context": ["https://w3id.org/wallet/v1"], 53 "type": "Person", 54 "name": "John Smith", 55 "image": "https://via.placeholder.com/150", 56 "description" : "Professional software developer for Acme Corp.", 57 "tags": ["professional", "person"], 58 "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"] 59 }` 60 didResolutionResult = `{ 61 "@context": [ 62 "https://w3id.org/wallet/v1", 63 "https://w3id.org/did-resolution/v1" 64 ], 65 "id": "did:example:123", 66 "type": ["DIDResolutionResponse"], 67 "name": "Farming Sensor DID Document", 68 "image": "https://via.placeholder.com/150", 69 "description": "An IoT device in the middle of a corn field.", 70 "tags": ["professional"], 71 "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"], 72 "created": "2017-06-18T21:19:10Z", 73 "expires": "2026-06-18T21:19:10Z", 74 "didDocument": { 75 "@context": [ 76 "https://www.w3.org/ns/did/v1", 77 { 78 "@base": "did:key:z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg" 79 } 80 ], 81 "id": "did:key:z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg", 82 "verificationMethod": [ 83 { 84 "id": "#z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg", 85 "type": "JsonWebKey2020", 86 "controller": "did:key:z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg", 87 "publicKeyJwk": { 88 "crv": "Ed25519", 89 "x": "vGur-MEOrN6GDLf4TBGHDYAERxkmWOjTbztvG3xP0I8", 90 "kty": "OKP" 91 } 92 }, 93 { 94 "id": "#z6LScrLMVd9jvbphPeQkGffSeB99EWSYqAnMg8rGiHCgz5ha", 95 "type": "JsonWebKey2020", 96 "controller": "did:key:z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg", 97 "publicKeyJwk": { 98 "kty": "OKP", 99 "crv": "X25519", 100 "x": "EXXinkMxdA4zGmwpOOpbCXt6Ts6CwyXyEKI3jfHkS3k" 101 } 102 } 103 ], 104 "authentication": [ 105 "#z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg" 106 ], 107 "assertionMethod": [ 108 "#z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg" 109 ], 110 "capabilityInvocation": [ 111 "#z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg" 112 ], 113 "capabilityDelegation": [ 114 "#z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg" 115 ], 116 "keyAgreement": [ 117 "#z6LScrLMVd9jvbphPeQkGffSeB99EWSYqAnMg8rGiHCgz5ha" 118 ] 119 }, 120 "didDocumentMetadata": { 121 "content-type": "application/did+json" 122 }, 123 "didResolutionMetadata": {} 124 }` 125 sampleKeyContentBase58Valid = `{ 126 "@context": ["https://w3id.org/wallet/v1"], 127 "id": "did:example:123456789abcdefghi#key-1", 128 "type": "Ed25519VerificationKey2018", 129 "privateKeyBase58":"zJRjGFZydU5DBdS2p5qbiUzDFAxbXTkjiDuGPksMBbY5TNyEsGfK4a4WGKjBCh1zeNryeuKtPotp8W1ESnwP71y" 130 }` 131 sampleKeyContentBase58WithInvalidField = `{ 132 "@context": ["https://w3id.org/wallet/v1"], 133 "id": "did:example:123456789abcdefghi#key-1", 134 "controller": "did:example:123456789abcdefghi", 135 "type": "Ed25519VerificationKey2018", 136 "privateKeyBase58":"zJRjGFZydU5DBdS2p5qbiUzDFAxbXTkjiDuGPksMBbY5TNyEsGfK4a4WGKjBCh1zeNryeuKtPotp8W1ESnwP71y" 137 }` 138 sampleKeyContentJwkValid = `{ 139 "@context": ["https://w3id.org/wallet/v1"], 140 "id": "did:example:123456789abcdefghi#z6MkiEh8RQL83nkPo8ehDeX7", 141 "type": "Ed25519VerificationKey2018", 142 "privateKeyJwk": { 143 "kty": "OKP", 144 "d":"Dq5t2WS3OMzcpkh8AyVxJs5r9v4L39ocIz9CpUOqM40", 145 "crv": "Ed25519", 146 "x": "ODaPFurJgFcoVCUYEmgOJpWOtPlOYbHSugasscKWqDM", 147 "kid":"z6MkiEh8RQL83nkPo8ehDeX7" 148 } 149 }` 150 sampleJWTCredContentValid = "eyJhbGciOiJFZERTQSIsImtpZCI6IiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1Nzc5MDY2MDQsImlhdCI6M" + 151 "TI2MjM3MzgwNCwiaXNzIjoiZGlkOmV4YW1wbGU6NzZlMTJlYzcxMmViYzZmMWMyMjFlYmZlYjFmIiwianRpIjoiaHR0cDovL2V4YW1wbGU" + 152 "uZWR1L2NyZWRlbnRpYWxzLzE4NzIiLCJuYmYiOjEyNjIzNzM4MDQsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2Z" + 153 "TEyZWMyMSIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly93d3c" + 154 "udzMub3JnLzIwMTgvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjEiXSwiY3JlZGVudGlhbFN1YmplY3QiOnsiZGVncmVlIjp7InR5cGUiOiJCY" + 155 "WNoZWxvckRlZ3JlZSIsInVuaXZlcnNpdHkiOiJNSVQifSwiaWQiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjE" + 156 "iLCJuYW1lIjoiSmF5ZGVuIERvZSIsInNwb3VzZSI6ImRpZDpleGFtcGxlOmMyNzZlMTJlYzIxZWJmZWIxZjcxMmViYzZmMSJ9LCJpc3N1Z" + 157 "XIiOnsibmFtZSI6IkV4YW1wbGUgVW5pdmVyc2l0eSJ9LCJyZWZlcmVuY2VOdW1iZXIiOjguMzI5NDg0N2UrMDcsInR5cGUiOlsiVmVyaWZ" + 158 "pYWJsZUNyZWRlbnRpYWwiLCJVbml2ZXJzaXR5RGVncmVlQ3JlZGVudGlhbCJdfX0.a5yKMPmDnEXvM-fG3BaOqfdkqdvU4s2rzeZuOzLmk" + 159 "TH1y9sJT-mgTe7map5E9x7abrNVpyYbaH7JaAb9Yhr1DQ" 160 ) 161 162 func TestContentTypes(t *testing.T) { 163 t.Run("test content types", func(t *testing.T) { 164 tests := []struct { 165 name string 166 inputs []string 167 expected []ContentType 168 fail bool 169 }{ 170 { 171 name: "validation success", 172 inputs: []string{"collection", "credential", "didResolutionResponse", "metadata", "connection", "key"}, 173 expected: []ContentType{Collection, Credential, DIDResolutionResponse, Metadata, Connection, Key}, 174 }, 175 { 176 name: "validation error", 177 inputs: []string{"collECtion", "CRED", "VC", "DID", ""}, 178 fail: true, 179 }, 180 } 181 182 t.Parallel() 183 184 for _, test := range tests { 185 tc := test 186 t.Run(tc.name, func(t *testing.T) { 187 for i, input := range tc.inputs { 188 ct := ContentType(input) 189 190 if tc.fail { 191 require.Error(t, ct.IsValid()) 192 return 193 } 194 195 require.NoError(t, ct.IsValid()) 196 require.Equal(t, tc.expected[i], ct) 197 require.Equal(t, ct.Name(), input) 198 } 199 }) 200 } 201 }) 202 } 203 204 func TestContentStores(t *testing.T) { 205 keyMgr := &mockkms.KeyManager{} 206 207 token, e := sessionManager().createSession(uuid.New().String(), keyMgr, 5*time.Second) 208 require.NoError(t, e) 209 210 t.Run("create new content store - success", func(t *testing.T) { 211 sp := getMockStorageProvider() 212 213 // create new store 214 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 215 require.NotEmpty(t, contentStore) 216 require.Empty(t, sp.config.TagNames) 217 218 // open store 219 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 220 require.EqualValues(t, sp.config.TagNames, 221 []string{"collection", "credential", "connection", "didResolutionResponse", "connection", "key"}) 222 223 // close store 224 require.True(t, contentStore.Close()) 225 store, err := contentStore.open(token) 226 require.Empty(t, store) 227 require.True(t, errors.Is(err, ErrWalletLocked)) 228 }) 229 230 t.Run("create new content store for EDV profile - success", func(t *testing.T) { 231 sp := getMockStorageProvider() 232 233 masterLock, err := getDefaultSecretLock(samplePassPhrase) 234 require.NoError(t, err) 235 236 masterLockCipherText, err := createMasterLock(masterLock) 237 require.NoError(t, err) 238 require.NotEmpty(t, masterLockCipherText) 239 240 profileInfo := &profile{ 241 ID: uuid.New().String(), 242 User: uuid.New().String(), 243 MasterLockCipher: masterLockCipherText, 244 EDVConf: &edvConf{ 245 ServerURL: sampleEDVServerURL, 246 VaultID: sampleEDVVaultID, 247 }, 248 } 249 250 kmsStore, err := kms.NewAriesProviderWrapper(sp) 251 require.NoError(t, err) 252 253 kmgr, err := keyManager().createKeyManager(profileInfo, kmsStore, &unlockOpts{passphrase: samplePassPhrase}) 254 require.NotEmpty(t, kmgr) 255 require.NoError(t, err) 256 257 tkn, err := sessionManager().createSession(profileInfo.User, kmgr, 500*time.Millisecond) 258 259 require.NoError(t, err) 260 require.NotEmpty(t, kmgr) 261 262 err = profileInfo.setupEDVEncryptionKey(kmgr) 263 require.NoError(t, err) 264 265 err = profileInfo.setupEDVMacKey(kmgr) 266 require.NoError(t, err) 267 268 // create new store 269 contentStore := newContentStore(sp, createTestDocumentLoader(t), profileInfo) 270 require.NotEmpty(t, contentStore) 271 require.Empty(t, sp.config.TagNames) 272 273 // open store 274 require.NoError(t, contentStore.Open(kmgr, &unlockOpts{ 275 edvOpts: []edv.RESTProviderOption{ 276 edv.WithFullDocumentsReturnedFromQueries(), 277 edv.WithBatchEndpointExtension(), 278 }, 279 })) 280 281 // close store 282 require.True(t, contentStore.Close()) 283 store, err := contentStore.open(tkn) 284 require.Empty(t, store) 285 require.True(t, errors.Is(err, ErrWalletLocked)) 286 }) 287 288 t.Run("open store - failure", func(t *testing.T) { 289 sp := getMockStorageProvider() 290 291 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 292 293 // open store error 294 sp.ErrOpenStoreHandle = errors.New(sampleContenttErr) 295 err := contentStore.Open(keyMgr, &unlockOpts{}) 296 require.Error(t, err) 297 require.Contains(t, err.Error(), sampleContenttErr) 298 require.Contains(t, err.Error(), "failed to open store") 299 300 // set store config error 301 sp.ErrOpenStoreHandle = nil 302 sp.failure = errors.New(sampleContenttErr) 303 err = contentStore.Open(keyMgr, &unlockOpts{}) 304 require.Error(t, err) 305 require.Contains(t, err.Error(), sampleContenttErr) 306 require.Contains(t, err.Error(), "failed to set store config") 307 308 sp.ErrOpenStoreHandle = nil 309 sp.failure = nil 310 sp.Store.ErrClose = errors.New(sampleContenttErr) 311 contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 312 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 313 314 require.True(t, contentStore.Close()) 315 }) 316 317 t.Run("save to store - success", func(t *testing.T) { 318 sp := getMockStorageProvider() 319 320 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 321 require.NotEmpty(t, contentStore) 322 323 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 324 325 err := contentStore.Save(token, Collection, []byte(sampleContentValid)) 326 require.NoError(t, err) 327 328 // store is open but invalid auth token 329 err = contentStore.Save(sampleFakeTkn, Collection, []byte(sampleContentValid)) 330 require.True(t, errors.Is(err, ErrInvalidAuthToken)) 331 332 err = contentStore.Save(sampleFakeTkn, 333 Credential, testdata.SampleUDCVC, AddByCollection("test")) 334 require.True(t, errors.Is(err, ErrInvalidAuthToken)) 335 }) 336 337 t.Run("save content to store without ID - success", func(t *testing.T) { 338 sp := getMockStorageProvider() 339 340 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 341 require.NotEmpty(t, contentStore) 342 343 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 344 345 err := contentStore.Save(token, Collection, []byte(sampleContentNoID)) 346 require.NoError(t, err) 347 }) 348 349 t.Run("save to doc resolution to store - success", func(t *testing.T) { 350 sp := getMockStorageProvider() 351 352 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 353 require.NotEmpty(t, contentStore) 354 355 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 356 357 err := contentStore.Save(token, DIDResolutionResponse, []byte(didResolutionResult)) 358 require.NoError(t, err) 359 360 // get by DID ID 361 response, err := contentStore.Get(token, 362 "did:key:z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg", DIDResolutionResponse) 363 require.NoError(t, err) 364 require.NotEmpty(t, response) 365 require.Equal(t, string(response), didResolutionResult) 366 367 // store is open but invalid auth token 368 response, err = contentStore.Get(sampleFakeTkn, 369 "did:key:z6Mks8mvCnVx4HQcoq7ZwvpTbMnoRGudHSiEpXhMf6VW8XMg", DIDResolutionResponse) 370 require.True(t, errors.Is(err, ErrInvalidAuthToken)) 371 require.Empty(t, response) 372 }) 373 374 t.Run("save JWTVC to store - success", func(t *testing.T) { 375 sp := getMockStorageProvider() 376 377 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 378 require.NotEmpty(t, contentStore) 379 380 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 381 382 err := contentStore.Save(token, Credential, []byte(sampleJWTCredContentValid)) 383 require.NoError(t, err) 384 }) 385 386 t.Run("save key to store - success", func(t *testing.T) { 387 sp := getMockStorageProvider() 388 sampleUser := uuid.New().String() 389 390 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: sampleUser}) 391 require.NotEmpty(t, contentStore) 392 393 // wallet locked 394 err := contentStore.Save(sampleFakeTkn, Key, []byte(sampleKeyContentBase58Valid)) 395 require.True(t, errors.Is(err, ErrWalletLocked)) 396 397 err = contentStore.Save(sampleFakeTkn, Key, []byte(sampleKeyContentJwkValid)) 398 require.True(t, errors.Is(err, ErrWalletLocked)) 399 400 // unlock keymanager 401 masterLock, err := getDefaultSecretLock(samplePassPhrase) 402 require.NoError(t, err) 403 404 masterLockCipherText, err := createMasterLock(masterLock) 405 require.NoError(t, err) 406 require.NotEmpty(t, masterLockCipherText) 407 408 profileInfo := &profile{ 409 User: sampleUser, 410 MasterLockCipher: masterLockCipherText, 411 } 412 413 kmsStore, err := kms.NewAriesProviderWrapper(mockstorage.NewMockStoreProvider()) 414 require.NoError(t, err) 415 416 kmgr, err := keyManager().createKeyManager(profileInfo, kmsStore, 417 &unlockOpts{passphrase: samplePassPhrase}) 418 require.NotEmpty(t, kmgr) 419 require.NoError(t, err) 420 421 tkn, err := sessionManager().createSession(profileInfo.User, kmgr, 500*time.Millisecond) 422 423 require.NoError(t, err) 424 require.NotEmpty(t, tkn) 425 426 // import base58 private key 427 err = contentStore.Save(tkn, Key, []byte(sampleKeyContentBase58Valid), ValidateContent()) 428 require.NoError(t, err) 429 430 // import jwk private key 431 err = contentStore.Save(tkn, Key, []byte(sampleKeyContentJwkValid), ValidateContent()) 432 require.NoError(t, err) 433 434 // import using invalid auth token 435 err = contentStore.Save(tkn+"invalid", Key, []byte(sampleKeyContentBase58Valid)) 436 require.True(t, errors.Is(err, ErrWalletLocked)) 437 }) 438 439 t.Run("save key to store - invalid jsonld", func(t *testing.T) { 440 sp := getMockStorageProvider() 441 sampleUser := uuid.New().String() 442 443 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: sampleUser}) 444 require.NotEmpty(t, contentStore) 445 446 // unlock keymanager 447 masterLock, err := getDefaultSecretLock(samplePassPhrase) 448 require.NoError(t, err) 449 450 masterLockCipherText, err := createMasterLock(masterLock) 451 require.NoError(t, err) 452 require.NotEmpty(t, masterLockCipherText) 453 454 profileInfo := &profile{ 455 User: sampleUser, 456 MasterLockCipher: masterLockCipherText, 457 } 458 459 kmsStore, err := kms.NewAriesProviderWrapper(mockstorage.NewMockStoreProvider()) 460 require.NoError(t, err) 461 462 kmgr, err := keyManager().createKeyManager(profileInfo, kmsStore, 463 &unlockOpts{passphrase: samplePassPhrase}) 464 require.NotEmpty(t, kmgr) 465 require.NoError(t, err) 466 467 tkn, err := sessionManager().createSession(profileInfo.User, kmgr, 500*time.Millisecond) 468 469 require.NoError(t, err) 470 require.NotEmpty(t, tkn) 471 472 // import base58 private key 473 err = contentStore.Save(tkn, Key, []byte(sampleKeyContentBase58WithInvalidField), ValidateContent()) 474 require.Contains(t, err.Error(), "JSON-LD doc has different structure after compaction") 475 }) 476 477 t.Run("save JWTVC to store - failures", func(t *testing.T) { 478 sp := getMockStorageProvider() 479 480 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 481 require.NotEmpty(t, contentStore) 482 483 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 484 485 // assumes bad data is not JWT, fails to parse as JSON 486 err := contentStore.Save(token, Credential, []byte("f")) 487 require.Error(t, err) 488 require.Contains(t, err.Error(), "failed to read content to be saved") 489 490 // fail to decode payload that isn't base64 491 err = contentStore.Save(token, Credential, []byte("!!!!.!!!!.!!!!")) 492 require.Error(t, err) 493 require.Contains(t, err.Error(), "decode base64 JWT data") 494 495 // YWJjZGVm is abcdef in base64, so this isn't valid JSON 496 err = contentStore.Save(token, Credential, []byte("YWJjZGVm.YWJjZGVm.YWJjZGVm")) 497 require.Error(t, err) 498 require.Contains(t, err.Error(), "failed to unmarshal JWT data") 499 500 // e30 is {} in base64, so jwt is empty 501 err = contentStore.Save(token, Credential, []byte("e30.e30.signature")) 502 require.Error(t, err) 503 require.Contains(t, err.Error(), "JWT data has no ID") 504 }) 505 506 t.Run("save key to store - failure", func(t *testing.T) { 507 sp := getMockStorageProvider() 508 sampleUser := uuid.New().String() 509 510 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: sampleUser}) 511 require.NotEmpty(t, contentStore) 512 513 // wallet locked 514 err := contentStore.Save(token, Key, []byte("")) 515 require.Error(t, err) 516 require.Contains(t, err.Error(), "failed to read key contents") 517 }) 518 519 t.Run("save to doc resolution to store - failure", func(t *testing.T) { 520 sp := getMockStorageProvider() 521 522 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 523 require.NotEmpty(t, contentStore) 524 525 err := contentStore.Save(token, DIDResolutionResponse, []byte(sampleContentInvalid)) 526 require.Error(t, err) 527 require.Contains(t, err.Error(), "invalid DID resolution response model") 528 }) 529 530 t.Run("save to store - failures", func(t *testing.T) { 531 sp := getMockStorageProvider() 532 533 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 534 require.NotEmpty(t, contentStore) 535 536 // invalid content type 537 err := contentStore.Save(token, ContentType("invalid"), []byte(sampleContentValid)) 538 require.Error(t, err) 539 require.Contains(t, err.Error(), "invalid content type 'invalid'") 540 541 // invalid content 542 err = contentStore.Save(token, Credential, []byte("--")) 543 require.Error(t, err) 544 require.Contains(t, err.Error(), "failed to read content to be saved") 545 546 // store errors 547 sp.Store.ErrPut = errors.New(sampleContenttErr) 548 549 contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 550 require.NotEmpty(t, contentStore) 551 552 // wallet locked 553 err = contentStore.Save(token, Credential, []byte(sampleContentValid)) 554 require.True(t, errors.Is(err, ErrWalletLocked)) 555 556 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 557 558 err = contentStore.Save(token, Credential, []byte(sampleContentValid)) 559 require.Error(t, err) 560 require.Contains(t, err.Error(), sampleContenttErr) 561 562 sp.Store.ErrGet = errors.New(sampleContenttErr) 563 err = contentStore.Save(token, Credential, []byte(sampleContentValid)) 564 require.Error(t, err) 565 require.Contains(t, err.Error(), sampleContenttErr) 566 }) 567 568 t.Run("save to invalid content type - validation", func(t *testing.T) { 569 sp := getMockStorageProvider() 570 571 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 572 require.NotEmpty(t, contentStore) 573 574 err := contentStore.Save(token, "Test", []byte("{}")) 575 require.Error(t, err) 576 require.Contains(t, err.Error(), "invalid content type") 577 }) 578 579 t.Run("save duplicate items - validation", func(t *testing.T) { 580 sp := getMockStorageProvider() 581 582 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 583 require.NotEmpty(t, contentStore) 584 585 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 586 587 err := contentStore.Save(token, Collection, []byte(sampleContentValid)) 588 require.NoError(t, err) 589 590 // save again 591 err = contentStore.Save(token, Collection, []byte(sampleContentValid)) 592 require.Error(t, err) 593 require.Contains(t, err.Error(), "content with same type and id already exists in this wallet") 594 }) 595 596 t.Run("get from store - success", func(t *testing.T) { 597 sp := getMockStorageProvider() 598 599 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 600 require.NotEmpty(t, contentStore) 601 602 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 603 604 // save 605 err := contentStore.Save(token, Collection, []byte(sampleContentValid)) 606 require.NoError(t, err) 607 608 // get 609 content, err := contentStore.Get(token, "did:example:123456789abcdefghi", Collection) 610 require.NoError(t, err) 611 require.Equal(t, sampleContentValid, string(content)) 612 }) 613 614 t.Run("get from store - failure", func(t *testing.T) { 615 sp := getMockStorageProvider() 616 sp.Store.ErrGet = errors.New(sampleContenttErr) 617 618 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 619 require.NotEmpty(t, contentStore) 620 621 content, err := contentStore.Get(token, "did:example:123456789abcdefghi", Collection) 622 require.Empty(t, content) 623 require.True(t, errors.Is(err, ErrWalletLocked)) 624 625 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 626 627 // get 628 content, err = contentStore.Get(token, "did:example:123456789abcdefghi", Collection) 629 require.Empty(t, content) 630 require.Error(t, err) 631 require.Contains(t, err.Error(), sampleContenttErr) 632 }) 633 634 t.Run("remove from store - success", func(t *testing.T) { 635 sp := getMockStorageProvider() 636 637 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 638 require.NotEmpty(t, contentStore) 639 640 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 641 642 // save 643 err := contentStore.Save(token, Collection, []byte(sampleContentValid)) 644 require.NoError(t, err) 645 646 // get 647 content, err := contentStore.Get(token, "did:example:123456789abcdefghi", Collection) 648 require.NoError(t, err) 649 require.Equal(t, sampleContentValid, string(content)) 650 651 // remove 652 err = contentStore.Remove(token, "did:example:123456789abcdefghi", Collection) 653 require.NoError(t, err) 654 655 // get 656 content, err = contentStore.Get(token, "did:example:123456789abcdefghi", Collection) 657 require.Empty(t, content) 658 require.Error(t, err) 659 require.True(t, errors.Is(err, storage.ErrDataNotFound)) 660 }) 661 662 t.Run("remove from store - failure", func(t *testing.T) { 663 sp := getMockStorageProvider() 664 sp.Store.ErrDelete = errors.New(sampleContenttErr) 665 666 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 667 require.NotEmpty(t, contentStore) 668 669 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 670 671 // save 672 err := contentStore.Save(token, Collection, []byte(sampleContentValid)) 673 require.NoError(t, err) 674 675 // remove 676 err = contentStore.Remove(token, "did:example:123456789abcdefghi", Collection) 677 require.Error(t, err) 678 require.Contains(t, err.Error(), sampleContenttErr) 679 680 require.True(t, contentStore.Close()) 681 err = contentStore.Remove(token, "did:example:123456789abcdefghi", Collection) 682 require.True(t, errors.Is(err, ErrWalletLocked)) 683 }) 684 } 685 686 func TestContentStore_GetAll(t *testing.T) { 687 const vcContent = `{ 688 "@context": [ 689 "https://www.w3.org/2018/credentials/v1", 690 "https://www.w3.org/2018/credentials/examples/v1" 691 ], 692 "credentialSchema": [], 693 "credentialSubject": { 694 "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 695 "name": "Jayden Doe" 696 }, 697 "id": "%s", 698 "issuanceDate": "2010-01-01T19:23:24Z", 699 "issuer": { 700 "id": "did:example:76e12ec712ebc6f1c221ebfeb1f", 701 "name": "Example University" 702 }, 703 "type": [ 704 "VerifiableCredential", 705 "UniversityDegreeCredential" 706 ] 707 }` 708 709 const testMetadata = `{ 710 "@context": ["https://w3id.org/wallet/v1"], 711 "id": "%s", 712 "type": "Person", 713 "name": "John Smith", 714 "image": "https://via.placeholder.com/150", 715 "description" : "Professional software developer for Acme Corp." 716 }` 717 718 keyMgr := &mockkms.KeyManager{} 719 720 token, err := sessionManager().createSession(uuid.New().String(), keyMgr, 500*time.Millisecond) 721 require.NoError(t, err) 722 723 t.Run("get all content from store for credential type - success", func(t *testing.T) { 724 sp := getMockStorageProvider() 725 726 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 727 require.NotEmpty(t, contentStore) 728 729 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 730 731 // save test data 732 const count = 5 733 734 for i := 0; i < count; i++ { 735 require.NoError(t, contentStore.Save(token, 736 Credential, []byte(fmt.Sprintf(vcContent, uuid.New().String())))) 737 require.NoError(t, contentStore.Save(token, 738 Metadata, []byte(fmt.Sprintf(testMetadata, uuid.New().String())))) 739 } 740 741 allVcs, err := contentStore.GetAll(token, Credential) 742 require.NoError(t, err) 743 require.Len(t, allVcs, count) 744 745 allMetadata, err := contentStore.GetAll(token, Metadata) 746 require.NoError(t, err) 747 require.Len(t, allMetadata, count) 748 749 allDIDs, err := contentStore.GetAll(token, DIDResolutionResponse) 750 require.NoError(t, err) 751 require.Empty(t, allDIDs) 752 753 // store is open but invalid auth token 754 allMetadata, err = contentStore.GetAll(sampleFakeTkn, DIDResolutionResponse) 755 require.True(t, errors.Is(err, ErrInvalidAuthToken)) 756 require.Empty(t, allMetadata) 757 }) 758 759 t.Run("get all content from store for credential type - errors", func(t *testing.T) { 760 sp := getMockStorageProvider() 761 762 // wallet locked 763 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 764 765 allVcs, err := contentStore.GetAll(token, Credential) 766 require.True(t, errors.Is(err, ErrWalletLocked)) 767 require.Empty(t, allVcs) 768 769 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 770 require.NoError(t, contentStore.Save(token, Credential, []byte(fmt.Sprintf(vcContent, uuid.New().String())))) 771 772 // iterator value error 773 sp.MockStoreProvider.Store.ErrValue = errors.New(sampleContenttErr + uuid.New().String()) 774 775 allVcs, err = contentStore.GetAll(token, Credential) 776 require.True(t, errors.Is(err, sp.MockStoreProvider.Store.ErrValue)) 777 require.Empty(t, allVcs) 778 779 // iterator value error 780 sp.MockStoreProvider.Store.ErrKey = errors.New(sampleContenttErr + uuid.New().String()) 781 782 contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 783 require.NotEmpty(t, contentStore) 784 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 785 786 allVcs, err = contentStore.GetAll(token, Credential) 787 require.True(t, errors.Is(err, sp.MockStoreProvider.Store.ErrKey)) 788 require.Empty(t, allVcs) 789 790 // iterator next error 791 sp.MockStoreProvider.Store.ErrNext = errors.New(sampleContenttErr + uuid.New().String()) 792 793 contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 794 require.NotEmpty(t, contentStore) 795 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 796 797 require.NoError(t, contentStore.Save(token, Credential, []byte(fmt.Sprintf(vcContent, uuid.New().String())))) 798 799 allVcs, err = contentStore.GetAll(token, Credential) 800 require.True(t, errors.Is(err, sp.MockStoreProvider.Store.ErrNext)) 801 require.Empty(t, allVcs) 802 803 // iterator next error 804 sp.MockStoreProvider.Store.ErrQuery = errors.New(sampleContenttErr + uuid.New().String()) 805 806 contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 807 require.NotEmpty(t, contentStore) 808 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 809 810 allVcs, err = contentStore.GetAll(token, Credential) 811 require.True(t, errors.Is(err, sp.MockStoreProvider.Store.ErrQuery)) 812 require.Empty(t, allVcs) 813 }) 814 } 815 816 func TestContentDIDResolver(t *testing.T) { 817 keyMgr := &mockkms.KeyManager{} 818 819 token, err := sessionManager().createSession(uuid.New().String(), keyMgr, 500*time.Millisecond) 820 require.NoError(t, err) 821 822 t.Run("create new content store - success", func(t *testing.T) { 823 sp := getMockStorageProvider() 824 825 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 826 require.NotEmpty(t, contentStore) 827 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 828 829 // save custom DID 830 err := contentStore.Save(token, DIDResolutionResponse, testdata.SampleDocResolutionResponse) 831 require.NoError(t, err) 832 833 contentVDR := newContentBasedVDR(token, &vdr.MockVDRegistry{}, contentStore) 834 require.NotEmpty(t, contentVDR) 835 836 didDoc, err := contentVDR.Resolve("did:key:z6MknC1wwS6DEYwtGbZZo2QvjQjkh2qSBjb4GYmbye8dv4S5") 837 require.NoError(t, err) 838 require.NotEmpty(t, didDoc) 839 require.Equal(t, "did:key:z6MknC1wwS6DEYwtGbZZo2QvjQjkh2qSBjb4GYmbye8dv4S5", didDoc.DIDDocument.ID) 840 require.NotEmpty(t, didDoc.DIDDocument.Authentication) 841 842 didDoc, err = contentVDR.Resolve("did:key:invalid") 843 require.Error(t, err) 844 require.Equal(t, vdrapi.ErrNotFound, err) 845 require.Empty(t, didDoc) 846 }) 847 848 t.Run("create new content store - errors", func(t *testing.T) { 849 sp := getMockStorageProvider() 850 851 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 852 require.NotEmpty(t, contentStore) 853 854 contentVDR := newContentBasedVDR(token, &vdr.MockVDRegistry{}, contentStore) 855 require.NotEmpty(t, contentVDR) 856 857 // wallet locked 858 didDoc, err := contentVDR.Resolve("did:key:invalid") 859 require.True(t, errors.Is(err, ErrWalletLocked)) 860 require.Empty(t, didDoc) 861 862 // open store 863 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 864 865 // DID not found 866 didDoc, err = contentVDR.Resolve("did:key:invalid") 867 require.Error(t, err) 868 require.Equal(t, vdrapi.ErrNotFound, err) 869 require.Empty(t, didDoc) 870 871 // parse error 872 st, err := contentStore.open(token) 873 require.NoError(t, err) 874 err = st.Put(getContentKeyPrefix(DIDResolutionResponse, 875 "did:key:z6MknC1wwS6DEYwtGbZZo2QvjQjkh2qSBjb4GYmbye8dv4S5"), []byte(sampleInvalidDIDContent)) 876 require.NoError(t, err) 877 878 didDoc, err = contentVDR.Resolve("did:key:z6MknC1wwS6DEYwtGbZZo2QvjQjkh2qSBjb4GYmbye8dv4S5") 879 require.Error(t, err) 880 require.Contains(t, err.Error(), "failed to parse stored DID") 881 require.Empty(t, didDoc) 882 }) 883 } 884 885 func TestContentStore_Collections(t *testing.T) { 886 const vcContent = `{ 887 "@context": [ 888 "https://www.w3.org/2018/credentials/v1", 889 "https://www.w3.org/2018/credentials/examples/v1" 890 ], 891 "credentialSchema": [], 892 "credentialSubject": { 893 "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 894 "name": "Jayden Doe" 895 }, 896 "id": "%s", 897 "issuanceDate": "2010-01-01T19:23:24Z", 898 "issuer": { 899 "id": "did:example:76e12ec712ebc6f1c221ebfeb1f", 900 "name": "Example University" 901 }, 902 "type": [ 903 "VerifiableCredential", 904 "UniversityDegreeCredential" 905 ] 906 }` 907 908 const testMetadata = `{ 909 "@context": ["https://w3id.org/wallet/v1"], 910 "id": "%s", 911 "type": "Person", 912 "name": "John Smith", 913 "image": "https://via.placeholder.com/150", 914 "description" : "Professional software developer for Acme Corp." 915 }` 916 917 const connection = `{ 918 "@context": ["https://w3id.org/wallet/v1"], 919 "id": "%s", 920 "name": "My Health Record Certifier", 921 "image": "https://via.placeholder.com/150", 922 "description" : "The identifier that issues health record credentials.", 923 "tags": ["professional"], 924 "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"], 925 "type": "Connection" 926 }` 927 928 const orgCollection = `{ 929 "@context": ["https://w3id.org/wallet/v1"], 930 "id": "did:example:acme123456789abcdefghi", 931 "type": "Organization", 932 "name": "Acme Corp.", 933 "image": "https://via.placeholder.com/150", 934 "description" : "A software company.", 935 "tags": ["professional", "organization"], 936 "correlation": ["4058a72a-9523-11ea-bb37-0242ac130002"] 937 }` 938 939 const collectionID = "did:example:acme123456789abcdefghi" 940 941 keyMgr := &mockkms.KeyManager{} 942 943 token, err := sessionManager().createSession(uuid.New().String(), keyMgr, 500*time.Millisecond) 944 require.NoError(t, err) 945 946 t.Run("contents by collection - success", func(t *testing.T) { 947 sp := getMockStorageProvider() 948 949 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 950 require.NotEmpty(t, contentStore) 951 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 952 953 // save a collection 954 require.NoError(t, contentStore.Save(token, Collection, []byte(orgCollection))) 955 956 const addedWithoutCollection = 4 957 const addedToCollection = 3 958 959 // save test data 960 for i := 0; i < addedToCollection; i++ { 961 require.NoError(t, contentStore.Save(token, 962 Credential, []byte(fmt.Sprintf(vcContent, uuid.New().String())), AddByCollection(collectionID))) 963 require.NoError(t, contentStore.Save(token, 964 Metadata, []byte(fmt.Sprintf(testMetadata, uuid.New().String())), AddByCollection(collectionID))) 965 } 966 967 require.NoError(t, contentStore.Save(token, 968 DIDResolutionResponse, []byte(didResolutionResult), AddByCollection(collectionID))) 969 970 for i := 0; i < addedWithoutCollection; i++ { 971 require.NoError(t, contentStore.Save(token, 972 Credential, []byte(fmt.Sprintf(vcContent, uuid.New().String())))) 973 require.NoError(t, contentStore.Save(token, 974 Metadata, []byte(fmt.Sprintf(testMetadata, uuid.New().String())))) 975 require.NoError(t, contentStore.Save(token, 976 Connection, []byte(fmt.Sprintf(connection, uuid.New().String())))) 977 } 978 979 allVcs, err := contentStore.GetAll(token, Credential) 980 require.NoError(t, err) 981 require.Len(t, allVcs, addedWithoutCollection+addedToCollection) 982 983 allVcs, err = contentStore.GetAllByCollection(token, collectionID, Credential) 984 require.NoError(t, err) 985 require.Len(t, allVcs, addedToCollection) 986 987 allMetadata, err := contentStore.GetAll(token, Metadata) 988 require.NoError(t, err) 989 require.Len(t, allMetadata, addedWithoutCollection+addedToCollection) 990 991 allMetadata, err = contentStore.GetAllByCollection(token, collectionID, Metadata) 992 require.NoError(t, err) 993 require.Len(t, allMetadata, addedToCollection) 994 995 allDIDs, err := contentStore.GetAll(token, DIDResolutionResponse) 996 require.NoError(t, err) 997 require.Len(t, allDIDs, 1) 998 999 allDIDs, err = contentStore.GetAllByCollection(token, collectionID, DIDResolutionResponse) 1000 require.NoError(t, err) 1001 require.Len(t, allDIDs, 1) 1002 1003 allConns, err := contentStore.GetAll(token, Connection) 1004 require.NoError(t, err) 1005 require.Len(t, allConns, addedWithoutCollection) 1006 1007 allConns, err = contentStore.GetAllByCollection(token, collectionID, Connection) 1008 require.NoError(t, err) 1009 require.Empty(t, allConns) 1010 }) 1011 1012 t.Run("contents by collection - failure", func(t *testing.T) { 1013 sp := getMockStorageProvider() 1014 1015 contentStore := newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 1016 require.NotEmpty(t, contentStore) 1017 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 1018 1019 err := contentStore.Save(token, 1020 DIDResolutionResponse, []byte(didResolutionResult), AddByCollection(collectionID+"invalid")) 1021 require.Error(t, err) 1022 require.Contains(t, err.Error(), "failed to find existing collection") 1023 1024 err = contentStore.Save(token, 1025 Credential, []byte(fmt.Sprintf(vcContent, uuid.New().String())), AddByCollection(collectionID+"invalid")) 1026 require.Error(t, err) 1027 require.Contains(t, err.Error(), "failed to find existing collection") 1028 1029 // save a collection 1030 require.NoError(t, contentStore.Save(token, Collection, []byte(orgCollection))) 1031 require.NoError(t, contentStore.Save(token, Credential, []byte(fmt.Sprintf(vcContent, uuid.New().String())), 1032 AddByCollection(collectionID))) 1033 1034 // get content error 1035 sp.MockStoreProvider.Store.ErrGet = errors.New(sampleContenttErr + uuid.New().String()) 1036 1037 contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 1038 require.NotEmpty(t, contentStore) 1039 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 1040 1041 allVcs, err := contentStore.GetAllByCollection(token, collectionID, Credential) 1042 require.True(t, errors.Is(err, sp.MockStoreProvider.Store.ErrGet)) 1043 require.Empty(t, allVcs) 1044 1045 // iterator value error 1046 sp.MockStoreProvider.Store.ErrValue = errors.New(sampleContenttErr + uuid.New().String()) 1047 1048 contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 1049 require.NotEmpty(t, contentStore) 1050 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 1051 1052 allVcs, err = contentStore.GetAllByCollection(token, collectionID, Credential) 1053 require.True(t, errors.Is(err, sp.MockStoreProvider.Store.ErrValue)) 1054 require.Empty(t, allVcs) 1055 1056 // iterator value error 1057 sp.MockStoreProvider.Store.ErrKey = errors.New(sampleContenttErr + uuid.New().String()) 1058 1059 contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 1060 require.NotEmpty(t, contentStore) 1061 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 1062 1063 allVcs, err = contentStore.GetAllByCollection(token, collectionID, Credential) 1064 require.True(t, errors.Is(err, sp.MockStoreProvider.Store.ErrKey)) 1065 require.Empty(t, allVcs) 1066 1067 // iterator next error 1068 sp.MockStoreProvider.Store.ErrNext = errors.New(sampleContenttErr + uuid.New().String()) 1069 1070 contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 1071 require.NotEmpty(t, contentStore) 1072 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 1073 1074 allVcs, err = contentStore.GetAllByCollection(token, collectionID, Credential) 1075 require.True(t, errors.Is(err, sp.MockStoreProvider.Store.ErrNext)) 1076 require.Empty(t, allVcs) 1077 1078 // iterator next error 1079 sp.MockStoreProvider.Store.ErrQuery = errors.New(sampleContenttErr + uuid.New().String()) 1080 1081 contentStore = newContentStore(sp, createTestDocumentLoader(t), &profile{ID: uuid.New().String()}) 1082 require.NotEmpty(t, contentStore) 1083 require.NoError(t, contentStore.Open(keyMgr, &unlockOpts{})) 1084 1085 allVcs, err = contentStore.GetAllByCollection(token, collectionID, Credential) 1086 require.True(t, errors.Is(err, sp.MockStoreProvider.Store.ErrQuery)) 1087 require.Empty(t, allVcs) 1088 1089 // wallet locked error 1090 require.True(t, contentStore.Close()) 1091 allVcs, err = contentStore.GetAllByCollection(token, collectionID, Credential) 1092 require.True(t, errors.Is(err, ErrWalletLocked)) 1093 require.Empty(t, allVcs) 1094 }) 1095 } 1096 1097 type mockStorageProvider struct { 1098 *mockstorage.MockStoreProvider 1099 config storage.StoreConfiguration 1100 failure error 1101 } 1102 1103 func (s *mockStorageProvider) SetStoreConfig(name string, config storage.StoreConfiguration) error { 1104 s.config = config 1105 1106 return s.failure 1107 } 1108 1109 func (s *mockStorageProvider) GetStoreConfig(name string) (storage.StoreConfiguration, error) { 1110 return s.config, nil 1111 } 1112 1113 func getMockStorageProvider() *mockStorageProvider { 1114 return &mockStorageProvider{MockStoreProvider: mockstorage.NewMockStoreProvider()} 1115 } 1116 1117 func createTestDocumentLoader(t *testing.T) *ld.DocumentLoader { 1118 t.Helper() 1119 1120 loader, err := ldtestutil.DocumentLoader() 1121 require.NoError(t, err) 1122 1123 return loader 1124 }