shc_vaccination_test_kit 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,207 @@
1
+ <html>
2
+ <head>
3
+ <meta charset="utf-8">
4
+ <meta name="viewport" content="width=device-width, initial-scale=1">
5
+ <title>Scan a QR Code</title>
6
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
7
+ </head>
8
+ <body class="m-3" onload="onLoad()">
9
+ <section class="hero is-small is-success">
10
+ <h3>Scan a QR Code</h3>
11
+ <p class="subtitle">Use device's camera to scan a QR code representing a Smart Health Card</p>
12
+ </section>
13
+
14
+ <div>
15
+ <div class="field is-grouped">
16
+ <button id="start" class="btn btn-primary" onclick="disableStartButton()">Start</button>
17
+ <button id="stop" class="btn btn-primary" onclick="enableStartButton()" disabled>Stop</button>
18
+ </div>
19
+ <div class="level-right" id="multi-status-container">
20
+ </div>
21
+
22
+ <video id="preview"></video>
23
+
24
+ <div class="notification is-success is-light" hidden id="success-notification">
25
+ <div class="level">
26
+ <div class="level-left">
27
+ <div class="level-item">
28
+ <span class="is-size-4">QR code scanned successfully.</span>
29
+ </div>
30
+ </div>
31
+ </div>
32
+ </div>
33
+
34
+ <div class="notification is-success is-light">
35
+ <form id="upload-qr-code" action="post_qr_code" accept-charset="UTF-8" method="post"></form>
36
+ <div class="level">
37
+ <div class="level-left">
38
+ <div class="level-item">
39
+ <span class="is-size-4" id="qr-contents"></span>
40
+ </div>
41
+ </div>
42
+ </div>
43
+ </form>
44
+ </div>
45
+
46
+ <div class="notification is-danger is-light" hidden id="error-notification">
47
+ <div class="level">
48
+ <div class="level-left">
49
+ <div class="level-item">
50
+ <span class="is-size-4">QR code does not contain a SMART Health Card.</span>
51
+ </div>
52
+ </div>
53
+ </div>
54
+ </div>
55
+ </div>
56
+
57
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
58
+
59
+ <script type="module">
60
+ import QrScanner from './qr-scanner.min.js';
61
+
62
+ const healthCardPattern = /^shc:\/(?<multipleChunks>(?<chunkIndex>[0-9]+)\/(?<chunkCount>[0-9]+)\/)?[0-9]+$/;
63
+
64
+ let qrScanner;
65
+ let startButton;
66
+ let stopButton;
67
+ let successNotification;
68
+ let errorNotification;
69
+ let inputField;
70
+ let multiStatusContainer;
71
+ let form
72
+
73
+ let scannedCodes = [];
74
+
75
+ window.onLoad = function() {
76
+ const videoElement = document.getElementById('preview');
77
+
78
+ qrScanner = new QrScanner(videoElement, handleScan);
79
+
80
+ startButton = document.getElementById('start');
81
+ stopButton = document.getElementById('stop');
82
+ successNotification = document.getElementById('success-notification');
83
+ errorNotification = document.getElementById('error-notification');
84
+ inputField = document.getElementById('qr-contents');
85
+ multiStatusContainer = document.getElementById('multi-status-container');
86
+ form = document.getElementById('upload-qr-code');
87
+
88
+ startButton.addEventListener('click', startScanning);
89
+ stopButton.addEventListener('click', stopScanning);
90
+ }
91
+
92
+ window.startScanning = function() {
93
+ disableStartButton();
94
+ hideSuccessNotification();
95
+ hideErrorNotification();
96
+ qrScanner.start();
97
+ };
98
+
99
+ window.stopScanning = function() {
100
+ enableStartButton();
101
+ qrScanner.stop();
102
+ };
103
+
104
+ window.disableStartButton = function() {
105
+ startButton.setAttribute('disabled', true);
106
+ stopButton.removeAttribute('disabled');
107
+ };
108
+
109
+ window.enableStartButton = function() {
110
+ stopButton.setAttribute('disabled', true);
111
+ startButton.removeAttribute('disabled');
112
+ };
113
+
114
+ window.hideSuccessNotification = function() {
115
+ successNotification.setAttribute('hidden', true);
116
+ };
117
+
118
+ window.showSuccessNotification = function() {
119
+ hideErrorNotification();
120
+ successNotification.removeAttribute('hidden');
121
+ };
122
+
123
+ window.hideErrorNotification = function() {
124
+ errorNotification.setAttribute('hidden', true);
125
+ };
126
+
127
+ window.showErrorNotification = function() {
128
+ hideSuccessNotification();
129
+ errorNotification.removeAttribute('hidden');
130
+ };
131
+
132
+ window.handleScan = function(result) {
133
+ console.log(result);
134
+
135
+ if (healthCardPattern.test(result)) {
136
+ const match = result.match(healthCardPattern);
137
+ if (match.groups.multipleChunks) {
138
+ hideErrorNotification();
139
+ const chunkCount = +match.groups.chunkCount;
140
+ const currentChunkIndex = +match.groups.chunkIndex;
141
+ if (scannedCodes.length !== chunkCount) {
142
+ scannedCodes = new Array(chunkCount);
143
+ scannedCodes.fill(null, 0, chunkCount);
144
+ }
145
+ scannedCodes[currentChunkIndex - 1] = result;
146
+
147
+ multiStatusContainer.innerHTML = scannedCodes
148
+ .map((code, index) => {
149
+ return code
150
+ ? multiPresentElement(index + 1, chunkCount)
151
+ : multiMissingElement(index + 1, chunkCount);
152
+ })
153
+ .join('\n');
154
+
155
+ if (scannedCodes.every(code => code)) {
156
+ stopScanning();
157
+
158
+ inputField.textContent = JSON.stringify(scannedCodes);
159
+ showSuccessNotification();
160
+
161
+ //TODO: do something here. Post result to endpoint? Need to understand the logic in this nested if statement
162
+
163
+ }
164
+ } else {
165
+ stopScanning();
166
+
167
+ multiStatusContainer.innerHTML = '';
168
+ inputField.textContent = JSON.stringify([result]);
169
+ showSuccessNotification();
170
+
171
+ //QR code scanned successfully. Post to endpoint (code borrowed from upload_qr_code.html)
172
+ const urlParams = new URLSearchParams(window.location.search);
173
+ const requestId = urlParams.get('id');
174
+ if (requestId) {
175
+ form.action += '?id=' + encodeURIComponent(requestId);
176
+ }
177
+
178
+ const postUrl = `${form.action}`;
179
+ fetch(postUrl, {
180
+ method: 'POST',
181
+ headers: {
182
+ 'Content-Type': 'application/json',
183
+ },
184
+ body: JSON.stringify({ qr_code_content: result }),
185
+ })
186
+ .then(response => {
187
+ if (response.ok) {
188
+ inputField.textContent += " - QR Code successfully posted to server.";
189
+ window.history.back(); // Go back to the previous page
190
+ } else {
191
+ inputField.textContent += " - Error posting QR code to server.";
192
+ }
193
+ })
194
+ .catch(error => {
195
+ inputField.textContent += ` - Network error: ${error}`;
196
+ });
197
+
198
+ }
199
+ } else {
200
+ stopScanning();
201
+
202
+ showErrorNotification();
203
+ }
204
+ };
205
+ </script>
206
+ </body>
207
+ </html>
@@ -0,0 +1,130 @@
1
+ <html>
2
+ <head>
3
+ <meta charset="utf-8">
4
+ <meta name="viewport" content="width=device-width, initial-scale=1">
5
+ <title>Upload a QR image file</title>
6
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
7
+ </head>
8
+ <body class="m-3">
9
+ <div>
10
+ <h3>Upload a QR image file</h3>
11
+ <p class="subtitle">Manually upload a pre saved QR image file. The file shall have .png, .jpg, or .jpeg file extension.</p>
12
+ </div>
13
+ <div>
14
+ <form id="upload-qr-code" action="post_qr_code" accept-charset="UTF-8" method="post">
15
+ <div class="field is-grouped">
16
+ <div class="file has-name">
17
+ <label class="file-label">
18
+ <input type="file" name="qr_file" id="qr_file" accept=".png, .jpg, .jpeg" class="file-input" style="display: none;">
19
+ <label for="qr_file" class="btn btn-primary">Choose File</label>
20
+ <span class="file-name">No file uploaded</span>
21
+ </label>
22
+ </div>
23
+ <p></p>
24
+ <p id="qr-content" style="margin-top: 10px;"></p>
25
+ <p class="control">
26
+ <input type="submit" class="btn btn-secondary" id="upload-button" disabled>
27
+ </p>
28
+ </div>
29
+ </form>
30
+ <canvas id="qr-canvas" style="display: none;"></canvas>
31
+
32
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
33
+ <script src="jsqr.js"></script>
34
+ <script>
35
+ document.addEventListener('DOMContentLoaded', function () {
36
+ const fileInput = document.getElementById('qr_file');
37
+ const fileName = document.querySelector('.file-name');
38
+ const uploadButton = document.getElementById('upload-button');
39
+ const qrCanvas = document.getElementById('qr-canvas');
40
+ const qrContent = document.getElementById('qr-content');
41
+ const form = document.getElementById('upload-qr-code');
42
+
43
+ let qrCodeContent = null;
44
+
45
+ // Update form action if `id` query param is present
46
+ const urlParams = new URLSearchParams(window.location.search);
47
+ const requestId = urlParams.get('id');
48
+ if (requestId) {
49
+ form.action += '?id=' + encodeURIComponent(requestId);
50
+ }
51
+
52
+ fileInput.addEventListener('change', function () {
53
+ const file = fileInput.files[0];
54
+ if (file) {
55
+ fileName.textContent = file.name;
56
+
57
+ // Read the image file and decode QR code
58
+ const reader = new FileReader();
59
+ reader.onload = function (e) {
60
+ const img = new Image();
61
+ img.onload = function () {
62
+ // Draw the image on the canvas
63
+ const ctx = qrCanvas.getContext('2d');
64
+ qrCanvas.width = img.width;
65
+ qrCanvas.height = img.height;
66
+ ctx.drawImage(img, 0, 0, img.width, img.height);
67
+
68
+ // Get image data from the canvas
69
+ const imageData = ctx.getImageData(0, 0, qrCanvas.width, qrCanvas.height);
70
+
71
+ // Decode QR code using jsQR
72
+ const qrCode = jsQR(imageData.data, imageData.width, imageData.height);
73
+ if (qrCode) {
74
+ qrContent.textContent = `QR Code Content: ${qrCode.data}`;
75
+ qrCodeContent = qrCode.data; // Store the decoded content
76
+ uploadButton.disabled = false; // Enable the submit button
77
+ // Change button style to "btn-primary"
78
+ uploadButton.classList.remove('btn-secondary');
79
+ uploadButton.classList.add('btn-primary');
80
+ } else {
81
+ qrContent.textContent = 'No QR code detected in the image.';
82
+ uploadButton.disabled = true;
83
+ // Reset button style to "btn-secondary"
84
+ uploadButton.classList.remove('btn-primary');
85
+ uploadButton.classList.add('btn-secondary');
86
+ }
87
+ };
88
+ img.src = e.target.result;
89
+ };
90
+ reader.readAsDataURL(file);
91
+ } else {
92
+ fileName.textContent = 'No file uploaded';
93
+ uploadButton.disabled = true;
94
+ qrContent.textContent = '';
95
+ // Reset button style to "btn-secondary"
96
+ uploadButton.classList.remove('btn-primary');
97
+ uploadButton.classList.add('btn-secondary');
98
+ }
99
+ });
100
+
101
+ form.addEventListener('submit', function (event) {
102
+ event.preventDefault(); // Prevent default form submission
103
+
104
+ if (qrCodeContent) {
105
+ const postUrl = `${form.action}`;
106
+ fetch(postUrl, {
107
+ method: 'POST',
108
+ headers: {
109
+ 'Content-Type': 'application/json',
110
+ },
111
+ body: JSON.stringify({ qr_code_content: qrCodeContent }),
112
+ })
113
+ .then(response => {
114
+ if (response.ok) {
115
+ qrContent.textContent += " - QR Code successfully posted to server.";
116
+ window.history.back(); // Go back to the previous page
117
+ } else {
118
+ qrContent.textContent += " - Error posting QR code to server.";
119
+ }
120
+ })
121
+ .catch(error => {
122
+ qrContent.textContent += ` - Network error: ${error}`;
123
+ });
124
+ }
125
+ });
126
+ });
127
+ </script>
128
+ </div>
129
+ </body>
130
+ </html>
@@ -1,13 +1,71 @@
1
- require 'health_cards'
2
- require_relative 'covid19_vci/file_download'
3
- require_relative 'covid19_vci/fhir_operation'
1
+ require 'smart_health_cards_test_kit'
2
+ require_relative 'shc_vaccination_test_kit/shc_vaccination_validation_test'
3
+ require_relative 'shc_vaccination_test_kit/metadata'
4
4
 
