github.com/hyperledger/aries-framework-go@v0.3.2/pkg/doc/verifiable/presentation_test.go (about) 1 /* 2 Copyright SecureKey Technologies Inc. All Rights Reserved. 3 SPDX-License-Identifier: Apache-2.0 4 */ 5 6 package verifiable 7 8 import ( 9 _ "embed" 10 "encoding/json" 11 "testing" 12 13 jsonld "github.com/piprate/json-gold/ld" 14 "github.com/stretchr/testify/require" 15 16 "github.com/hyperledger/aries-framework-go/pkg/doc/ldcontext" 17 jsonldsig "github.com/hyperledger/aries-framework-go/pkg/doc/signature/jsonld" 18 "github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite" 19 "github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/ed25519signature2018" 20 "github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier" 21 "github.com/hyperledger/aries-framework-go/pkg/internal/ldtestutil" 22 "github.com/hyperledger/aries-framework-go/pkg/kms" 23 ) 24 25 const validPresentation = ` 26 { 27 "@context": [ 28 "https://www.w3.org/2018/credentials/v1", 29 "https://www.w3.org/2018/credentials/examples/v1", 30 "https://trustbloc.github.io/context/vc/examples-v1.jsonld" 31 ], 32 "id": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5", 33 "type": "VerifiablePresentation", 34 "verifiableCredential": [ 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/58473", 41 "type": ["VerifiableCredential", "UniversityDegreeCredential"], 42 "issuer": "https://example.edu/issuers/14", 43 "issuanceDate": "2010-01-01T19:23:24Z", 44 "credentialSubject": { 45 "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 46 "alumniOf": "Example University" 47 }, 48 "proof": { 49 "type": "RsaSignature2018" 50 } 51 } 52 ], 53 "holder": "did:example:ebfeb1f712ebc6f1c276e12ec21" 54 } 55 ` 56 57 const presentationWithoutCredentials = ` 58 { 59 "@context": [ 60 "https://www.w3.org/2018/credentials/v1", 61 "https://www.w3.org/2018/credentials/examples/v1", 62 "https://trustbloc.github.io/context/vc/examples-v1.jsonld" 63 ], 64 "id": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5", 65 "type": "VerifiablePresentation", 66 "holder": "did:example:ebfeb1f712ebc6f1c276e12ec21" 67 } 68 ` 69 70 const validPresentationWithCustomFields = ` 71 { 72 "@context": [ 73 "https://www.w3.org/2018/credentials/v1", 74 "https://trustbloc.github.io/context/vc/presentation-exchange-submission-v1.jsonld" 75 ], 76 "id": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5", 77 "type": [ 78 "VerifiablePresentation", 79 "PresentationSubmission" 80 ], 81 "presentation_submission": { 82 "descriptor_map": [ 83 { 84 "id": "degree_input_1", 85 "path": "$.verifiableCredential.[0]" 86 }, 87 { 88 "id": "citizenship_input_1", 89 "path": "$.verifiableCredential.[1]" 90 } 91 ] 92 }, 93 "verifiableCredential": [ 94 { 95 "@context": [ 96 "https://www.w3.org/2018/credentials/v1", 97 "https://www.w3.org/2018/credentials/examples/v1" 98 ], 99 "id": "http://example.edu/credentials/58473", 100 "type": ["VerifiableCredential", "UniversityDegreeCredential"], 101 "issuer": "https://example.edu/issuers/14", 102 "issuanceDate": "2010-01-01T19:23:24Z", 103 "credentialSubject": { 104 "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 105 "alumniOf": "Example University" 106 }, 107 "proof": { 108 "type": "RsaSignature2018" 109 } 110 } 111 ], 112 "holder": "did:example:ebfeb1f712ebc6f1c276e12ec21" 113 } 114 ` 115 116 //go:embed testdata/validPresentationWithJWTVC.jsonld 117 var validPresentationWithJWTVC []byte //nolint:gochecknoglobals 118 119 //go:embed testdata/context/presentation_submission_v1.jsonld 120 var presentationSubmissionV1 []byte //nolint:gochecknoglobals 121 122 func TestParsePresentation(t *testing.T) { 123 t.Run("creates a new Verifiable Presentation from JSON with valid structure", func(t *testing.T) { 124 vp, err := newTestPresentation(t, []byte(validPresentation), WithPresStrictValidation()) 125 require.NoError(t, err) 126 require.NotNil(t, vp) 127 128 // validate @context 129 require.Equal(t, []string{ 130 "https://www.w3.org/2018/credentials/v1", 131 "https://www.w3.org/2018/credentials/examples/v1", 132 "https://trustbloc.github.io/context/vc/examples-v1.jsonld", 133 }, vp.Context) 134 135 // check id 136 require.Equal(t, "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5", vp.ID) 137 138 // check type 139 require.Equal(t, []string{"VerifiablePresentation"}, vp.Type) 140 141 // check verifiableCredentials 142 require.NotNil(t, vp.Credentials()) 143 require.Len(t, vp.Credentials(), 1) 144 145 // check holder 146 require.Equal(t, "did:example:ebfeb1f712ebc6f1c276e12ec21", vp.Holder) 147 }) 148 149 t.Run("creates a new Verifiable Presentation from valid JSON without credentials", func(t *testing.T) { 150 vp, err := newTestPresentation(t, []byte(presentationWithoutCredentials), WithPresStrictValidation()) 151 require.NoError(t, err) 152 require.NotNil(t, vp) 153 154 // validate @context 155 require.Equal(t, []string{ 156 "https://www.w3.org/2018/credentials/v1", 157 "https://www.w3.org/2018/credentials/examples/v1", 158 "https://trustbloc.github.io/context/vc/examples-v1.jsonld", 159 }, vp.Context) 160 161 // check id 162 require.Equal(t, "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5", vp.ID) 163 164 // check type 165 require.Equal(t, []string{"VerifiablePresentation"}, vp.Type) 166 167 // check verifiableCredentials 168 require.Nil(t, vp.Credentials()) 169 require.Empty(t, vp.Credentials()) 170 171 // check holder 172 require.Equal(t, "did:example:ebfeb1f712ebc6f1c276e12ec21", vp.Holder) 173 174 // check rawPresentation 175 rp, err := vp.raw() 176 require.NoError(t, err) 177 178 require.IsType(t, nil, rp.Credential) 179 }) 180 181 t.Run("creates a new Verifiable Presentation with custom/additional fields", func(t *testing.T) { 182 verify := func(t *testing.T, vp *Presentation) { 183 require.Len(t, vp.CustomFields, 1) 184 require.Len(t, vp.CustomFields["presentation_submission"], 1) 185 submission, ok := vp.CustomFields["presentation_submission"].(map[string]interface{}) 186 require.True(t, ok) 187 require.Len(t, submission, 1) 188 descrMap, ok := submission["descriptor_map"].([]interface{}) 189 require.True(t, ok) 190 require.Len(t, descrMap, 2) 191 } 192 193 loader := createTestDocumentLoader(t, ldcontext.Document{ 194 URL: "https://trustbloc.github.io/context/vc/presentation-exchange-submission-v1.jsonld", 195 Content: presentationSubmissionV1, 196 }) 197 198 vp, err := ParsePresentation([]byte(validPresentationWithCustomFields), WithPresJSONLDDocumentLoader(loader)) 199 require.NoError(t, err) 200 require.NotNil(t, vp) 201 verify(t, vp) 202 203 b, e := vp.MarshalJSON() 204 require.NoError(t, e) 205 require.NotEmpty(t, b) 206 207 vp, err = ParsePresentation(b, WithPresStrictValidation(), WithPresJSONLDDocumentLoader(loader)) 208 require.NoError(t, err) 209 require.NotNil(t, vp) 210 verify(t, vp) 211 }) 212 213 t.Run("creates a new Verifiable Presentation from JSON with invalid structure", func(t *testing.T) { 214 emptyJSONDoc := "{}" 215 vp, err := newTestPresentation(t, []byte(emptyJSONDoc)) 216 require.Error(t, err) 217 require.Nil(t, vp) 218 }) 219 220 t.Run("fails to create a new Verifiable Presentation from non-JSON doc", func(t *testing.T) { 221 vp, err := newTestPresentation(t, []byte("non json")) 222 require.Error(t, err) 223 require.Contains(t, err.Error(), "JSON unmarshalling of verifiable presentation") 224 require.Nil(t, vp) 225 }) 226 227 t.Run("strict VP validation fails because of invalid field in VP", func(t *testing.T) { 228 var vpMap map[string]interface{} 229 230 err := json.Unmarshal([]byte(validPresentation), &vpMap) 231 require.NoError(t, err) 232 233 // add invalid field 234 vpMap["foo1"] = "bar1" 235 236 vpBytes, err := json.Marshal(vpMap) 237 require.NoError(t, err) 238 239 vp, err := newTestPresentation(t, vpBytes, WithPresStrictValidation()) 240 require.Error(t, err) 241 require.EqualError(t, err, "JSON-LD doc has different structure after compaction") 242 require.Nil(t, vp) 243 }) 244 245 t.Run("strict VP validation fails because of invalid field in VP proof", func(t *testing.T) { 246 vp, err := newTestPresentation(t, []byte(validPresentation)) 247 require.NoError(t, err) 248 249 signer, err := newCryptoSigner(kms.ED25519Type) 250 require.NoError(t, err) 251 252 ss := ed25519signature2018.New(suite.WithSigner(signer), 253 suite.WithVerifier(ed25519signature2018.NewPublicKeyVerifier())) 254 255 ldpContext := &LinkedDataProofContext{ 256 SignatureType: "Ed25519Signature2018", 257 SignatureRepresentation: SignatureJWS, 258 Suite: ss, 259 VerificationMethod: "did:example:123456#key1", 260 } 261 262 err = vp.AddLinkedDataProof(ldpContext, jsonldsig.WithDocumentLoader(createTestDocumentLoader(t))) 263 require.NoError(t, err) 264 265 proof := vp.Proofs[0] 266 proof["foo2"] = "bar2" 267 268 vpBytes, err := json.Marshal(vp) 269 require.NoError(t, err) 270 271 vp, err = newTestPresentation(t, vpBytes, 272 WithPresStrictValidation(), 273 WithPresPublicKeyFetcher(SingleKey(signer.PublicKeyBytes(), kms.ED25519))) 274 require.Error(t, err) 275 require.EqualError(t, err, "JSON-LD doc has different structure after compaction") 276 require.Nil(t, vp) 277 }) 278 279 t.Run("strict VP validation fails because of invalid field in VC of VP", func(t *testing.T) { 280 vp, err := newTestPresentation(t, []byte(validPresentation)) 281 require.NoError(t, err) 282 283 vc := vp.Credentials()[0] 284 require.NotNil(t, vc) 285 286 vcMap, ok := vc.(map[string]interface{}) 287 require.True(t, ok) 288 289 vcMap["foo3"] = "bar3" 290 291 vpBytes, err := json.Marshal(vp) 292 require.NoError(t, err) 293 294 vp, err = newTestPresentation(t, vpBytes, WithPresStrictValidation()) 295 require.Error(t, err) 296 require.EqualError(t, err, "JSON-LD doc has different structure after compaction") 297 require.Nil(t, vp) 298 }) 299 300 t.Run("parsing VP with a JWT VC succeeds", func(t *testing.T) { 301 loader := createTestDocumentLoader(t, ldcontext.Document{ 302 URL: "https://trustbloc.github.io/context/vc/presentation-exchange-submission-v1.jsonld", 303 Content: presentationSubmissionV1, 304 }) 305 306 vp, err := ParsePresentation(validPresentationWithJWTVC, WithPresDisabledProofCheck(), 307 WithPresJSONLDDocumentLoader(loader)) 308 require.NoError(t, err) 309 require.NotNil(t, vp) 310 }) 311 312 t.Run("parsing VP with a JWT VC with required JSON-LD checks succeeds", func(t *testing.T) { 313 vp, err := ParsePresentation(validPresentationWithJWTVC, WithPresDisabledProofCheck(), 314 WithDisabledJSONLDChecks()) 315 require.NoError(t, err) 316 require.NotNil(t, vp) 317 }) 318 } 319 320 func TestValidateVP_Context(t *testing.T) { 321 t.Run("rejects verifiable presentation with empty context", func(t *testing.T) { 322 raw := &rawPresentation{} 323 require.NoError(t, json.Unmarshal([]byte(validPresentation), &raw)) 324 raw.Context = nil 325 bytes, err := json.Marshal(raw) 326 require.NoError(t, err) 327 vp, err := newTestPresentation(t, bytes) 328 require.Error(t, err) 329 require.Contains(t, err.Error(), "@context is required") 330 require.Nil(t, vp) 331 }) 332 333 t.Run("rejects verifiable presentation with invalid context", func(t *testing.T) { 334 raw := &rawPresentation{} 335 require.NoError(t, json.Unmarshal([]byte(validPresentation), &raw)) 336 raw.Context = []string{ 337 "https://www.w3.org/2018/credentials/v2", 338 "https://www.w3.org/2018/credentials/examples/v1", 339 } 340 bytes, err := json.Marshal(raw) 341 require.NoError(t, err) 342 vp, err := newTestPresentation(t, bytes) 343 require.Error(t, err) 344 require.Contains(t, err.Error(), "does not match: \"https://www.w3.org/2018/credentials/v1\"") 345 require.Nil(t, vp) 346 }) 347 348 t.Run("generate verifiable presentation with valid string context", func(t *testing.T) { 349 raw := &rawPresentation{} 350 require.NoError(t, json.Unmarshal([]byte(validPresentation), &raw)) 351 raw.Context = "https://www.w3.org/2018/credentials/v1" 352 bytes, err := json.Marshal(raw) 353 require.NoError(t, err) 354 vp, err := newTestPresentation(t, bytes) 355 require.NoError(t, err) 356 require.NotNil(t, vp) 357 }) 358 359 t.Run("rejects verifiable presentation with invalid string context", func(t *testing.T) { 360 raw := &rawPresentation{} 361 require.NoError(t, json.Unmarshal([]byte(validPresentation), &raw)) 362 raw.Context = "https://www.w3.org/2018/credentials/v2" 363 bytes, err := json.Marshal(raw) 364 require.NoError(t, err) 365 vp, err := newTestPresentation(t, bytes) 366 require.Error(t, err) 367 require.Contains(t, err.Error(), "does not match: \"https://www.w3.org/2018/credentials/v1\"") 368 require.Nil(t, vp) 369 }) 370 } 371 372 func TestValidateVP_ID(t *testing.T) { 373 t.Run("accept verifiable presentation with string ID", func(t *testing.T) { 374 raw := &rawPresentation{} 375 require.NoError(t, json.Unmarshal([]byte(validPresentation), &raw)) 376 raw.ID = "id" 377 bytes, err := json.Marshal(raw) 378 require.NoError(t, err) 379 _, err = newTestPresentation(t, bytes) 380 require.NoError(t, err) 381 }) 382 } 383 384 func TestValidateVP_Type(t *testing.T) { 385 t.Run("accepts verifiable presentation with single VerifiablePresentation type", func(t *testing.T) { 386 raw := &rawPresentation{} 387 require.NoError(t, json.Unmarshal([]byte(validPresentation), &raw)) 388 raw.Type = "VerifiablePresentation" 389 bytes, err := json.Marshal(raw) 390 require.NoError(t, err) 391 _, err = newTestPresentation(t, bytes) 392 require.NoError(t, err) 393 }) 394 395 t.Run("accepts verifiable presentation with multiple types where VerifiablePresentation is a first type", 396 func(t *testing.T) { 397 raw := &rawPresentation{} 398 require.NoError(t, json.Unmarshal([]byte(validPresentation), &raw)) 399 raw.Type = []string{"VerifiablePresentation", "CredentialManagerPresentation"} 400 bytes, err := json.Marshal(raw) 401 require.NoError(t, err) 402 _, err = newTestPresentation(t, bytes) 403 require.NoError(t, err) 404 }) 405 406 t.Run("accepts verifiable presentation with multiple types where VerifiablePresentation is not a first type", 407 func(t *testing.T) { 408 raw := &rawPresentation{} 409 require.NoError(t, json.Unmarshal([]byte(validPresentation), &raw)) 410 raw.Type = []string{"CredentialManagerPresentation", "VerifiablePresentation"} 411 bytes, err := json.Marshal(raw) 412 require.NoError(t, err) 413 _, err = newTestPresentation(t, bytes) 414 require.NoError(t, err) 415 }) 416 417 t.Run("rejects verifiable presentation with no type defined", func(t *testing.T) { 418 raw := &rawPresentation{} 419 require.NoError(t, json.Unmarshal([]byte(validPresentation), &raw)) 420 raw.Type = nil 421 bytes, err := json.Marshal(raw) 422 require.NoError(t, err) 423 vp, err := newTestPresentation(t, bytes) 424 require.Error(t, err) 425 require.Contains(t, err.Error(), "type is required") 426 require.Nil(t, vp) 427 }) 428 429 t.Run("rejects verifiable presentation where single type is not VerifiablePresentation", func(t *testing.T) { 430 raw := &rawPresentation{} 431 require.NoError(t, json.Unmarshal([]byte(validPresentation), &raw)) 432 raw.Type = "CredentialManagerPresentation" 433 bytes, err := json.Marshal(raw) 434 require.NoError(t, err) 435 vp, err := newTestPresentation(t, bytes) 436 require.Error(t, err) 437 require.Contains(t, err.Error(), "Does not match pattern '^VerifiablePresentation$'") 438 require.Nil(t, vp) 439 }) 440 } 441 442 func TestValidateVP_Holder(t *testing.T) { 443 t.Run("rejects verifiable presentation with non-url holder", func(t *testing.T) { 444 raw := &rawPresentation{} 445 require.NoError(t, json.Unmarshal([]byte(validPresentation), &raw)) 446 raw.Holder = "not valid presentation Holder URL" 447 bytes, err := json.Marshal(raw) 448 require.NoError(t, err) 449 vp, err := newTestPresentation(t, bytes) 450 require.Error(t, err) 451 require.Contains(t, err.Error(), "holder: Does not match format 'uri'") 452 require.Nil(t, vp) 453 }) 454 } 455 456 func TestPresentation_MarshalJSON(t *testing.T) { 457 vp, err := newTestPresentation(t, []byte(validPresentation)) 458 require.NoError(t, err) 459 require.NotEmpty(t, vp) 460 461 // convert verifiable credential to json byte data 462 vpData, err := vp.MarshalJSON() 463 require.NoError(t, err) 464 require.NotEmpty(t, vpData) 465 466 // convert json byte data back to verifiable presentation 467 vp2, err := newTestPresentation(t, vpData) 468 require.NoError(t, err) 469 require.NotEmpty(t, vp2) 470 471 // verify that verifiable presentations created by ParsePresentation() and MarshalJSON() matches 472 require.Equal(t, vp, vp2) 473 } 474 475 func TestNewPresentation(t *testing.T) { 476 r := require.New(t) 477 478 vc, err := ParseCredential([]byte(validCredential), 479 WithJSONLDDocumentLoader(createTestDocumentLoader(t)), 480 WithDisabledProofCheck()) 481 r.NoError(err) 482 483 // Pass Credential struct pointer 484 vp, err := NewPresentation(WithCredentials(vc)) 485 r.NoError(err) 486 r.Len(vp.credentials, 1) 487 r.Equal(vc, vp.credentials[0]) 488 489 vp.AddCredentials(&Credential{}) 490 r.Len(vp.credentials, 2) 491 492 // Pass VC marshalled into unsecured JWT 493 jwtClaims, err := vc.JWTClaims(true) 494 r.NoError(err) 495 496 jwt, err := jwtClaims.MarshalUnsecuredJWT() 497 r.NoError(err) 498 499 vp, err = NewPresentation(WithJWTCredentials(jwt)) 500 r.NoError(err) 501 r.Len(vp.credentials, 1) 502 // VC JWT is NOT converted to vc struct, it's kept as is 503 r.Equal(jwt, vp.credentials[0]) 504 505 // set multiple credentials 506 vp, err = NewPresentation(WithCredentials(vc, vc), WithJWTCredentials(jwt), WithCredentials(vc)) 507 r.NoError(err) 508 r.Len(vp.credentials, 4) 509 r.Equal(vc, vp.credentials[0]) 510 r.Equal(vc, vp.credentials[1]) 511 r.Equal(jwt, vp.credentials[2]) 512 r.Equal(vc, vp.credentials[3]) 513 514 // Error - pass unsupported type 515 _, err = NewPresentation(WithJWTCredentials("notajwt")) 516 r.Error(err) 517 r.EqualError(err, "credential is not base64url encoded JWT") 518 } 519 520 func TestPresentation_decodeCredentials(t *testing.T) { 521 r := require.New(t) 522 523 signer, err := newCryptoSigner(kms.ED25519Type) 524 r.NoError(err) 525 526 vc, err := parseTestCredential(t, []byte(validCredential)) 527 r.NoError(err) 528 529 jwtClaims, err := vc.JWTClaims(false) 530 r.NoError(err) 531 532 jws, err := jwtClaims.MarshalJWS(EdDSA, signer, "did:123#k1") 533 r.NoError(err) 534 535 // single credential - JWS 536 opts := defaultPresentationOpts() 537 opts.jsonldCredentialOpts.jsonldDocumentLoader = createTestDocumentLoader(t) 538 opts.publicKeyFetcher = SingleKey(signer.PublicKeyBytes(), kms.ED25519) 539 dCreds, err := decodeCredentials(jws, opts) 540 r.NoError(err) 541 r.Len(dCreds, 1) 542 543 // no credential 544 dCreds, err = decodeCredentials(nil, opts) 545 r.NoError(err) 546 r.Len(dCreds, 0) 547 dCreds, err = decodeCredentials([]interface{}{}, opts) 548 r.NoError(err) 549 r.Len(dCreds, 0) 550 551 // single credential - JWS decoding failed (e.g. to no public key fetcher available) 552 opts.publicKeyFetcher = nil 553 _, err = decodeCredentials(jws, opts) 554 r.Error(err) 555 } 556 557 func TestWithPresPublicKeyFetcher(t *testing.T) { 558 vpOpt := WithPresPublicKeyFetcher(SingleKey([]byte("test pubKey"), kms.ED25519)) 559 require.NotNil(t, vpOpt) 560 561 opts := &presentationOpts{} 562 vpOpt(opts) 563 require.NotNil(t, opts.publicKeyFetcher) 564 } 565 566 func TestWithPresEmbeddedSignatureSuites(t *testing.T) { 567 ss := ed25519signature2018.New() 568 569 vpOpt := WithPresEmbeddedSignatureSuites(ss) 570 require.NotNil(t, vpOpt) 571 572 opts := &presentationOpts{} 573 vpOpt(opts) 574 require.Equal(t, []verifier.SignatureSuite{ss}, opts.ldpSuites) 575 } 576 577 func TestWithPresJSONLDDocumentLoader(t *testing.T) { 578 documentLoader := jsonld.NewDefaultDocumentLoader(nil) 579 presentationOpt := WithPresJSONLDDocumentLoader(documentLoader) 580 require.NotNil(t, presentationOpt) 581 582 opts := &presentationOpts{} 583 presentationOpt(opts) 584 require.Equal(t, documentLoader, opts.jsonldDocumentLoader) 585 } 586 587 func TestParseUnverifiedPresentation(t *testing.T) { 588 loader, err := ldtestutil.DocumentLoader() 589 require.NoError(t, err) 590 591 // happy path 592 vp, err := ParsePresentation([]byte(validPresentation), WithPresDisabledProofCheck(), 593 WithPresJSONLDDocumentLoader(loader)) 594 require.NoError(t, err) 595 require.NotNil(t, vp) 596 597 // delete the embedded proof and check the VP decoding once again 598 var vpJSON map[string]interface{} 599 600 err = json.Unmarshal([]byte(validPresentation), &vpJSON) 601 require.NoError(t, err) 602 delete(vpJSON, "proof") 603 604 vpWithoutProofBytes, err := json.Marshal(vpJSON) 605 require.NoError(t, err) 606 607 vp, err = ParsePresentation(vpWithoutProofBytes, WithPresDisabledProofCheck(), 608 WithPresJSONLDDocumentLoader(loader)) 609 require.NoError(t, err) 610 require.NotNil(t, vp) 611 612 // VP decoding error 613 vp, err = ParsePresentation([]byte("invalid"), WithPresDisabledProofCheck(), 614 WithPresJSONLDDocumentLoader(loader)) 615 require.Error(t, err) 616 require.Nil(t, vp) 617 }