Skip to content

Commit 70158ed

Browse files
authored
Merge pull request #8 from inferno-framework/FI-3759-update-ruby
FI-3759 Change input for validation module from credential string to FHIR Bundle hash input parameter
2 parents b6fcf14 + f639d57 commit 70158ed

File tree

6 files changed

+136
-49
lines changed

6 files changed

+136
-49
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
# Inferno Smart Health Card Test Kit
22

33
This is an [Inferno](https://inferno-framework.github.io/) test kit
4-
for the SMART Health Cards Framework [v1.4.0](https://spec.smarthealth.cards/)
4+
for the SMART Health Cards Framework [v1.4.0](https://spec.smarthealth.cards/).
5+
6+
The test kit currently tests the following requirements:
7+
- Download and validate a health card [via File Download](https://spec.smarthealth.cards/#via-file-download)
8+
- Download and validate a health card [via FHIR $health-cards-issue Operation](https://spec.smarthealth.cards/#via-fhir-health-cards-issue-operation)
9+
- Download and validate a health card [via QR Code](https://spec.smarthealth.cards/#via-qr-print-or-scan)
10+
11+
The test kit does **NOT** test this requirement:
12+
- Download and validate a health card [via Deep Link](https://spec.smarthealth.cards/#via-deep-link)
513

614
## Instructions
715

lib/smart_health_cards_test_kit/metadata.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@ class Metadata < Inferno::TestKit
2121
These tests are intended to allow server implementers to perform checks of their server against SMART Health Cards Framework requrirements.
2222
2323
The test kit currently tests the following requirements:
24-
- Download and validate a health card via file download
25-
- Download and validate a health card via FHIR $health-cards-issue operation
26-
- Download and validate a health card via QR Code scanning
24+
- Download and validate a health card [via File Download](https://spec.smarthealth.cards/#via-file-download)
25+
- Download and validate a health card [via FHIR $health-cards-issue Operation](https://spec.smarthealth.cards/#via-fhir-health-cards-issue-operation)
26+
- Download and validate a health card [via QR Code](https://spec.smarthealth.cards/#via-qr-print-or-scan)
27+
28+
The test kit does **NOT** test this requirement:
29+
- Download and validate a health card [via Deep Link](https://spec.smarthealth.cards/#via-deep-link)
2730
2831
See the test descriptions within the test kit for detail on the specific validations performed as part of testing these requirements.
2932

lib/smart_health_cards_test_kit/shc_fhir_validation.rb

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,19 @@ class SHCFHIRValidation < Inferno::Test
77
description %(
88
SMART Health Card payload SHALL be a valid FHIR Bundle resource
99
)
10-
input :credential_strings
11-
output :fhir_bundles
10+
input :fhir_bundles
1211

1312
run do
13+
skip_if fhir_bundles.blank?, 'No FHIR bundles received'
1414

15-
skip_if credential_strings.blank?, 'No Verifiable Credentials received'
16-
bundle_array = []
15+
assert_valid_json(fhir_bundles)
16+
bundle_array = JSON.parse(fhir_bundles)
1717

18-
credential_strings.split(',').each do |credential|
19-
jws = SmartHealthCardsTestKit::Utils::JWS.from_jws(credential)
20-
payload = payload_from_jws(jws)
21-
22-
vc = payload['vc']
23-
assert vc.is_a?(Hash), "Expected 'vc' claim to be a JSON object, but found #{vc.class}"
24-
25-
subject = vc['credentialSubject']
26-
assert subject.is_a?(Hash), "Expected 'vc.credentialSubject' to be a JSON object, but found #{subject.class}"
27-
28-
raw_bundle = subject['fhirBundle']
29-
assert raw_bundle.is_a?(Hash), "Expected 'vc.fhirBundle' to be a JSON object, but found #{raw_bundle.class}"
30-
31-
bundle = FHIR::Bundle.new(raw_bundle)
32-
assert_valid_resource(resource: bundle)
33-
bundle_array.append(bundle)
18+
skip_if bundle_array.blank?, 'No FHIR bundles received'
3419

20+
bundle_array.each do |bundle|
21+
assert_valid_resource(resource: FHIR::Bundle.new(bundle))
3522
end
36-
output fhir_bundles: bundle_array
3723
end
3824
end
3925
end

lib/smart_health_cards_test_kit/shc_payload_verification.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ class SHCPayloadVerification < Inferno::Test
3333
(e.g., `{"patient": {"reference": "resource:0"}}`)
3434
)
3535
input :credential_strings
36-
output :decompressed_payloads
36+
output :fhir_bundles
3737

3838
run do
3939
skip_if credential_strings.blank?, 'No Verifiable Credentials received'
40-
decompressed_payload_array = []
40+
fhir_bundles = []
4141

4242
credential_strings.split(',').each do |credential|
4343
jws = SmartHealthCardsTestKit::Utils::JWS.from_jws(credential)
@@ -79,6 +79,9 @@ class SHCPayloadVerification < Inferno::Test
7979
"The following Bundle entry urls do not use short resource-scheme URIs: #{bad_urls.join(', ')}"
8080
end
8181

82+
# Have to make another copy of bundle to avoid being modified by the following codes
83+
fhir_bundles.append(FHIR::Bundle.new(raw_bundle))
84+
8285
bundle = FHIR::Bundle.new(raw_bundle)
8386
resources = bundle.entry.map(&:resource)
8487
bundle.entry.each { |entry| entry.resource = nil }
@@ -117,7 +120,8 @@ class SHCPayloadVerification < Inferno::Test
117120
end
118121
end
119122
end
120-
output decompressed_payloads: decompressed_payload_array
123+
124+
output fhir_bundles: fhir_bundles.to_json
121125
end
122126
end
123127
end

lib/smart_health_cards_test_kit/smart_health_cards_test_suite.rb

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,26 @@ class SmartHealthCardsTestSuite < Inferno::TestSuite
1919
id :smart_health_cards
2020
title 'SMART Health Cards'
2121
description %(
22-
The US Core Test Kit tests systems for their conformance to the
22+
The SMART Health Cards tests systems for their conformance to the
2323
[SMART Health Cards Framework v1.4.0](https://spec.smarthealth.cards/)
2424
)
2525

2626
links [
2727
{
28-
type: 'source_code',
29-
label: 'Open Source',
30-
url: 'https://github.com/inferno-framework/smart-health-cards-test-kit/'
28+
label: 'Report Issue',
29+
url: 'https://github.com/inferno-framework/smart-health-cards-test-kit/issues'
3130
},
3231
{
33-
type: 'report_issue',
34-
label: 'Report Issue',
35-
url: 'https://github.com/inferno-framework/smart-health-cards-test-kit/issues/'
32+
label: 'Open Source',
33+
url: 'https://github.com/inferno-framework/smart-health-cards-test-kit'
3634
},
3735
{
38-
type: 'download',
3936
label: 'Download',
40-
url: 'https://github.com/inferno-framework/smart-health-cards-test-kit/releases/'
37+
url: 'https://github.com/inferno-framework/smart-health-cards-test-kit/releases'
38+
},
39+
{
40+
label: 'SMART Health Cards Framework',
41+
url: 'https://spec.smarthealth.cards/'
4142
}
4243
]
4344

spec/smart_health_cards_test_kit/shc_fhir_validation_spec.rb

Lines changed: 97 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,31 +29,116 @@ def run(runnable, inputs = {})
2929
sessionId: 'b8cf5547-1dc7-4714-a797-dc2347b93fe2'
3030
}
3131
end
32+
let(:fhir_bundle_corrina_rowe) do
33+
FHIR::Bundle.new(
34+
type: 'collection',
35+
entry: [
36+
{
37+
fullUrl: 'resource:0',
38+
resource: FHIR::Patient.new(
39+
name: [
40+
{
41+
family: 'Rowe',
42+
given: ['Corrina']
43+
}
44+
],
45+
birthDate: '1971-12-06',
46+
resourceType: 'Patient'
47+
)
48+
},
49+
{
50+
fullUrl: 'resource:1',
51+
resource: FHIR::Immunization.new(
52+
status: 'completed',
53+
vaccineCode: {
54+
coding: [
55+
{
56+
system: 'http://hl7.org/fhir/sid/cvx',
57+
code: '207'
58+
}
59+
]
60+
},
61+
patient: {
62+
reference: 'resource:0'
63+
},
64+
occurrenceDateTime: '2025-02-05',
65+
lotNumber: '1234567',
66+
resourceType: 'Immunization'
67+
)
68+
}
69+
],
70+
resourceType: 'Bundle'
71+
)
72+
end
73+
74+
let (:fhir_bundle_deanne_gleichner) do
75+
FHIR::Bundle.new(
76+
type: 'collection',
77+
entry: [
78+
{
79+
fullUrl: 'resource:0',
80+
resource: FHIR::Patient.new(
81+
name: [
82+
{
83+
family: 'Gleichner',
84+
given: [
85+
'Deanne'
86+
]
87+
}
88+
],
89+
birthDate: '2007-04-11',
90+
resourceType: 'Patient'
91+
)
92+
},
93+
{
94+
fullUrl: 'resource:1',
95+
resource: FHIR::Immunization.new(
96+
status: 'completed',
97+
vaccineCode: {
98+
coding: [
99+
{
100+
system: 'http://hl7.org/fhir/sid/cvx',
101+
code: '210'
102+
}
103+
]
104+
},
105+
patient: {
106+
reference: 'resource:0'
107+
},
108+
occurrenceDateTime: '2025-02-04',
109+
lotNumber: '1234567',
110+
resourceType: 'Immunization'
111+
)
112+
}
113+
],
114+
resourceType: 'Bundle'
115+
)
116+
end
32117

33118
before do
34119
stub_request(:post, "https://example.com/validatorapi/validate")
35120
.to_return(status: 200, body: operation_outcome_success.to_json)
36121
end
37122

38-
#TODO: update text with specific bundle type
39-
it 'passes if the JWS payload conforms to the FHIR Bundle profile' do
40-
credential_strings = 'eyJ6aXAiOiJERUYiLCJhbGciOiJFUzI1NiIsImtpZCI6IjRIVWIyYXJ2aFRTWHNzRW9NczJHNVRvRHBzWXZzajdoNXdUXzN6TkV0dWcifQ.hVLLjtQwEPyX5pqHk5nMI0fggoQAwcIFzcFxOhMjx45sJ2JY5d9pJ7tktLuz5BLZrq6uqu57kM5BCa33fZmmygiuWuN8uWGMQQS6aqDM9hu22xd5nkUwCijvwV96hPLnXOaoznXc-ha58m0iuK3dm-UQhwPR3MYJM8o6O76KkV03aPmHe2k0nCIQFmvUXnL1bah-ofBBUtNK-wOtC5gStglLMiINt28HXStcZYMwSlFVQEZARPZCXohhUOq7VQSw6MxgBZYhgsdDINC8wwXLO6moDD5y62aesxxRh0y-ctEiNYDTRForSWbecx_6ZsddFrMszo9XtHeLpi_kjqTANEUvKsmeKHGe-8HNZrpeoccQ88iFkBrfmXrGCFNLfZ71uovz2K2DbtU-MfachnxSJ-tUjL-JQMyVkLMDTKcpgv5BFZFZbNCiDt2v8yGQEWKw81PweSe7hSLfxhkju0SrjP80dBXaEEK-2Ra7_fMEPlxP-VYM-a0YGqm5-ufgVe_KSC2C-9VwwYrtId4vpt26VLdNY9OEFRpf8pwV8yzUME-CV4r-xNH7_whz2nRYJ1I3JnUkYJ3Hjm0OBWPHReCT4D5XDu34mNvp2fvD_k_0_QU.-jNkrXCHlq75fLCGvD8_7eF4iQ-XYQT7uZyiZ1Fqa33-ZQA1-aVEk519JZYGMDdJpO-mVqIC20Xh9sBsD8COzg'
41-
result = run(test, { file_download_url: url, url: url, credential_strings: credential_strings})
123+
it 'passes if the input is an array with a single bundle conforms to the FHIR Bundle profile' do
124+
fhir_bundles = [ fhir_bundle_corrina_rowe ].to_json
125+
result = run(test, { file_download_url: url, url: url, fhir_bundles: fhir_bundles})
42126
expect(result.result).to eq('pass')
43127
end
44128

45-
it 'passes if a comma-separated list of VCs all contain JWS payloads that conform to the FHIR Bundle profile' do
46-
credential_strings = 'eyJ6aXAiOiJERUYiLCJhbGciOiJFUzI1NiIsImtpZCI6IjRIVWIyYXJ2aFRTWHNzRW9NczJHNVRvRHBzWXZzajdoNXdUXzN6TkV0dWcifQ.hVLLjtQwEPyX5pqHk5nMI0fggoQAwcIFzcFxOhMjx45sJ2JY5d9pJ7tktLuz5BLZrq6uqu57kM5BCa33fZmmygiuWuN8uWGMQQS6aqDM9hu22xd5nkUwCijvwV96hPLnXOaoznXc-ha58m0iuK3dm-UQhwPR3MYJM8o6O76KkV03aPmHe2k0nCIQFmvUXnL1bah-ofBBUtNK-wOtC5gStglLMiINt28HXStcZYMwSlFVQEZARPZCXohhUOq7VQSw6MxgBZYhgsdDINC8wwXLO6moDD5y62aesxxRh0y-ctEiNYDTRForSWbecx_6ZsddFrMszo9XtHeLpi_kjqTANEUvKsmeKHGe-8HNZrpeoccQ88iFkBrfmXrGCFNLfZ71uovz2K2DbtU-MfachnxSJ-tUjL-JQMyVkLMDTKcpgv5BFZFZbNCiDt2v8yGQEWKw81PweSe7hSLfxhkju0SrjP80dBXaEEK-2Ra7_fMEPlxP-VYM-a0YGqm5-ufgVe_KSC2C-9VwwYrtId4vpt26VLdNY9OEFRpf8pwV8yzUME-CV4r-xNH7_whz2nRYJ1I3JnUkYJ3Hjm0OBWPHReCT4D5XDu34mNvp2fvD_k_0_QU.-jNkrXCHlq75fLCGvD8_7eF4iQ-XYQT7uZyiZ1Fqa33-ZQA1-aVEk519JZYGMDdJpO-mVqIC20Xh9sBsD8COzg,eyJ6aXAiOiJERUYiLCJhbGciOiJFUzI1NiIsImtpZCI6IjRIVWIyYXJ2aFRTWHNzRW9NczJHNVRvRHBzWXZzajdoNXdUXzN6TkV0dWcifQ.fZDBTsMwEET_ZbkmaUJatfURVT0jFbigHhxnWxs5drV2IoUq_866oUJCAt_WfjOe2SuYEECAjvEiFgvrlbTahyjqsiwhA9ecQFTruqrrzWa1zGBQIK4QxwuCeL_JAutCJylqlDbqQklqw8M85Glgm7855QfTVtt_GdN1vTOfMhrv4JiBImzRRSPtoW8-UMUU6aQNvSGFxAhYFmVRsWm6fepda_EnNihvLasSmQEb0chd2KG39pUsA4TB96RQpBXch2TgZIczKztjWQZ7EzQSY2czoEs7OXiSo4TjxEkbw1V2MqZfq-3jKi_X-a3s3fRlTvTM3TgITEn06-07_sTnCw.pYwsdxlzdXVhnPzO_YDlMXnSHHz88XA3A9bGuzutySq2v3tO5lOWsfsOQGhoWiH7LCtUNpoizX5GSi5cXVI19g'
47-
result = run(test, { file_download_url: url, url: url, credential_strings: credential_strings})
48-
129+
it 'passes if the input is an array of multiple bundles that all conform to the FHIR Bundle profile' do
130+
fhir_bundles = [
131+
fhir_bundle_corrina_rowe,
132+
fhir_bundle_deanne_gleichner
133+
].to_json
134+
result = run(test, { file_download_url: url, url: url, fhir_bundles: fhir_bundles})
49135
expect(result.result).to eq('pass')
50136
end
51137

52-
it 'raises an error if the JWS payload does not conform to the FHIR Bundle profile' do
53-
credential_strings = 'asdf'
54-
expect {result = run(test, { file_download_url: url, url: url, credential_strings: credential_strings })}.to raise_error()
138+
it 'skips if the no FHIR bundles received' do
139+
result = run(test, { file_download_url: url, url: url, fhir_bundles: [].to_json})
140+
expect(result.result).to eq('skip')
55141
end
56142

57143
end
58-
59144
end

0 commit comments

Comments
 (0)