Skip to content

Commit 8497f4a

Browse files
author
Oleksandr Abakumov
committed
test: add tests for structured WalletError.Code and context
1 parent bfe929e commit 8497f4a

File tree

1 file changed

+119
-1
lines changed

1 file changed

+119
-1
lines changed

Tests/EudiWalletKitTests/DcqlQueryTests.swift

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,125 @@ struct DcqlQueryTests {
616616
#expect(result["pid_cred"]?.count == 4, "Should have all four claims")
617617
}
618618

619-
}
619+
// MARK: - Structured WalletError.Code tests
620620

621+
@Test("WalletError has .claimNotFound code when claim is missing", arguments: ["dcql-vehicle"])
622+
func testErrorCodeClaimNotFound(dcqlFile: String) throws {
623+
let dcqlData = try loadTestResource(fileName: dcqlFile)
624+
let wrapper = try JSONDecoder().decode(DCQL.self, from: dcqlData)
625+
let dcql = try DCQL(credentials: wrapper.credentials)
626+
let dcqlQueryable = DefaultDcqlQueryable(
627+
credentials: ["cred1": ("org.iso.7367.1.mVRC", DocDataFormat.cbor)],
628+
claimPaths: [
629+
"cred1": [
630+
ClaimPath([.claim(name: "org.iso.7367.1"), .claim(name: "vehicle_holder")])
631+
// Missing first_name claim
632+
]
633+
]
634+
)
635+
do {
636+
_ = try OpenId4VpUtils.resolveDcql(dcql, queryable: dcqlQueryable)
637+
Issue.record("Expected WalletError to be thrown")
638+
} catch let error as WalletError {
639+
#expect(error.code == .claimNotFound, "Error code should be .claimNotFound")
640+
#expect(error.context["claimPath"] == "org.iso.18013.5.1/first_name", "Context should contain the missing claim path")
641+
}
642+
}
621643

644+
@Test("WalletError has .credentialNotFound code when docType is missing", arguments: ["dcql-vehicle"])
645+
func testErrorCodeCredentialNotFound(dcqlFile: String) throws {
646+
let dcqlData = try loadTestResource(fileName: dcqlFile)
647+
let wrapper = try JSONDecoder().decode(DCQL.self, from: dcqlData)
648+
let dcql = try DCQL(credentials: wrapper.credentials)
649+
// No credentials at all
650+
let dcqlQueryable = DefaultDcqlQueryable(
651+
credentials: [:],
652+
claimPaths: [:]
653+
)
654+
do {
655+
_ = try OpenId4VpUtils.resolveDcql(dcql, queryable: dcqlQueryable)
656+
Issue.record("Expected WalletError to be thrown")
657+
} catch let error as WalletError {
658+
#expect(error.code == .credentialNotFound, "Error code should be .credentialNotFound")
659+
#expect(error.context["docType"] == "org.iso.7367.1.mVRC", "Context should contain the missing docType")
660+
}
661+
}
622662

663+
@Test("WalletError has .claimValueMismatch code when value doesn't match", arguments: ["dcql-query-values"])
664+
func testErrorCodeClaimValueMismatch(dcqlFile: String) throws {
665+
let dcqlData = try loadTestResource(fileName: dcqlFile)
666+
let dcql = try JSONDecoder().decode(DCQL.self, from: dcqlData)
667+
let dcqlQueryable = DefaultDcqlQueryable(
668+
credentials: [
669+
"pid_cred": ("https://credentials.example.com/identity_credential", DocDataFormat.sdjwt)
670+
],
671+
claimPaths: [
672+
"pid_cred": [
673+
ClaimPath([.claim(name: "last_name")]),
674+
ClaimPath([.claim(name: "first_name")]),
675+
ClaimPath([.claim(name: "address"), .claim(name: "street_address")]),
676+
ClaimPath([.claim(name: "postal_code")])
677+
]
678+
],
679+
claimValues: [
680+
"pid_cred": [
681+
ClaimPath([.claim(name: "last_name")]): ["Smith"], // Wrong value
682+
ClaimPath([.claim(name: "postal_code")]): ["90210"]
683+
]
684+
]
685+
)
686+
do {
687+
_ = try OpenId4VpUtils.resolveDcql(dcql, queryable: dcqlQueryable)
688+
Issue.record("Expected WalletError to be thrown")
689+
} catch let error as WalletError {
690+
#expect(error.code == .claimValueMismatch, "Error code should be .claimValueMismatch")
691+
#expect(error.context["claimPath"] == "last_name", "Context should contain the mismatched claim path")
692+
}
693+
}
694+
695+
@Test("WalletError has .claimSetNotSatisfied code when no claim_set option works", arguments: ["dcql-claim-sets"])
696+
func testErrorCodeClaimSetNotSatisfied(dcqlFile: String) throws {
697+
let dcqlData = try loadTestResource(fileName: dcqlFile)
698+
let dcql = try JSONDecoder().decode(DCQL.self, from: dcqlData)
699+
let dcqlQueryable = DefaultDcqlQueryable(
700+
credentials: [
701+
"pid_cred": ("https://credentials.example.com/identity_credential", DocDataFormat.sdjwt)
702+
],
703+
claimPaths: [
704+
"pid_cred": [
705+
ClaimPath([.claim(name: "last_name")]),
706+
ClaimPath([.claim(name: "date_of_birth")])
707+
// Missing locality, region from set 1
708+
// Missing postal_code from set 2
709+
]
710+
]
711+
)
712+
do {
713+
_ = try OpenId4VpUtils.resolveDcql(dcql, queryable: dcqlQueryable)
714+
Issue.record("Expected WalletError to be thrown")
715+
} catch let error as WalletError {
716+
#expect(error.code == .claimSetNotSatisfied, "Error code should be .claimSetNotSatisfied")
717+
#expect(error.context["claimPath"] != nil, "Context should contain the first missing claim path")
718+
}
719+
}
720+
721+
@Test("WalletError backward compatibility — code and context default to nil and empty")
722+
func testWalletErrorBackwardCompatibility() throws {
723+
let error = WalletError(description: "Some legacy error")
724+
#expect(error.code == nil, "Code should default to nil")
725+
#expect(error.context.isEmpty, "Context should default to empty")
726+
#expect(error.errorDescription == "Some legacy error", "Description should still work")
727+
}
728+
729+
@Test("WalletError with code and context preserves all fields")
730+
func testWalletErrorStructuredFields() throws {
731+
let error = WalletError(
732+
description: "Claim not found: family_name_birth",
733+
code: .claimNotFound,
734+
context: ["claimPath": "family_name_birth"]
735+
)
736+
#expect(error.code == .claimNotFound)
737+
#expect(error.context["claimPath"] == "family_name_birth")
738+
#expect(error.errorDescription == "Claim not found: family_name_birth")
739+
}
740+
}

0 commit comments

Comments
 (0)