bulk_data_test_kit 0.9.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.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/lib/bulk_data_test_kit/bulk_data_jwks.json +58 -0
  4. data/lib/bulk_data_test_kit/bulk_data_test_kit_properties.rb +20 -0
  5. data/lib/bulk_data_test_kit/bulk_export_validation_tester.rb +214 -0
  6. data/lib/bulk_data_test_kit/export_cancel_tests.rb +43 -0
  7. data/lib/bulk_data_test_kit/export_kick_off_performer.rb +26 -0
  8. data/lib/bulk_data_test_kit/export_operation_tests.rb +171 -0
  9. data/lib/bulk_data_test_kit/export_parameters_tests.rb +49 -0
  10. data/lib/bulk_data_test_kit/v1.0.1/bulk_data_export_cancel_test.rb +35 -0
  11. data/lib/bulk_data_test_kit/v1.0.1/bulk_data_export_kick_off_test.rb +37 -0
  12. data/lib/bulk_data_test_kit/v1.0.1/bulk_data_export_operation_support_test.rb +46 -0
  13. data/lib/bulk_data_test_kit/v1.0.1/bulk_data_export_tests_test_group.rb +41 -0
  14. data/lib/bulk_data_test_kit/v1.0.1/bulk_data_group_export_test_group.rb +24 -0
  15. data/lib/bulk_data_test_kit/v1.0.1/bulk_data_multiple_patients_test.rb +23 -0
  16. data/lib/bulk_data_test_kit/v1.0.1/bulk_data_ndjson_download_test.rb +33 -0
  17. data/lib/bulk_data_test_kit/v1.0.1/bulk_data_no_auth_test.rb +35 -0
  18. data/lib/bulk_data_test_kit/v1.0.1/bulk_data_output_check_test.rb +45 -0
  19. data/lib/bulk_data_test_kit/v1.0.1/bulk_data_patient_export_test_group.rb +24 -0
  20. data/lib/bulk_data_test_kit/v1.0.1/bulk_data_smart_backend_services_group.rb +21 -0
  21. data/lib/bulk_data_test_kit/v1.0.1/bulk_data_status_check_test.rb +43 -0
  22. data/lib/bulk_data_test_kit/v1.0.1/bulk_data_system_export_test_group.rb +24 -0
  23. data/lib/bulk_data_test_kit/v1.0.1/bulk_data_test_suite.rb +166 -0
  24. data/lib/bulk_data_test_kit/v1.0.1/bulk_data_valid_resources_test.rb +30 -0
  25. data/lib/bulk_data_test_kit/v1.0.1/group/bulk_data_group_export_cancel_group.rb +32 -0
  26. data/lib/bulk_data_test_kit/v1.0.1/group/bulk_data_group_export_group.rb +102 -0
  27. data/lib/bulk_data_test_kit/v1.0.1/group/bulk_data_group_export_validation_group.rb +51 -0
  28. data/lib/bulk_data_test_kit/v1.0.1/patient/bulk_data_patient_export_cancel_group.rb +32 -0
  29. data/lib/bulk_data_test_kit/v1.0.1/patient/bulk_data_patient_export_group.rb +108 -0
  30. data/lib/bulk_data_test_kit/v1.0.1/patient/bulk_data_patient_export_validation_group.rb +63 -0
  31. data/lib/bulk_data_test_kit/v1.0.1/system_export/bulk_data_system_export_cancel_group.rb +32 -0
  32. data/lib/bulk_data_test_kit/v1.0.1/system_export/bulk_data_system_export_group.rb +108 -0
  33. data/lib/bulk_data_test_kit/v1.0.1/system_export/bulk_data_system_export_validation_group.rb +63 -0
  34. data/lib/bulk_data_test_kit/v2.0.0/bulk_data_export_cancel_test.rb +28 -0
  35. data/lib/bulk_data_test_kit/v2.0.0/bulk_data_export_tests_test_group.rb +41 -0
  36. data/lib/bulk_data_test_kit/v2.0.0/bulk_data_group_export_test_group.rb +35 -0
  37. data/lib/bulk_data_test_kit/v2.0.0/bulk_data_outputFormat_param_test.rb +36 -0
  38. data/lib/bulk_data_test_kit/v2.0.0/bulk_data_patient_export_test_group.rb +35 -0
  39. data/lib/bulk_data_test_kit/v2.0.0/bulk_data_since_param_test.rb +48 -0
  40. data/lib/bulk_data_test_kit/v2.0.0/bulk_data_system_export_test_group.rb +35 -0
  41. data/lib/bulk_data_test_kit/v2.0.0/bulk_data_test_suite.rb +165 -0
  42. data/lib/bulk_data_test_kit/v2.0.0/group/bulk_data_group_export_cancel_group.rb +15 -0
  43. data/lib/bulk_data_test_kit/v2.0.0/group/bulk_data_group_export_parameters_group.rb +40 -0
  44. data/lib/bulk_data_test_kit/v2.0.0/patient/bulk_data_patient_export_cancel_group.rb +18 -0
  45. data/lib/bulk_data_test_kit/v2.0.0/patient/bulk_data_patient_export_parameters_group.rb +37 -0
  46. data/lib/bulk_data_test_kit/v2.0.0/system_export/bulk_data_system_export_cancel_group.rb +18 -0
  47. data/lib/bulk_data_test_kit/v2.0.0/system_export/bulk_data_system_export_parameters_group.rb +37 -0
  48. data/lib/bulk_data_test_kit/version.rb +5 -0
  49. data/lib/bulk_data_test_kit.rb +4 -0
  50. metadata +289 -0