5
- module Covid19VCI
6
- class Suite < Inferno::TestSuite
7
- id 'c19-vci'
5
+ module SHCVaccinationTestKit
6
+ class SHCVaccinationSuite < Inferno::TestSuite
7
+ id 'shc_vaccination'
8
8
  title 'SMART Health Cards: Vaccination & Testing'
9
+ description %(
10
+ This test suite evaluates the ability of a system to provide
11
+ access to [SMART Health Cards Vaccination and Testing](https://hl7.org/fhir/uv/shc-vaccination/2021Sep/index.html)
12
+ resources via file download, HL7® FHIR® API, or QR Scanning.
13
+ )
14
+ source_code_url('https://github.com/inferno-framework/shc-vaccination-test-kit')
15
+ download_url('https://github.com/inferno-framework/shc-vaccination-test-kit/releases')
16
+ report_issue_url('https://github.com/inferno-framework/shc-vaccination-test-kit/issues')
9
17
 
10
- group from: :vci_file_download
11
- group from: :vci_fhir_operation
18
+ VALIDATION_MESSAGE_FILTERS = [
19
+ /\A\S+: \S+: URL value '.*' does not resolve/,
20
+ ].freeze
21
+
22
+ fhir_resource_validator do
23
+ igs('igs/cards.smarthealth.terminology-0.1.0.tgz', 'igs/shc-vaccination-1.0.0-updated.tgz')
24
+
25
+ exclude_message do |message|
26
+ VALIDATION_MESSAGE_FILTERS.any? { |filter| filter.match? message.message }
27
+ end
28
+ end
29
+
30
+ scan_qr_code_html = File.read(File.join(__dir__, './shc_vaccination_test_kit/views/scan_qr_code.html'))
31
+ scan_qr_code_html_route_handler = proc { [200, { 'Content-Type' => 'text/html' }, [scan_qr_code_html]] }
32
+ route(:get, '/scan_qr_code', scan_qr_code_html_route_handler)
33
+
34
+ qr_scanner_route_handler = proc { [200, { 'Content-Type' => 'text/javascript' }, [qr_scanner]] }
35
+ route(:get, '/qr-scanner.min.js', qr_scanner_route_handler)
36
+
37
+ qr_scanner_worker = File.read(File.join(__dir__, './shc_vaccination_test_kit/javascript/qr-scanner-worker.min.js'))
38
+ qr_scanner_worker_route_handler = proc { [200, { 'Content-Type' => 'text/javascript' }, [qr_scanner_worker]] }
39
+ route(:get, '/qr-scanner-worker.min.js', qr_scanner_worker_route_handler)
40
+
41
+ js_qr = File.read(File.join(__dir__, './shc_vaccination_test_kit/javascript/jsQR.js'))
42
+ js_qr_route_handler = proc { [200, { 'Content-Type' => 'text/javascript' }, [js_qr]] }
43
+ route(:get, '/jsqr.js', js_qr_route_handler)
44
+
45
+ upload_html = File.read(File.join(__dir__, './shc_vaccination_test_kit/views/upload_qr_code.html'))
46
+ upload_html_route_handler = proc { [200, { 'Content-Type' => 'text/html' }, [upload_html]] }
47
+ route(:get, '/upload_qr_code', upload_html_route_handler)
48
+
49
+
50
+ # Tests and TestGroups
51
+ # SmartHealthCardsTestKit::SmartHealthCardsTestSuite.groups.each do |group|
52
+ # test_group = group.ancestors[1]
53
+
54
+ # test_group.children.reject! { |test| test.id.include?('shc_fhir_validation_test') }
55
+ # test_group.test(from: :shc_vaccination_validation_test)
56
+
57
+ # group(from: test_group.id)
58
+ # end
59
+
60
+ def self.add_shc_group(group_id)
61
+ group from: group_id do
62
+ children.reject! { |test| test.id.include?('shc_fhir_validation_test') }
63
+ test from: :shc_vaccination_validation_test
64
+ end
65
+ end
66
+
67
+ add_shc_group :shc_file_download_group
68
+ add_shc_group :shc_fhir_operation_group
69
+ add_shc_group :shc_qr_code_group
12
70
  end
13
71
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shc_vaccination_test_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen MacVicar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-28 00:00:00.000000000 Z
11
+ date: 2025-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: health_cards
14
+ name: inferno_core
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 0.6.4
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 0.6.4
27
27
  - !ruby/object:Gem::Dependency
28
- name: inferno_core
28
+ name: smart_health_cards_test_kit
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 0.4.2
33
+ version: 0.10.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 0.4.2
40
+ version: 0.10.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: database_cleaner-sequel
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -103,18 +103,23 @@ extensions: []
103
103
  extra_rdoc_files: []
104
104
  files:
105
105
  - LICENSE
106
- - lib/covid19_vci/fhir_operation.rb
107
- - lib/covid19_vci/file_download.rb
108
- - lib/covid19_vci/vc_fhir_validation.rb
109
- - lib/covid19_vci/vc_headers.rb
110
- - lib/covid19_vci/vc_payload_verification.rb
111
- - lib/covid19_vci/vc_signature_verification.rb
112
- - lib/covid19_vci/version.rb
113
106
  - lib/shc_vaccination_test_kit.rb
107
+ - lib/shc_vaccination_test_kit/igs/README.md
108
+ - lib/shc_vaccination_test_kit/igs/cards.smarthealth.terminology-0.1.0.tgz
109
+ - lib/shc_vaccination_test_kit/igs/shc-vaccination-1.0.0-updated.tgz
110
+ - lib/shc_vaccination_test_kit/javascript/jsQR.js
111
+ - lib/shc_vaccination_test_kit/javascript/qr-scanner-worker.min.js
112
+ - lib/shc_vaccination_test_kit/javascript/qr-scanner.min.js
113
+ - lib/shc_vaccination_test_kit/metadata.rb
114
+ - lib/shc_vaccination_test_kit/shc_vaccination_validation_test.rb
115
+ - lib/shc_vaccination_test_kit/version.rb
116
+ - lib/shc_vaccination_test_kit/views/scan_qr_code.html
117
+ - lib/shc_vaccination_test_kit/views/upload_qr_code.html
114
118
  homepage: https://github.com/inferno-framework/shc-vaccination-test-kit
115
119
  licenses:
116
120
  - Apache-2.0
117
121
  metadata:
122
+ inferno_test_kit: 'true'
118
123
  homepage_uri: https://github.com/inferno-framework/shc-vaccination-test-kit
119
124
  source_code_uri: https://github.com/inferno-framework/shc-vaccination-test-kit
120
125
  post_install_message:
@@ -125,14 +130,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
125
130
  requirements:
126
131
  - - ">="
127
132
  - !ruby/object:Gem::Version
128
- version: 3.1.2
133
+ version: 3.3.6
129
134
  required_rubygems_version: !ruby/object:Gem::Requirement
130
135
  requirements:
131
136
  - - ">="
132
137
  - !ruby/object:Gem::Version
133
138
  version: '0'
134
139
  requirements: []
135
- rubygems_version: 3.3.7
140
+ rubygems_version: 3.5.22
136
141
  signing_key:
137
142
  specification_version: 4
138
143
  summary: 'A collection of tests for the SMART Health Cards: Vaccination & Testing
@@ -1,105 +0,0 @@
1
- require_relative 'vc_fhir_validation'
2
- require_relative 'vc_headers'
3
- require_relative 'vc_payload_verification'
4
- require_relative 'vc_signature_verification'
5
-
6
- module Covid19VCI
7
- class FHIROperation < Inferno::TestGroup
8
- id 'vci_fhir_operation'
9
- title 'Download and validate a health card via FHIR $health-cards-issue operation'
10
-
11
- input :base_fhir_url, :patient_id
12
-
13
- fhir_client do
14
- url :base_fhir_url
15
- end
16
-
17
- test do
18
- title 'Server advertises health card support in its SMART configuration'
19
- id 'vci-fhir-01'
20
-
21
- run do
22
- get("#{base_fhir_url}/.well-known/smart-configuration")
23
-
24
- assert_response_status(200)
25
- assert_valid_json(response[:body])
26
-
27
- smart_configuration = JSON.parse(response[:body])
28
-
29
- assert smart_configuration['capabilities']&.include?('health-cards'),
30
- "SMART configuration does not list support for 'health-cards' capability"
31
- end
32
- end
33
-
34
- test do
35
- title 'Server advertises $health-cards-issue operation support in its CapabilityStatement'
36
- id 'vci-fhir-02'
37
-
38
- run do
39
- fhir_get_capability_statement
40
-
41
- assert_response_status(200)
42
-
43
- operations = resource.rest&.flat_map do |rest|
44
- rest.resource
45
- &.select { |r| r.type == 'Patient' && r.respond_to?(:operation) }
46
- &.flat_map(&:operation)
47
- end&.compact
48
-
49
- operation_defined = operations.any? { |operation| operation.name == 'health-cards-issue' }
50
-
51
- assert operation_defined,
52
- 'Server CapabilityStatement did not declare support for $health-cards-issue operation ' \
53
- 'on the Patient resource.'
54
- end
55
- end
56
-
57
- test do
58
- title 'Server returns a health card from the $health-cards-issue operation'
59
- id 'vci-fhir-03'
60
- output :credential_strings
61
-
62
- run do
63
- request_params = FHIR::Parameters.new(
64
- parameter: [
65
- {
66
- name: 'credentialType',
67
- valueUri: 'https://smarthealth.cards#covid19'
68
- }
69
- ]
70
- )
71
- fhir_operation("/Patient/#{patient_id}/$health-cards-issue", body: request_params)
72
-
73
- assert_response_status((200..207).to_a)
74
- assert_resource_type(:parameters)
75
-
76
- hc_parameters = resource.parameter.select { |parameter| parameter.name == 'verifiableCredential' }
77
-
78
- assert hc_parameters.present?, 'No COVID-19 health cards were returned'
79
- credential_strings = hc_parameters.map(&:value).join(',')
80
-
81
- output credential_strings: credential_strings
82
-
83
- count = hc_parameters.length
84
-
85
- pass "#{count} verifiable #{'credential'.pluralize(count)} received"
86
- end
87
- end
88
-
89
- test from: :vc_headers do
90
- id 'vci-fhir-04'
91
- end
92
-
93
- test from: :vc_signature_verification do
94
- id 'vci-fhir-05'
95
- end
96
-
97
- test from: :vc_payload_verification do
98
- id 'vci-fhir-06'
99
- end
100
-
101
- test from: :vc_fhir_verification do
102
- id 'vci-fhir-07'
103
- end
104
- end
105
- end