github.com/hyperledger/aries-framework-go@v0.3.2/pkg/store/verifiable/store_test.go (about) 1 /* 2 Copyright SecureKey Technologies Inc. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package verifiable_test 8 9 import ( 10 "encoding/json" 11 "fmt" 12 "strconv" 13 "testing" 14 15 "github.com/stretchr/testify/require" 16 17 "github.com/hyperledger/aries-framework-go/pkg/doc/verifiable" 18 "github.com/hyperledger/aries-framework-go/pkg/internal/ldtestutil" 19 mockprovider "github.com/hyperledger/aries-framework-go/pkg/mock/provider" 20 mockstore "github.com/hyperledger/aries-framework-go/pkg/mock/storage" 21 . "github.com/hyperledger/aries-framework-go/pkg/store/verifiable" 22 "github.com/hyperledger/aries-framework-go/pkg/store/verifiable/internal" 23 ) 24 25 const ( 26 sampleCredentialName = "sampleVCName" 27 sampleCredentialID = "sampleVCID" 28 samplePresentationName = "sampleVPName" 29 samplePresentationID = "sampleVPID" 30 ) 31 32 //nolint:gochecknoglobals 33 var udCredential = ` 34 35 { 36 "@context": [ 37 "https://www.w3.org/2018/credentials/v1", 38 "https://www.w3.org/2018/credentials/examples/v1" 39 ], 40 "id": "http://example.edu/credentials/1872", 41 "type": [ 42 "VerifiableCredential", 43 "UniversityDegreeCredential" 44 ], 45 "credentialSubject": { 46 "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 47 "degree": { 48 "type": "BachelorDegree" 49 }, 50 "name": "Jayden Doe", 51 "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 52 }, 53 54 "issuer": { 55 "id": "did:example:76e12ec712ebc6f1c221ebfeb1f", 56 "name": "Example University" 57 }, 58 59 "issuanceDate": "2010-01-01T19:23:24Z", 60 61 "expirationDate": "2020-01-01T19:23:24Z", 62 63 "credentialStatus": { 64 "id": "https://example.edu/status/24", 65 "type": "CredentialStatusList2017" 66 }, 67 68 "evidence": [{ 69 "id": "https://example.edu/evidence/f2aeec97-fc0d-42bf-8ca7-0548192d4231", 70 "type": ["DocumentVerification"], 71 "verifier": "https://example.edu/issuers/14", 72 "evidenceDocument": "DriversLicense", 73 "subjectPresence": "Physical", 74 "documentPresence": "Physical" 75 },{ 76 "id": "https://example.edu/evidence/f2aeec97-fc0d-42bf-8ca7-0548192dxyzab", 77 "type": ["SupportingActivity"], 78 "verifier": "https://example.edu/issuers/14", 79 "evidenceDocument": "Fluid Dynamics Focus", 80 "subjectPresence": "Digital", 81 "documentPresence": "Digital" 82 }], 83 84 "termsOfUse": [ 85 { 86 "type": "IssuerPolicy", 87 "id": "http://example.com/policies/credential/4", 88 "profile": "http://example.com/profiles/credential", 89 "prohibition": [ 90 { 91 "assigner": "https://example.edu/issuers/14", 92 "assignee": "AllVerifiers", 93 "target": "http://example.edu/credentials/3732", 94 "action": [ 95 "Archival" 96 ] 97 } 98 ] 99 } 100 ], 101 102 "refreshService": { 103 "id": "https://example.edu/refresh/3732", 104 "type": "ManualRefreshService2018" 105 } 106 } 107 ` 108 109 //nolint:gochecknoglobals 110 var udCredentialWithoutID = ` 111 112 { 113 "@context": [ 114 "https://www.w3.org/2018/credentials/v1", 115 "https://www.w3.org/2018/credentials/examples/v1" 116 ], 117 "type": [ 118 "VerifiableCredential", 119 "UniversityDegreeCredential" 120 ], 121 "credentialSubject": { 122 "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 123 "degree": { 124 "type": "BachelorDegree" 125 }, 126 "name": "Jayden Doe", 127 "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 128 }, 129 130 "issuer": { 131 "id": "did:example:76e12ec712ebc6f1c221ebfeb1f", 132 "name": "Example University" 133 }, 134 135 "issuanceDate": "2010-01-01T19:23:24Z", 136 137 "expirationDate": "2020-01-01T19:23:24Z" 138 } 139 ` 140 141 //nolint:lll 142 const udVerifiablePresentation = `{ 143 "@context": ["https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1"], 144 "type": ["VerifiablePresentation"], 145 "holder": "did:example:ebfeb1f712ebc6f1c276e12ec21", 146 "verifiableCredential": [{ 147 "@context": ["https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1"], 148 "credentialSchema": [], 149 "credentialStatus": { 150 "id": "http://issuer.vc.rest.example.com:8070/status/1", 151 "type": "CredentialStatusList2017" 152 }, 153 "credentialSubject": { 154 "degree": {"degree": "MIT", "type": "BachelorDegree"}, 155 "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 156 "name": "Jayden Doe", 157 "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 158 }, 159 "id": "https://example.com/credentials/9315d0fd-da93-436e-9e20-2121f2821df3", 160 "issuanceDate": "2020-03-16T22:37:26.544Z", 161 "issuer": { 162 "id": "did:elem:EiBJJPdo-ONF0jxqt8mZYEj9Z7FbdC87m2xvN0_HAbcoEg", 163 "name": "alice_ca31684e-6cbb-40f9-b7e6-87e1ab5661ae" 164 }, 165 "proof": { 166 "created": "2020-04-08T21:19:02Z", 167 "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..yGHHYmRp4mWd918SDSzmBDs8eq-SX7WPl8moGB8oJeSqEMmuEiI81D4s5-BPWGmKy3VlCsKJxYrTNqrEGJpNAQ", 168 "proofPurpose": "assertionMethod", 169 "type": "Ed25519Signature2018", 170 "verificationMethod": "did:elem:EiBJJPdo-ONF0jxqt8mZYEj9Z7FbdC87m2xvN0_HAbcoEg#xqc3gS1gz1vch7R3RvNebWMjLvBOY-n_14feCYRPsUo" 171 }, 172 "type": ["VerifiableCredential", "UniversityDegreeCredential"] 173 }], 174 "proof": { 175 "created": "2020-04-08T17:19:05-04:00", 176 "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..0CH8GwphcMoQ0JHCm1O8n9ctM-s8hTfTuOa-WeQFSmPipaO41pECe7pQ4zDM6sp08W59pkrTz_U1PrwLlUyoBw", 177 "proofPurpose": "assertionMethod", 178 "type": "Ed25519Signature2018", 179 "verificationMethod": "did:elem:EiBJJPdo-ONF0jxqt8mZYEj9Z7FbdC87m2xvN0_HAbcoEg#xqc3gS1gz1vch7R3RvNebWMjLvBOY-n_14feCYRPsUo" 180 } 181 } 182 ` 183 184 //nolint:lll 185 const udPresentation = `{ 186 "@context": ["https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1"], 187 "type": ["VerifiablePresentation"], 188 "holder": "did:example:ebfeb1f712ebc6f1c276e12ec21", 189 "verifiableCredential": [{ 190 "@context": ["https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1"], 191 "credentialSchema": [], 192 "credentialStatus": { 193 "id": "http://issuer.vc.rest.example.com:8070/status/1", 194 "type": "CredentialStatusList2017" 195 }, 196 "credentialSubject": { 197 "degree": {"degree": "MIT", "type": "BachelorDegree"}, 198 "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 199 "name": "Jayden Doe", 200 "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" 201 }, 202 "id": "https://example.com/credentials/9315d0fd-da93-436e-9e20-2121f2821df3", 203 "issuanceDate": "2020-03-16T22:37:26.544Z", 204 "issuer": { 205 "id": "did:elem:EiBJJPdo-ONF0jxqt8mZYEj9Z7FbdC87m2xvN0_HAbcoEg", 206 "name": "alice_ca31684e-6cbb-40f9-b7e6-87e1ab5661ae" 207 }, 208 "proof": { 209 "created": "2020-04-08T21:19:02Z", 210 "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..yGHHYmRp4mWd918SDSzmBDs8eq-SX7WPl8moGB8oJeSqEMmuEiI81D4s5-BPWGmKy3VlCsKJxYrTNqrEGJpNAQ", 211 "proofPurpose": "assertionMethod", 212 "type": "Ed25519Signature2018", 213 "verificationMethod": "did:elem:EiBJJPdo-ONF0jxqt8mZYEj9Z7FbdC87m2xvN0_HAbcoEg#xqc3gS1gz1vch7R3RvNebWMjLvBOY-n_14feCYRPsUo" 214 }, 215 "type": ["VerifiableCredential", "UniversityDegreeCredential"] 216 }] 217 } 218 ` 219 220 func TestNew(t *testing.T) { 221 t.Run("test new store", func(t *testing.T) { 222 s, err := New(&mockprovider.Provider{ 223 StorageProviderValue: mockstore.NewMockStoreProvider(), 224 }) 225 require.NoError(t, err) 226 require.NotNil(t, s) 227 }) 228 229 t.Run("test error from open store", func(t *testing.T) { 230 s, err := New(&mockprovider.Provider{ 231 StorageProviderValue: &mockstore.MockStoreProvider{ 232 ErrOpenStoreHandle: fmt.Errorf("failed to open store"), 233 }, 234 }) 235 require.Error(t, err) 236 require.Contains(t, err.Error(), "failed to open store") 237 require.Nil(t, s) 238 }) 239 } 240 241 func TestSaveVC(t *testing.T) { 242 t.Run("test save vc - success", func(t *testing.T) { 243 s, err := New(&mockprovider.Provider{ 244 StorageProviderValue: mockstore.NewMockStoreProvider(), 245 }) 246 require.NoError(t, err) 247 require.NoError(t, s.SaveCredential(sampleCredentialName, &verifiable.Credential{ID: "vc1"})) 248 }) 249 250 t.Run("test save vc - error from store put", func(t *testing.T) { 251 s, err := New(&mockprovider.Provider{ 252 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 253 Store: make(map[string]mockstore.DBEntry), 254 ErrPut: fmt.Errorf("error put"), 255 }), 256 }) 257 require.NoError(t, err) 258 err = s.SaveCredential(sampleCredentialName, &verifiable.Credential{ID: "vc1"}) 259 require.Error(t, err) 260 require.Contains(t, err.Error(), "error put") 261 }) 262 263 t.Run("test save vc - empty name", func(t *testing.T) { 264 s, err := New(&mockprovider.Provider{ 265 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 266 Store: make(map[string]mockstore.DBEntry), 267 ErrPut: fmt.Errorf("error put"), 268 }), 269 }) 270 require.NoError(t, err) 271 err = s.SaveCredential("", &verifiable.Credential{ID: "vc1"}) 272 require.Error(t, err) 273 require.Contains(t, err.Error(), "credential name is mandatory") 274 }) 275 276 t.Run("test save vc - error getting existing mapping for name", func(t *testing.T) { 277 s, err := New(&mockprovider.Provider{ 278 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 279 Store: make(map[string]mockstore.DBEntry), 280 ErrGet: fmt.Errorf("error get"), 281 }), 282 }) 283 require.NoError(t, err) 284 err = s.SaveCredential(sampleCredentialName, &verifiable.Credential{ID: "vc1"}) 285 require.Error(t, err) 286 require.Contains(t, err.Error(), "get credential id using name") 287 }) 288 289 t.Run("test save vc - name already exists", func(t *testing.T) { 290 s, err := New(&mockprovider.Provider{ 291 StorageProviderValue: mockstore.NewMockStoreProvider(), 292 }) 293 require.NoError(t, err) 294 require.NoError(t, s.SaveCredential(sampleCredentialName, &verifiable.Credential{ID: "vc1"})) 295 296 err = s.SaveCredential(sampleCredentialName, &verifiable.Credential{ID: "vc2"}) 297 require.Error(t, err) 298 require.Contains(t, err.Error(), "credential name already exists") 299 }) 300 301 t.Run("test save vc - with options", func(t *testing.T) { 302 const ( 303 MyDID = "MyDID" 304 TheirDID = "TheirDID" 305 ) 306 s, err := New(&mockprovider.Provider{ 307 StorageProviderValue: mockstore.NewMockStoreProvider(), 308 }) 309 require.NoError(t, err) 310 require.NoError(t, s.SaveCredential(sampleCredentialName, &verifiable.Credential{ID: "vc1"}, 311 WithMyDID(MyDID), WithTheirDID(TheirDID))) 312 313 records, err := s.GetCredentials() 314 require.NoError(t, err) 315 require.Equal(t, 1, len(records)) 316 317 require.Equal(t, MyDID, records[0].MyDID) 318 require.Equal(t, TheirDID, records[0].TheirDID) 319 }) 320 } 321 322 func TestGetVC(t *testing.T) { 323 loader, err := ldtestutil.DocumentLoader() 324 require.NoError(t, err) 325 326 t.Run("test success", func(t *testing.T) { 327 s, err := New(&mockprovider.Provider{ 328 StorageProviderValue: mockstore.NewMockStoreProvider(), 329 DocumentLoaderValue: loader, 330 }) 331 require.NoError(t, err) 332 udVC, err := verifiable.ParseCredential([]byte(udCredential), 333 verifiable.WithJSONLDDocumentLoader(loader)) 334 require.NoError(t, err) 335 require.NoError(t, s.SaveCredential(sampleCredentialName, udVC)) 336 vc, err := s.GetCredential("http://example.edu/credentials/1872") 337 require.NoError(t, err) 338 require.Equal(t, vc.ID, "http://example.edu/credentials/1872") 339 340 records, err := s.GetCredentials() 341 require.NoError(t, err) 342 require.NotEmpty(t, records) 343 344 for _, r := range records { 345 require.Equal(t, "did:example:ebfeb1f712ebc6f1c276e12ec21", r.SubjectID) 346 require.Equal(t, "http://example.edu/credentials/1872", r.ID) 347 require.Equal(t, "sampleVCName", r.Name) 348 } 349 }) 350 351 t.Run("test success - vc without ID", func(t *testing.T) { 352 s, err := New(&mockprovider.Provider{ 353 StorageProviderValue: mockstore.NewMockStoreProvider(), 354 DocumentLoaderValue: loader, 355 }) 356 require.NoError(t, err) 357 udVC, err := verifiable.ParseCredential([]byte(udCredentialWithoutID), 358 verifiable.WithJSONLDDocumentLoader(loader)) 359 require.NoError(t, err) 360 require.NoError(t, s.SaveCredential(sampleCredentialName, udVC)) 361 362 id, err := s.GetCredentialIDByName(sampleCredentialName) 363 require.NoError(t, err) 364 require.NotEmpty(t, id) 365 366 vc, err := s.GetCredential(id) 367 require.NoError(t, err) 368 require.NotEmpty(t, vc) 369 }) 370 371 t.Run("test error from store get", func(t *testing.T) { 372 s, err := New(&mockprovider.Provider{ 373 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 374 Store: make(map[string]mockstore.DBEntry), 375 ErrGet: fmt.Errorf("error get"), 376 }), 377 DocumentLoaderValue: loader, 378 }) 379 require.NoError(t, err) 380 vc, err := s.GetCredential("vc1") 381 require.Error(t, err) 382 require.Contains(t, err.Error(), "error get") 383 require.Nil(t, vc) 384 }) 385 386 t.Run("test error from new credential", func(t *testing.T) { 387 s, err := New(&mockprovider.Provider{ 388 StorageProviderValue: mockstore.NewMockStoreProvider(), 389 DocumentLoaderValue: loader, 390 }) 391 require.NoError(t, err) 392 require.NoError(t, s.SaveCredential(sampleCredentialName, &verifiable.Credential{ID: "vc1"})) 393 require.NoError(t, err) 394 vc, err := s.GetCredential("vc1") 395 require.Error(t, err) 396 require.Contains(t, err.Error(), "credential type of unknown structure") 397 require.Nil(t, vc) 398 }) 399 } 400 401 func TestGetCredentialIDBasedOnName(t *testing.T) { 402 t.Run("test get credential based on name - success", func(t *testing.T) { 403 rbytes, err := json.Marshal(&Record{ 404 ID: sampleCredentialID, 405 Name: "", 406 Context: nil, 407 Type: nil, 408 SubjectID: "", 409 }, 410 ) 411 require.NoError(t, err) 412 413 store := make(map[string]mockstore.DBEntry) 414 store[internal.CredentialNameDataKey(sampleCredentialName)] = mockstore.DBEntry{Value: rbytes} 415 416 s, err := New(&mockprovider.Provider{ 417 StorageProviderValue: &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: store}}, 418 }) 419 require.NoError(t, err) 420 421 id, err := s.GetCredentialIDByName(sampleCredentialName) 422 require.NoError(t, err) 423 require.Equal(t, sampleCredentialID, id) 424 425 id, err = s.GetCredentialIDByName("some-random-id") 426 require.Error(t, err) 427 require.Empty(t, id) 428 require.Contains(t, err.Error(), "fetch credential id based on name : data not found") 429 }) 430 431 t.Run("test get credential based on name - db error", func(t *testing.T) { 432 s, err := New(&mockprovider.Provider{ 433 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 434 Store: make(map[string]mockstore.DBEntry), 435 ErrGet: fmt.Errorf("error get"), 436 }), 437 }) 438 require.NoError(t, err) 439 440 id, err := s.GetCredentialIDByName(sampleCredentialName) 441 require.Error(t, err) 442 require.Contains(t, err.Error(), "fetch credential id based on name") 443 require.Equal(t, "", id) 444 }) 445 } 446 447 func TestGetCredentials(t *testing.T) { 448 t.Run("test get credentials", func(t *testing.T) { 449 store := make(map[string]mockstore.DBEntry) 450 s, err := New(&mockprovider.Provider{ 451 StorageProviderValue: &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: store}}, 452 }) 453 require.NoError(t, err) 454 455 records, err := s.GetCredentials() 456 require.NoError(t, err) 457 require.Equal(t, 0, len(records)) 458 459 err = s.SaveCredential(sampleCredentialName, &verifiable.Credential{ID: sampleCredentialID}) 460 require.NoError(t, err) 461 462 records, err = s.GetCredentials() 463 require.NoError(t, err) 464 require.Equal(t, 1, len(records)) 465 require.Equal(t, records[0].Name, sampleCredentialName) 466 require.Equal(t, records[0].ID, sampleCredentialID) 467 468 // add some other values and make sure the GetCredential returns records as before 469 store["dummy-value"] = mockstore.DBEntry{Value: []byte("dummy-key")} 470 471 records, err = s.GetCredentials() 472 require.NoError(t, err) 473 require.Equal(t, 1, len(records)) 474 475 n := 10 476 for i := 0; i < n; i++ { 477 err = s.SaveCredential(sampleCredentialName+strconv.Itoa(i), 478 &verifiable.Credential{ID: sampleCredentialID + strconv.Itoa(i)}) 479 require.NoError(t, err) 480 } 481 482 records, err = s.GetCredentials() 483 require.Equal(t, 1+n, len(records)) 484 require.NoError(t, err) 485 }) 486 } 487 488 func TestSaveVP(t *testing.T) { 489 t.Run("test save vp - success", func(t *testing.T) { 490 s, err := New(&mockprovider.Provider{ 491 StorageProviderValue: mockstore.NewMockStoreProvider(), 492 }) 493 require.NoError(t, err) 494 require.NoError(t, s.SavePresentation(samplePresentationName, &verifiable.Presentation{ID: "vp1"})) 495 }) 496 497 t.Run("test save vp - error from store put", func(t *testing.T) { 498 s, err := New(&mockprovider.Provider{ 499 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 500 Store: make(map[string]mockstore.DBEntry), 501 ErrPut: fmt.Errorf("error put"), 502 }), 503 }) 504 require.NoError(t, err) 505 err = s.SavePresentation(samplePresentationName, &verifiable.Presentation{ID: "vp1"}) 506 require.Error(t, err) 507 require.Contains(t, err.Error(), "error put") 508 }) 509 510 t.Run("test save vp - empty name", func(t *testing.T) { 511 s, err := New(&mockprovider.Provider{ 512 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 513 Store: make(map[string]mockstore.DBEntry), 514 ErrPut: fmt.Errorf("error put"), 515 }), 516 }) 517 require.NoError(t, err) 518 err = s.SavePresentation("", &verifiable.Presentation{ID: "vp1"}) 519 require.Error(t, err) 520 require.Contains(t, err.Error(), "presentation name is mandatory") 521 }) 522 523 t.Run("test save vp - error getting existing mapping for name", func(t *testing.T) { 524 s, err := New(&mockprovider.Provider{ 525 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 526 Store: make(map[string]mockstore.DBEntry), 527 ErrGet: fmt.Errorf("error get"), 528 }), 529 }) 530 require.NoError(t, err) 531 err = s.SavePresentation(samplePresentationName, &verifiable.Presentation{ID: "vp1"}) 532 require.Error(t, err) 533 require.Contains(t, err.Error(), "get presentation id using name") 534 }) 535 536 t.Run("test save vp - name already exists", func(t *testing.T) { 537 s, err := New(&mockprovider.Provider{ 538 StorageProviderValue: mockstore.NewMockStoreProvider(), 539 }) 540 require.NoError(t, err) 541 require.NoError(t, s.SavePresentation(samplePresentationName, &verifiable.Presentation{ID: "vp1"})) 542 543 err = s.SavePresentation(samplePresentationName, &verifiable.Presentation{ID: "vp2"}) 544 require.Error(t, err) 545 require.Contains(t, err.Error(), "presentation name already exists") 546 }) 547 548 t.Run("test save vp - with options", func(t *testing.T) { 549 const ( 550 MyDID = "MyDID" 551 TheirDID = "TheirDID" 552 ) 553 s, err := New(&mockprovider.Provider{ 554 StorageProviderValue: mockstore.NewMockStoreProvider(), 555 }) 556 require.NoError(t, err) 557 require.NoError(t, s.SavePresentation(samplePresentationName, &verifiable.Presentation{ID: "vp1"}, 558 WithMyDID(MyDID), WithTheirDID(TheirDID))) 559 560 records, err := s.GetPresentations() 561 require.NoError(t, err) 562 require.Equal(t, 1, len(records)) 563 564 require.Equal(t, MyDID, records[0].MyDID) 565 require.Equal(t, TheirDID, records[0].TheirDID) 566 }) 567 } 568 569 func TestGetVP(t *testing.T) { 570 loader, err := ldtestutil.DocumentLoader() 571 require.NoError(t, err) 572 573 t.Run("test success - save presentation", func(t *testing.T) { 574 s, err := New(&mockprovider.Provider{ 575 StorageProviderValue: mockstore.NewMockStoreProvider(), 576 DocumentLoaderValue: loader, 577 }) 578 require.NoError(t, err) 579 udVP, err := verifiable.ParsePresentation([]byte(udPresentation), 580 verifiable.WithPresDisabledProofCheck(), 581 verifiable.WithPresJSONLDDocumentLoader(loader)) 582 require.NoError(t, err) 583 require.NoError(t, s.SavePresentation(samplePresentationName, udVP)) 584 585 id, err := s.GetPresentationIDByName(samplePresentationName) 586 require.NoError(t, err) 587 require.NotEmpty(t, id) 588 589 vp, err := s.GetPresentation(id) 590 require.NoError(t, err) 591 require.Equal(t, vp.Type[0], "VerifiablePresentation") 592 require.NotEmpty(t, vp.Credentials()) 593 require.EqualValues(t, vp.Credentials()[0].(map[string]interface{})["id"], 594 "https://example.com/credentials/9315d0fd-da93-436e-9e20-2121f2821df3") 595 }) 596 597 t.Run("test success - save VP", func(t *testing.T) { 598 s, err := New(&mockprovider.Provider{ 599 StorageProviderValue: mockstore.NewMockStoreProvider(), 600 DocumentLoaderValue: loader, 601 }) 602 require.NoError(t, err) 603 udVP, err := verifiable.ParsePresentation([]byte(udVerifiablePresentation), 604 verifiable.WithPresDisabledProofCheck(), 605 verifiable.WithPresJSONLDDocumentLoader(loader)) 606 require.NoError(t, err) 607 require.NoError(t, s.SavePresentation(samplePresentationName, udVP)) 608 609 id, err := s.GetPresentationIDByName(samplePresentationName) 610 require.NoError(t, err) 611 require.NotEmpty(t, id) 612 613 vp, err := s.GetPresentation(id) 614 require.NoError(t, err) 615 require.Equal(t, vp.Type[0], "VerifiablePresentation") 616 require.NotEmpty(t, vp.Credentials()) 617 require.EqualValues(t, vp.Credentials()[0].(map[string]interface{})["id"], 618 "https://example.com/credentials/9315d0fd-da93-436e-9e20-2121f2821df3") 619 }) 620 621 t.Run("test error from store get", func(t *testing.T) { 622 s, err := New(&mockprovider.Provider{ 623 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 624 Store: make(map[string]mockstore.DBEntry), 625 ErrGet: fmt.Errorf("error get"), 626 }), 627 DocumentLoaderValue: loader, 628 }) 629 require.NoError(t, err) 630 vp, err := s.GetPresentation("vpxyz") 631 require.Error(t, err) 632 require.Contains(t, err.Error(), "error get") 633 require.Nil(t, vp) 634 }) 635 636 t.Run("test error from new presentation", func(t *testing.T) { 637 s, err := New(&mockprovider.Provider{ 638 StorageProviderValue: mockstore.NewMockStoreProvider(), 639 DocumentLoaderValue: loader, 640 }) 641 require.NoError(t, err) 642 require.NoError(t, s.SavePresentation(samplePresentationName, &verifiable.Presentation{ID: "vp1"})) 643 require.NoError(t, err) 644 645 vc, err := s.GetPresentation("vp1") 646 require.Error(t, err) 647 require.Contains(t, err.Error(), "verifiable presentation is not valid") 648 require.Nil(t, vc) 649 }) 650 } 651 652 func TestGetPresentationIDBasedOnName(t *testing.T) { 653 t.Run("test get presentation based on name - success", func(t *testing.T) { 654 rbytes, err := json.Marshal(&Record{ 655 ID: samplePresentationID, 656 Name: "", 657 Context: nil, 658 Type: nil, 659 SubjectID: "", 660 }, 661 ) 662 require.NoError(t, err) 663 664 store := make(map[string]mockstore.DBEntry) 665 store[internal.PresentationNameDataKey(samplePresentationName)] = mockstore.DBEntry{Value: rbytes} 666 667 s, err := New(&mockprovider.Provider{ 668 StorageProviderValue: &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: store}}, 669 }) 670 require.NoError(t, err) 671 672 id, err := s.GetPresentationIDByName(samplePresentationName) 673 require.NoError(t, err) 674 require.Equal(t, samplePresentationID, id) 675 }) 676 677 t.Run("test get presentation based on name - db error", func(t *testing.T) { 678 s, err := New(&mockprovider.Provider{ 679 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 680 Store: make(map[string]mockstore.DBEntry), 681 ErrGet: fmt.Errorf("error get"), 682 }), 683 }) 684 require.NoError(t, err) 685 686 id, err := s.GetPresentationIDByName(samplePresentationName) 687 require.Error(t, err) 688 require.Contains(t, err.Error(), "fetch presentation id based on name") 689 require.Equal(t, "", id) 690 }) 691 } 692 693 func TestGetPresentations(t *testing.T) { 694 t.Run("test get save & presentations", func(t *testing.T) { 695 store := make(map[string]mockstore.DBEntry) 696 s, err := New(&mockprovider.Provider{ 697 StorageProviderValue: &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: store}}, 698 }) 699 require.NoError(t, err) 700 701 records, err := s.GetPresentations() 702 require.NoError(t, err) 703 require.Equal(t, 0, len(records)) 704 705 err = s.SavePresentation(samplePresentationName, &verifiable.Presentation{ID: samplePresentationID}) 706 require.NoError(t, err) 707 708 records, err = s.GetPresentations() 709 require.NoError(t, err) 710 require.Equal(t, 1, len(records)) 711 require.Equal(t, records[0].Name, samplePresentationName) 712 require.Equal(t, records[0].ID, samplePresentationID) 713 714 // add some other values and make sure the GetCredential returns records as before 715 store["dummy-value"] = mockstore.DBEntry{Value: []byte("dummy-key")} 716 717 records, err = s.GetPresentations() 718 require.NoError(t, err) 719 require.Equal(t, 1, len(records)) 720 721 n := 10 722 for i := 0; i < n; i++ { 723 err = s.SavePresentation(samplePresentationName+strconv.Itoa(i), 724 &verifiable.Presentation{ID: samplePresentationID + strconv.Itoa(i)}) 725 require.NoError(t, err) 726 } 727 728 records, err = s.GetPresentations() 729 require.NoError(t, err) 730 require.Len(t, records, 1+n) 731 }) 732 733 t.Run("test get presentations", func(t *testing.T) { 734 loader, err := ldtestutil.DocumentLoader() 735 require.NoError(t, err) 736 737 store := make(map[string]mockstore.DBEntry) 738 s, err := New(&mockprovider.Provider{ 739 StorageProviderValue: &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: store}}, 740 DocumentLoaderValue: loader, 741 }) 742 require.NoError(t, err) 743 744 udVP, err := verifiable.ParsePresentation([]byte(udVerifiablePresentation), 745 verifiable.WithPresDisabledProofCheck(), 746 verifiable.WithPresJSONLDDocumentLoader(loader)) 747 require.NoError(t, err) 748 require.NoError(t, s.SavePresentation(samplePresentationName, udVP)) 749 750 records, err := s.GetPresentations() 751 require.NoError(t, err) 752 require.Len(t, records, 1) 753 754 require.Equal(t, records[0].Name, samplePresentationName) 755 require.Equal(t, records[0].SubjectID, udVP.Holder) 756 }) 757 } 758 759 func TestRemoveVC(t *testing.T) { 760 loader, err := ldtestutil.DocumentLoader() 761 require.NoError(t, err) 762 763 t.Run("test remove vc - success", func(t *testing.T) { 764 s, err := New(&mockprovider.Provider{ 765 StorageProviderValue: mockstore.NewMockStoreProvider(), 766 DocumentLoaderValue: loader, 767 }) 768 require.NoError(t, err) 769 udVC, err := verifiable.ParseCredential([]byte(udCredential), 770 verifiable.WithDisabledProofCheck(), 771 verifiable.WithJSONLDDocumentLoader(loader)) 772 require.NoError(t, err) 773 require.NoError(t, s.SaveCredential(sampleCredentialName, udVC)) 774 775 id, err := s.GetCredentialIDByName(sampleCredentialName) 776 require.NoError(t, err) 777 require.NotEmpty(t, id) 778 779 vc, err := s.GetCredential(id) 780 require.NoError(t, err) 781 require.Equal(t, vc.Types[0], "VerifiableCredential") 782 require.EqualValues(t, vc.ID, 783 "http://example.edu/credentials/1872") 784 785 err = s.RemoveCredentialByName(sampleCredentialName) 786 require.NoError(t, err) 787 788 _, err = s.GetCredentialIDByName(sampleCredentialName) 789 require.Error(t, err) 790 791 _, err = s.GetCredential(id) 792 require.Error(t, err) 793 }) 794 t.Run("test remove vc - error from store delete", func(t *testing.T) { 795 s, err := New(&mockprovider.Provider{ 796 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 797 Store: make(map[string]mockstore.DBEntry), 798 ErrDelete: fmt.Errorf("error delete"), 799 }), 800 DocumentLoaderValue: loader, 801 }) 802 require.NoError(t, err) 803 udVC, err := verifiable.ParseCredential([]byte(udCredential), 804 verifiable.WithDisabledProofCheck(), 805 verifiable.WithJSONLDDocumentLoader(loader)) 806 require.NoError(t, err) 807 require.NoError(t, s.SaveCredential(sampleCredentialName, udVC)) 808 809 err = s.RemoveCredentialByName(sampleCredentialName) 810 require.Error(t, err) 811 require.Contains(t, err.Error(), "unable to delete credential") 812 }) 813 t.Run("test remove vc - empty name", func(t *testing.T) { 814 s, err := New(&mockprovider.Provider{ 815 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 816 Store: make(map[string]mockstore.DBEntry), 817 }), 818 }) 819 require.NoError(t, err) 820 err = s.RemoveCredentialByName("") 821 require.Error(t, err) 822 require.Contains(t, err.Error(), "credential name is mandatory") 823 }) 824 t.Run("test remove vc - error removing non-existing credential", func(t *testing.T) { 825 s, err := New(&mockprovider.Provider{ 826 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 827 Store: make(map[string]mockstore.DBEntry), 828 }), 829 }) 830 require.NoError(t, err) 831 err = s.RemoveCredentialByName(sampleCredentialName) 832 require.Error(t, err) 833 require.Contains(t, err.Error(), "get credential id using name") 834 }) 835 t.Run("test remove vc - error removing non-existing credential", func(t *testing.T) { 836 s, err := New(&mockprovider.Provider{ 837 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 838 Store: make(map[string]mockstore.DBEntry), 839 ErrGet: fmt.Errorf("error get"), 840 }), 841 }) 842 require.NoError(t, err) 843 err = s.RemoveCredentialByName(sampleCredentialName) 844 require.Error(t, err) 845 require.Contains(t, err.Error(), "get credential id using name") 846 }) 847 } 848 849 func TestRemoveVP(t *testing.T) { 850 loader, err := ldtestutil.DocumentLoader() 851 require.NoError(t, err) 852 853 t.Run("test remove vp - success", func(t *testing.T) { 854 s, err := New(&mockprovider.Provider{ 855 StorageProviderValue: mockstore.NewMockStoreProvider(), 856 DocumentLoaderValue: loader, 857 }) 858 require.NoError(t, err) 859 udVP, err := verifiable.ParsePresentation([]byte(udPresentation), 860 verifiable.WithPresDisabledProofCheck(), 861 verifiable.WithPresJSONLDDocumentLoader(loader)) 862 require.NoError(t, err) 863 require.NoError(t, s.SavePresentation(samplePresentationName, udVP)) 864 865 id, err := s.GetPresentationIDByName(samplePresentationName) 866 require.NoError(t, err) 867 require.NotEmpty(t, id) 868 869 vp, err := s.GetPresentation(id) 870 require.NoError(t, err) 871 require.Equal(t, vp.Type[0], "VerifiablePresentation") 872 require.NotEmpty(t, vp.Credentials()) 873 require.EqualValues(t, vp.Credentials()[0].(map[string]interface{})["id"], 874 "https://example.com/credentials/9315d0fd-da93-436e-9e20-2121f2821df3") 875 876 err = s.RemovePresentationByName(samplePresentationName) 877 require.NoError(t, err) 878 879 _, err = s.GetPresentationIDByName(samplePresentationName) 880 require.Error(t, err) 881 882 _, err = s.GetPresentation(id) 883 require.Error(t, err) 884 }) 885 886 t.Run("test remove vp - error from store delete", func(t *testing.T) { 887 s, err := New(&mockprovider.Provider{ 888 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 889 Store: make(map[string]mockstore.DBEntry), 890 ErrDelete: fmt.Errorf("error delete"), 891 }), 892 DocumentLoaderValue: loader, 893 }) 894 require.NoError(t, err) 895 udVP, err := verifiable.ParsePresentation([]byte(udPresentation), 896 verifiable.WithPresDisabledProofCheck(), 897 verifiable.WithPresJSONLDDocumentLoader(loader)) 898 require.NoError(t, err) 899 require.NoError(t, s.SavePresentation(samplePresentationName, udVP)) 900 901 err = s.RemovePresentationByName(samplePresentationName) 902 require.Error(t, err) 903 require.Contains(t, err.Error(), "unable to delete presentation") 904 }) 905 t.Run("test remove vp - empty name", func(t *testing.T) { 906 s, err := New(&mockprovider.Provider{ 907 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 908 Store: make(map[string]mockstore.DBEntry), 909 }), 910 }) 911 require.NoError(t, err) 912 err = s.RemovePresentationByName("") 913 require.Error(t, err) 914 require.Contains(t, err.Error(), "presentation name is mandatory") 915 }) 916 t.Run("test remove vp - error removing non-existing presentation", func(t *testing.T) { 917 s, err := New(&mockprovider.Provider{ 918 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 919 Store: make(map[string]mockstore.DBEntry), 920 }), 921 }) 922 require.NoError(t, err) 923 err = s.RemovePresentationByName(samplePresentationName) 924 require.Error(t, err) 925 require.Contains(t, err.Error(), "get presentation id using name") 926 }) 927 t.Run("test remove vp - error getting id", func(t *testing.T) { 928 s, err := New(&mockprovider.Provider{ 929 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 930 Store: make(map[string]mockstore.DBEntry), 931 ErrGet: fmt.Errorf("error get"), 932 }), 933 }) 934 require.NoError(t, err) 935 err = s.RemovePresentationByName(samplePresentationName) 936 require.Error(t, err) 937 require.Contains(t, err.Error(), "get presentation id using name") 938 }) 939 }