@@ -0,0 +1,171 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'export_kick_off_performer'
4
+ require_relative 'bulk_data_test_kit_properties'
5
+
6
+ module BulkDataTestKit
7
+ module BulkDataExportOperationTests
8
+ extend Forwardable
9
+
10
+ def_delegators 'self.class', :properties
11
+ def_delegators 'properties',
12
+ :resource_type,
13
+ :bulk_export_url
14
+
15
+ def check_export_support
16
+ fhir_get_capability_statement(client: :bulk_server)
17
+ assert_response_status([200, 201])
18
+
19
+ assert_valid_json(request.response_body)
20
+ capability_statement = FHIR.from_contents(request.response_body)
21
+
22
+ warning do
23
+ has_instantiates = capability_statement&.instantiates&.any? do |canonical|
24
+ canonical.match(%r{^http://hl7.org/fhir/uv/bulkdata/CapabilityStatement/bulk-data(\|\S+)?$})
25
+ end
26
+ assert has_instantiates,
27
+ 'Server did not declare conformance to the Bulk Data IG by including ' \
28
+ "'http://hl7.org/fhir/uv/bulkdata/CapabilityStatement/bulk-data' in " \
29
+ "CapabilityStatement.instantiates element (#{capability_statement&.instantiates})"
30
+ end
31
+
32
+ group_resource_capabilities = nil
33
+
34
+ capability_statement&.rest&.each do |rest|
35
+ group_resource_capabilities = if resource_type == 'system'
36
+ rest
37
+ else
38
+ rest.resource&.find do |resource|
39
+ resource.type == resource_type
40
+ end
41
+ end
42
+ end
43
+
44
+ assert group_resource_capabilities.respond_to?(:operation) && group_resource_capabilities.operation&.any?,
45
+ "Server CapabilityStatement did not declare support for any operations on the #{resource_type} resource"
46
+
47
+ has_export_operation = group_resource_capabilities.operation&.any? do |operation|
48
+ name_match = (operation.name == 'export')
49
+ operationDefURL = resource_type == 'system' ? 'export' : "#{resource_type.downcase}-export"
50
+
51
+ if name_match && !operation.definition&.match(%r{^http://hl7.org/fhir/uv/bulkdata/OperationDefinition/#{operationDefURL}(\|\S+)?$})
52
+ info("Server CapabilityStatement does not include export operation with definition http://hl7.org/fhir/uv/bulkdata/OperationDefinition/#{operationDefURL}")
53
+ end
54
+ name_match
55
+ end
56
+ warning do
57
+ assert has_export_operation,
58
+ "Server CapabilityStatement did not declare support for an operation named export in the #{resource_type} " \
59
+ 'resource (operation.name should be export)'
60
+ end
61
+ end
62
+
63
+ def rejects_without_authorization
64
+ skip_if bearer_token.blank?, 'Bearer token is not set and thus not required to connect to server.'
65
+
66
+ url = bulk_export_url.dup
67
+ url = bulk_export_url.gsub('[group_id]', group_id) if resource_type == 'Group'
68
+
69
+ perform_export_kick_off_request(use_token: false, url:)
70
+ assert_response_status([400, 401])
71
+ end
72
+
73
+ def export_kick_off_success
74
+ use_token = !bearer_token.blank?
75
+
76
+ url = bulk_export_url.dup
77
+ url = bulk_export_url.gsub('[group_id]', group_id) if resource_type == 'Group'
78
+
79
+ perform_export_kick_off_request(use_token:, url:)
80
+ assert_response_status(202)
81
+
82
+ polling_url = request.response_header('content-location')&.value
83
+ assert polling_url.present?, 'Export response headers did not include "Content-Location"'
84
+
85
+ polling_url
86
+ end
87
+
88
+ def export_status_check_success(status_polling_url)
89
+ skip 'Server response did not have Content-Location in header' unless status_polling_url.present?
90
+
91
+ timeout = bulk_timeout.to_i
92
+
93
+ if !timeout.positive?
94
+ timeout = 180
95
+ elsif timeout > 600
96
+ timeout = 600
97
+ end
98
+
99
+ wait_time = 1
100
+ start = Time.now
101
+ used_time = 0
102
+
103
+ loop do
104
+ get(status_polling_url, headers: { authorization: "Bearer #{bearer_token}", accept: 'application/json' })
105
+
106
+ retry_after_val = request.response_header('retry-after')&.value.to_i
107
+
108
+ wait_time = retry_after_val.positive? ? retry_after_val : wait_time *= 2
109
+
110
+ used_time = Time.now - start
111
+
112
+ total_time_to_next_poll = Time.now - start + wait_time
113
+
114
+ break if response[:status] != 202 || total_time_to_next_poll > timeout
115
+
116
+ sleep wait_time
117
+ end
118
+
119
+ if response[:status] == 202
120
+ skip "Server already used #{used_time} seconds processing this request, " \
121
+ "and next poll is #{wait_time} seconds after. " \
122
+ "The total wait time for next poll is more than #{timeout} seconds time out setting."
123
+ end
124
+
125
+ assert_response_status(200)
126
+
127
+ assert request.response_header('content-type')&.value&.include?('application/json'),
128
+ 'Content-Type not application/json'
129
+
130
+ assert_valid_json(response[:body])
131
+ response_body = JSON.parse(response[:body])
132
+
133
+ %w[transactionTime request requiresAccessToken output error].each do |key|
134
+ assert response_body.key?(key), "Complete Status response did not contain \"#{key}\" as required"
135
+ end
136
+
137
+ requires_access_token = response_body['requiresAccessToken'].to_s.downcase
138
+ status_response = response[:body]
139
+
140
+ [requires_access_token, status_response]
141
+ end
142
+
143
+ def check_bulk_data_output(export_status_response)
144
+ assert export_status_response.present?, 'Bulk Data Server status response not found'
145
+
146
+ assert_valid_json(export_status_response)
147
+ status_output = JSON.parse(export_status_response)['output']
148
+ assert status_output, 'Bulk Data Server status response does not contain output'
149
+
150
+ skip_if status_output.empty?, 'Bulk Data Server status response does not contain any data in the output'
151
+
152
+ begin
153
+ status_output_json = status_output.to_json
154
+ bulk_download_url = status_output[0]['url']
155
+
156
+ [status_output_json, bulk_download_url]
157
+ ensure
158
+ status_output.each do |file|
159
+ %w[type url].each do |key|
160
+ assert file.key?(key), "Output file did not contain \"#{key}\" as required"
161
+ end
162
+
163
+ if config.options[:require_absolute_urls_in_output]
164
+ assert file['url'].to_s.match?(%r{\Ahttps?://}),
165
+ "URLs in output file must be absolute, but found `#{file['url']}`."
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'export_kick_off_performer'
4
+ require_relative 'bulk_data_test_kit_properties'
5
+
6
+ module BulkDataTestKit
7
+ module BulkDataExportParametersTests
8
+ extend Forwardable
9
+
10
+ def_delegators 'self.class', :properties
11
+ def_delegators 'properties',
12
+ :resource_type,
13
+ :bulk_export_url
14
+
15
+ def perform_outputFormat_param_test
16
+ url = bulk_export_url.dup
17
+ url = bulk_export_url.gsub('[group_id]', group_id) if resource_type == 'Group'
18
+
19
+ ['application/fhir+ndjson', 'application/ndjson', 'ndjson'].each do |format|
20
+ kickoff_url = url.dup
21
+ perform_export_kick_off_request(params: { _outputFormat: format }, url: kickoff_url)
22
+ assert_response_status(202)
23
+
24
+ delete_export_kick_off_request
25
+ end
26
+ end
27
+
28
+ def perform_since_param_test(since_timestamp_param)
29
+ fhir_instant_regex = /
30
+ ([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)
31
+ -(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])
32
+ T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\.[0-9]+)
33
+ ?(Z|(\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))
34
+ /x
35
+
36
+ url = bulk_export_url.dup
37
+ url = bulk_export_url.gsub('[group_id]', group_id) if resource_type == 'Group'
38
+
39
+ assert since_timestamp_param.match?(fhir_instant_regex),
40
+ "The provided `_since` timestamp `#{since_timestamp_param}` is not a valid " \
41
+ '[FHIR instant](https://www.hl7.org/fhir/datatypes.html#instant).'
42
+
43
+ perform_export_kick_off_request(params: { _since: since_timestamp_param }, url:)
44
+ assert_response_status(202)
45
+
46
+ delete_export_kick_off_request
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../export_cancel_tests'
4
+
5
+ module BulkDataTestKit
6
+ module BulkDataV101
7
+ class BulkDataExportCancelTest < Inferno::Test
8
+ include BulkDataTestKit::BulkDataExportCancelTests
9
+ include BulkDataTestKit::ExportKickOffPerformer
10
+
11
+ id :bulk_data_export_cancel
12
+
13
+ title 'Bulk Data Server returns "202 Accepted" for delete request'
14
+ description <<~DESCRIPTION
15
+ After a bulk data request has been started, a client MAY send a delete request to the URL provided in the Content-Location header to cancel the request.
16
+ Bulk Data Server MUST support client's delete request and return HTTP Status Code of "202 Accepted"
17
+ DESCRIPTION
18
+ # link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/export/index.html#bulk-data-delete-request'
19
+
20
+ output :cancelled_polling_url
21
+
22
+ def self.properties
23
+ @properties ||= BulkDataTestKitProperties.new(
24
+ resource_type: config.options[:resource_type],
25
+ bulk_export_url: config.options[:bulk_export_url]
26
+ )
27
+ end
28
+
29
+ run do
30
+ cancelled_polling_url = perform_export_cancel_test
31
+ output cancelled_polling_url:
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../export_operation_tests'
4
+
5
+ module BulkDataTestKit
6
+ module BulkDataV101
7
+ class BulkDataKickOffTest < Inferno::Test
8
+ include BulkDataTestKit::BulkDataExportOperationTests
9
+ include BulkDataTestKit::ExportKickOffPerformer
10
+
11
+ id :bulk_data_kick_off
12
+
13
+ title 'Bulk Data Server returns "202 Accepted" and "Content-location" for bulk data $export operations'
14
+ description <<~DESCRIPTION
15
+ Response - Success
16
+
17
+ * HTTP Status Code of 202 Accepted
18
+ * Content-Location header with the absolute URL of an endpoint for subsequent status requests (polling location)
19
+ DESCRIPTION
20
+ # link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/export/index.html#response---success'
21
+
22
+ output :polling_url
23
+
24
+ def self.properties
25
+ @properties ||= BulkDataTestKitProperties.new(
26
+ resource_type: config.options[:resource_type],
27
+ bulk_export_url: config.options[:bulk_export_url]
28
+ )
29
+ end
30
+
31
+ run do
32
+ polling_url = export_kick_off_success
33
+ output polling_url:
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../export_operation_tests'
4
+
5
+ module BulkDataTestKit
6
+ module BulkDataV101
7
+ class BulkDataExportOperationSupportTest < Inferno::Test
8
+ include BulkDataTestKit::BulkDataExportOperationTests
9
+
10
+ id :bulk_data_export_operation_support
11
+ title 'Bulk Data Server declares support for particular bulk data export operation in CapabilityStatement'
12
+ description <<~DESCRIPTION
13
+ This test verifies that the Bulk Data Server declares support for
14
+ a particular bulk data operation in its server CapabilityStatement.
15
+
16
+ Given flexibility in the FHIR specification for declaring constrained
17
+ OperationDefinitions, this test only verifies that the server declares
18
+ any operation for the specific resource in the CapabilityStatement. It does not verify that it
19
+ declares the standard bulk data export OperationDefinition provided in the
20
+ Bulk Data specification, nor does it attempt to resolve any non-standard
21
+ OperationDefinitions to verify if it is a constrained version of the
22
+ standard OperationDefintion.
23
+
24
+ This test will provide a warning if no operations are declared via the
25
+ `CapabilityStatement.rest.resource.operation.name` element. It will
26
+ also provide an informational message if an operation on the particular
27
+ resource exists, but does not point to the standard OperationDefinition
28
+ canonical URL.
29
+
30
+ Additionally, this test provides a warning if the bulk data server does
31
+ not include the following URL in its `CapabilityStatement.instantiates`
32
+ element: http://hl7.org/fhir/uv/bulkdata/CapabilityStatement/bulk-data
33
+ DESCRIPTION
34
+
35
+ def self.properties
36
+ @properties ||= BulkDataTestKitProperties.new(
37
+ resource_type: config.options[:resource_type]
38
+ )
39
+ end
40
+
41
+ run do
42
+ check_export_support
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'bulk_data_group_export_test_group'
4
+ require_relative 'bulk_data_patient_export_test_group'
5
+ require_relative 'bulk_data_system_export_test_group'
6
+
7
+ module BulkDataTestKit
8
+ module BulkDataV101
9
+ class BulkDataSmartBackendServicesGroupV101 < Inferno::TestGroup
10
+ id :bulk_data_export_tests_v101
11
+ title 'Bulk Data Export Tests'
12
+
13
+ group do
14
+ id :bulk_data_server_tests
15
+ title 'Bulk Data Server TLS Tests'
16
+ run_as_group
17
+
18
+ test from: :tls_version_test do
19
+ title 'Bulk Data Server is secured by transport layer security'
20
+ description <<~DESCRIPTION
21
+ [§170.315(g)(10) Test
22
+ Procedure](https://www.healthit.gov/test-method/standardized-api-patient-and-population-services)
23
+ requires that all exchanges described herein between a client and a
24
+ server SHALL be secured using Transport Layer Security (TLS) Protocol
25
+ Version 1.2 (RFC5246).
26
+ DESCRIPTION
27
+ id :bulk_data_server_tls_version
28
+
29
+ config(
30
+ inputs: { url: { name: :bulk_server_url } },
31
+ options: { minimum_allowed_version: OpenSSL::SSL::TLS1_2_VERSION }
32
+ )
33
+ end
34
+ end
35
+
36
+ group from: :bulk_data_group_export_v101
37
+ group from: :bulk_data_patient_export_v101
38
+ group from: :bulk_data_system_export_v101
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'group/bulk_data_group_export_group'
4
+ require_relative 'group/bulk_data_group_export_cancel_group'
5
+ require_relative 'group/bulk_data_group_export_validation_group'
6
+
7
+ module BulkDataTestKit
8
+ module BulkDataV101
9
+ class BulkDataGroupTestGroup < Inferno::TestGroup
10
+ title 'Bulk Data Group API Tests'
11
+ id :bulk_data_group_export_v101
12
+ run_as_group
13
+
14
+ description %(
15
+ The Bulk Data Access API Tests evaluate the ability of a system (Bulk Data Server)
16
+ to support required Bulk Data Group $export operation.
17
+ )
18
+
19
+ group from: :bulk_data_group_export_group
20
+ group from: :bulk_data_group_export_validation
21
+ group from: :bulk_data_group_export_cancel_group
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../bulk_export_validation_tester'
4
+
5
+ module BulkDataTestKit
6
+ module BulkDataV101
7
+ class BulkDataMultiplePatientsTest < Inferno::Test
8
+ include BulkDataTestKit::BulkExportValidationTester
9
+
10
+ id :bulk_data_multiple_patients
11
+
12
+ title 'Export has at least two patients'
13
+ description <<~DESCRIPTION
14
+ This test verifies that the bulk data export has at least two patients.
15
+ DESCRIPTION
16
+ # link 'http://ndjson.org/'
17
+
18
+ run do
19
+ export_multiple_patients_check
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../bulk_export_validation_tester'
4
+
5
+ module BulkDataTestKit
6
+ module BulkDataV101
7
+ class BulkDataNDJSONDownloadTest < Inferno::Test
8
+ include BulkDataTestKit::BulkExportValidationTester
9
+
10
+ id :bulk_data_ndjson_download
11
+
12
+ title 'NDJSON download requires access token if requireAccessToken is true'
13
+ description <<~DESCRIPTION
14
+ If the requiresAccessToken field in the Complete Status body is set to true, the request SHALL include a valid#{' '}
15
+ access token.
16
+
17
+ [FHIR R4 Security](https://www.hl7.org/fhir/security.html#AccessDenied) and
18
+ [The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://tools.ietf.org/html/rfc6750#section-3.1)
19
+ recommend using HTTP status code 401 for invalid token but also allow the actual result be controlled by policy#{' '}
20
+ and context.
21
+ DESCRIPTION
22
+ # link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/export/index.html#file-request'
23
+
24
+ input :bulk_download_url
25
+ input :requires_access_token
26
+
27
+ run do
28
+ ndjson_download_requiresAccessToken_check(bulk_data_download_url: bulk_download_url,
29
+ bulk_requires_access_token: requires_access_token)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../export_operation_tests'
4
+
5
+ module BulkDataTestKit
6
+ module BulkDataV101
7
+ class BulkDataExportNoAuthRejectTest < Inferno::Test
8
+ include BulkDataTestKit::BulkDataExportOperationTests
9
+ include BulkDataTestKit::ExportKickOffPerformer
10
+
11
+ id :bulk_data_no_auth_reject
12
+
13
+ title 'Bulk Data Server rejects $export request without authorization'
14
+ description <<~DESCRIPTION
15
+ The FHIR server SHALL limit the data returned to only those FHIR resources for which the client is authorized.
16
+
17
+ [FHIR R4 Security](https://www.hl7.org/fhir/security.html#AccessDenied) and
18
+ [The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://tools.ietf.org/html/rfc6750#section-3.1)
19
+ recommend using HTTP status code 401 for invalid token but also allow the actual result be controlled by policy and context.
20
+ DESCRIPTION
21
+ # link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/export/index.html#bulk-data-kick-off-request'
22
+
23
+ def self.properties
24
+ @properties ||= BulkDataTestKitProperties.new(
25
+ resource_type: config.options[:resource_type],
26
+ bulk_export_url: config.options[:bulk_export_url]
27
+ )
28
+ end
29
+
30
+ run do
31
+ rejects_without_authorization
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../export_operation_tests'
4
+
5
+ module BulkDataTestKit
6
+ module BulkDataV101
7
+ class BulkDataOutputCheckTest < Inferno::Test
8
+ include BulkDataTestKit::BulkDataExportOperationTests
9
+
10
+ id :bulk_data_output_check
11
+
12
+ title 'Bulk Data Server returns output with type and url for status complete'
13
+ description <<~DESCRIPTION
14
+ The value of output field is an array of file items with one entry for each generated file.
15
+ If no resources are returned from the kick-off request, the server SHOULD return an empty array.
16
+
17
+ Each file item SHALL contain the following fields:
18
+
19
+ * type - the FHIR resource type that is contained in the file.
20
+
21
+ Each file SHALL contain resources of only one type, but a server MAY create more than one file for each resource type returned.
22
+
23
+ * url - the path to the file. The format of the file SHOULD reflect that requested in the _outputFormat parameter of the initial kick-off request.
24
+ DESCRIPTION
25
+ # link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/export/index.html#response---complete-status'
26
+
27
+ input :status_response
28
+
29
+ output :status_output, :bulk_download_url
30
+
31
+ def self.properties
32
+ @properties ||= BulkDataTestKitProperties.new(
33
+ resource_type: config.options[:resource_type]
34
+ )
35
+ end
36
+
37
+ run do
38
+ status_output, bulk_download_url = check_bulk_data_output(status_response)
39
+
40
+ output status_output:,
41
+ bulk_download_url:
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'patient/bulk_data_patient_export_group'
4
+ require_relative 'patient/bulk_data_patient_export_cancel_group'
5
+ require_relative 'patient/bulk_data_patient_export_validation_group'
6
+
7
+ module BulkDataTestKit
8
+ module BulkDataV101
9
+ class BulkDataPatientTestGroup < Inferno::TestGroup
10
+ title 'Bulk Data Patient API Tests'
11
+ id :bulk_data_patient_export_v101
12
+ run_as_group
13
+
14
+ description %(
15
+ The Bulk Data Access API Tests evaluate the ability of a system (Bulk Data Server)
16
+ to support required Bulk Data Patient $export operation.
17
+ )
18
+
19
+ group from: :bulk_data_patient_export_group
20
+ group from: :bulk_data_patient_export_validation
21
+ group from: :bulk_data_patient_export_cancel_group
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'smart_app_launch/smart_stu2_suite'
4
+
5
+ module BulkDataTestKit
6
+ module BulkDataV101
7
+ class BulkDataSmartBackendServicesGroup < Inferno::TestGroup
8
+ title 'SMART Backend Services'
9
+ id :bulk_data_smart_backend_services
10
+ run_as_group
11
+ optional
12
+
13
+ group from: :smart_discovery_stu2,
14
+ config: {
15
+ inputs: { url: { name: :bulk_server_url } }
16
+ }
17
+
18
+ group from: :backend_services_authorization
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../export_operation_tests'
4
+
5
+ module BulkDataTestKit
6
+ module BulkDataV101
7
+ class BulkDataStatusCheckTest < Inferno::Test
8
+ include BulkDataTestKit::BulkDataExportOperationTests
9
+
10
+ id :bulk_data_status_check
11
+
12
+ title 'Bulk Data Server returns "202 Accepted" or "200 OK" for status check'
13
+ description <<~DESCRIPTION
14
+ Clients SHOULD follow an exponential backoff approach when polling for status. Servers SHOULD respond with
15
+
16
+ * In-Progress Status: HTTP Status Code of 202 Accepted
17
+ * Complete Status: HTTP status of 200 OK and Content-Type header of application/json
18
+
19
+ The JSON object of Complete Status SHALL contain these required field:
20
+
21
+ * transactionTime, request, requiresAccessToken, output, and error
22
+ DESCRIPTION
23
+ # link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/export/index.html#bulk-data-status-request'
24
+
25
+ input :polling_url
26
+
27
+ output :status_response, :requires_access_token
28
+
29
+ def self.properties
30
+ @properties ||= BulkDataTestKitProperties.new(
31
+ resource_type: config.options[:resource_type]
32
+ )
33
+ end
34
+
35
+ run do
36
+ requires_access_token, status_response = export_status_check_success(polling_url)
37
+
38
+ output(requires_access_token:)
39
+ output status_response:
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'system_export/bulk_data_system_export_group'
4
+ require_relative 'system_export/bulk_data_system_export_cancel_group'
5
+ require_relative 'system_export/bulk_data_system_export_validation_group'
6
+
7
+ module BulkDataTestKit
8
+ module BulkDataV101
9
+ class BulkDataSystemExportTestGroup < Inferno::TestGroup
10
+ title 'Bulk Data System Level Export API Tests'
11
+ id :bulk_data_system_export_v101
12
+ run_as_group
13
+
14
+ description %(
15
+ The Bulk Data Access API Tests evaluate the ability of a system (Bulk Data Server)
16
+ to support required Bulk Data system $export operation.
17
+ )
18
+
19
+ group from: :bulk_data_system_export_group
20
+ group from: :bulk_data_system_export_validation
21
+ group from: :bulk_data_system_export_cancel_group
22
+ end
23
+ end
24
+ end