davinci_pas_test_kit 0.12.0 → 0.12.1

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/lib/davinci_pas_test_kit/client_suite.rb +24 -0
  3. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_approval_submit_test.rb +29 -1
  4. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_denial_submit_test.rb +27 -4
  5. data/lib/davinci_pas_test_kit/{generated/v2.0.1/client_tests/client_pended_pas_inquiry_request_bundle_validation_test.rb → custom_groups/v2.0.1/client_tests/pas_client_inquire_request_bundle_validation_test.rb} +22 -20
  6. data/lib/davinci_pas_test_kit/{generated/v2.0.1/client_tests/client_denial_pas_response_bundle_validation_test.rb → custom_groups/v2.0.1/client_tests/pas_client_inquire_response_bundle_validation_test.rb} +34 -21
  7. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_submit_test.rb +124 -5
  8. data/lib/davinci_pas_test_kit/{generated/v2.0.1/client_tests/client_pas_request_bundle_validation_test.rb → custom_groups/v2.0.1/client_tests/pas_client_request_bundle_validation_test.rb} +22 -20
  9. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/{pas_client_approval_submit_response_attest.rb → pas_client_response_attest.rb} +26 -9
  10. data/lib/davinci_pas_test_kit/{generated/v2.0.1/client_tests/client_pended_pas_response_bundle_validation_test.rb → custom_groups/v2.0.1/client_tests/pas_client_response_bundle_validation_test.rb} +44 -20
  11. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_subscription_create_test.rb +49 -0
  12. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_subscription_pas_conformance_test.rb +48 -0
  13. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_approval_group.rb +21 -9
  14. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_authentication_group.rb +2 -2
  15. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_denial_group.rb +21 -22
  16. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_pended_group.rb +97 -31
  17. data/lib/davinci_pas_test_kit/docs/client_suite_description_v201.md +213 -72
  18. data/lib/davinci_pas_test_kit/endpoints/claim_endpoint.rb +85 -134
  19. data/lib/davinci_pas_test_kit/endpoints/subscription_create_endpoint.rb +96 -0
  20. data/lib/davinci_pas_test_kit/endpoints/subscription_status_endpoint.rb +90 -0
  21. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_request_bundle/metadata.yml +0 -2
  22. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_request_bundle/server_pas_inquiry_request_bundle_validation_test.rb +3 -1
  23. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_response_bundle/server_pas_inquiry_response_bundle_validation_test.rb +2 -1
  24. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_request_bundle/metadata.yml +0 -2
  25. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_request_bundle/server_pas_request_bundle_validation_test.rb +3 -1
  26. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_response_bundle/metadata.yml +0 -4
  27. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_response_bundle/server_pas_response_bundle_validation_test.rb +2 -1
  28. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_server_denial_use_case_group.rb +1 -1
  29. data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_server_pended_use_case_group.rb +6 -5
  30. data/lib/davinci_pas_test_kit/generated/v2.0.1/server_suite.rb +1 -0
  31. data/lib/davinci_pas_test_kit/generator/group_generator.rb +9 -8
  32. data/lib/davinci_pas_test_kit/generator/group_metadata_extractor.rb +7 -3
  33. data/lib/davinci_pas_test_kit/generator/templates/suite.rb.erb +1 -0
  34. data/lib/davinci_pas_test_kit/generator/validation_test_generator.rb +19 -56
  35. data/lib/davinci_pas_test_kit/generator/value_extractor.rb +4 -1
  36. data/lib/davinci_pas_test_kit/generator.rb +1 -1
  37. data/lib/davinci_pas_test_kit/jobs/send_pas_subscription_notification.rb +136 -0
  38. data/lib/davinci_pas_test_kit/jobs/send_subscription_handshake.rb +139 -0
  39. data/lib/davinci_pas_test_kit/pas_bundle_validation.rb +8 -7
  40. data/lib/davinci_pas_test_kit/response_generator.rb +397 -0
  41. data/lib/davinci_pas_test_kit/tags.rb +9 -0
  42. data/lib/davinci_pas_test_kit/urls.rb +8 -0
  43. data/lib/davinci_pas_test_kit/user_input_response.rb +11 -8
  44. data/lib/davinci_pas_test_kit/validation_test.rb +0 -1
  45. data/lib/davinci_pas_test_kit/version.rb +2 -2
  46. metadata +30 -14
  47. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_denial_submit_response_attest.rb +0 -38
  48. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_inquire_response_attest.rb +0 -39
  49. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_inquire_test.rb +0 -35
  50. data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_submit_response_attest.rb +0 -39
  51. data/lib/davinci_pas_test_kit/generator/templates/validation_client.rb.erb +0 -50
@@ -0,0 +1,96 @@
1
+ require_relative '../tags'
2
+ require_relative '../jobs/send_subscription_handshake'
3
+ require 'subscriptions_test_kit'
4
+
5
+ module DaVinciPASTestKit
6
+ class SubscriptionCreateEndpoint < Inferno::DSL::SuiteEndpoint
7
+ include SubscriptionsTestKit::SubscriptionsR5BackportR4Client::SubscriptionSimulationUtils
8
+
9
+ def test_run_identifier
10
+ request.headers['authorization']&.delete_prefix('Bearer ')
11
+ end
12
+
13
+ def make_response
14
+ response.format = :json
15
+ response.status = 400
16
+
17
+ begin
18
+ subscription = FHIR.from_contents(request.body.string)
19
+ rescue StandardError
20
+ response.body = operation_outcome('error', 'invalid', 'No recognized R4 Subscription in request body').to_json
21
+ return
22
+ end
23
+
24
+ verification_outcome = verify_subscription(subscription)
25
+ if verification_outcome.present?
26
+ response.body = verification_outcome.to_json
27
+ return
28
+ end
29
+
30
+ # Deny subscription if one already created
31
+ requests = requests_repo.tagged_requests(test_run.test_session_id, tags)
32
+ existing_subscription_request = requests.find { |r| r.status == 201 }
33
+ if existing_subscription_request.present?
34
+ subscription_hash = JSON.parse(existing_subscription_request.response_body)
35
+ error_text = 'Inferno only supports one subscription per test run. Subscription already created with ' \
36
+ "ID #{subscription_hash['id']}"
37
+ response.body = operation_outcome('error', 'business-rule', error_text).to_json
38
+ return
39
+ end
40
+
41
+ # Form response
42
+ notification_json = nil # no notification
43
+ subscription_id = SecureRandom.uuid
44
+ # We have to manipulate the raw hash so that we don't lose the _payload primitive extension
45
+ subscription_hash = JSON.parse(request.body.string).merge('id' => subscription_id, 'status' => 'requested')
46
+ subscription_hash['channel']['payload'] = actual_mime_type(subscription)
47
+ response.status = 201
48
+ response.body = subscription_hash.to_json
49
+
50
+ # Kick off handshake job
51
+ subscription_url = "#{request.url}/#{subscription_id}"
52
+ client_endpoint = subscription.channel.endpoint
53
+ bearer_token = client_access_token_input(result)
54
+ test_suite_base_url = request.url.chomp('/').chomp(FHIR_SUBSCRIPTION_PATH)
55
+ Inferno::Jobs.perform(Jobs::SendSubscriptionHandshake, test_run.id, test_run.test_session_id, result.id,
56
+ subscription_id, subscription_url, client_endpoint, bearer_token, notification_json,
57
+ test_run_identifier, test_suite_base_url)
58
+ end
59
+
60
+ def tags
61
+ [SUBSCRIPTION_CREATE_TAG]
62
+ end
63
+
64
+ def verify_subscription(subscription)
65
+ unless subscription.is_a? FHIR::Subscription
66
+ return operation_outcome('error', 'invalid', 'No recognized R4 Subscription in request body')
67
+ end
68
+
69
+ unless subscription.channel&.type == 'rest-hook'
70
+ return operation_outcome('error', 'business-rule', 'channel.type must be rest-hook')
71
+ end
72
+
73
+ unless valid_url?(subscription.channel&.endpoint)
74
+ return operation_outcome('error', 'value', 'channel.endpoint is not recognized as a conformant URL')
75
+ end
76
+
77
+ heartbeat_period = find_heartbeat_period(subscription)
78
+ operation_outcome('error', 'not-supported', 'heartbeatPeriod is not supported') unless heartbeat_period.nil?
79
+ end
80
+
81
+ def find_heartbeat_period(subscription)
82
+ return unless subscription.present?
83
+
84
+ subscription.channel&.extension&.find do |e|
85
+ e.url == 'http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-heartbeat-period'
86
+ end
87
+ end
88
+
89
+ def valid_url?(url)
90
+ uri = URI.parse(url)
91
+ %w[http https].include?(uri.scheme)
92
+ rescue URI::InvalidURIError
93
+ false
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,90 @@
1
+ require_relative '../tags'
2
+ require 'subscriptions_test_kit'
3
+
4
+ module DaVinciPASTestKit
5
+ class SubscriptionStatusEndpoint < Inferno::DSL::SuiteEndpoint
6
+ include SubscriptionsTestKit::SubscriptionsR5BackportR4Client::SubscriptionSimulationUtils
7
+ include ResponseGenerator
8
+
9
+ def test_run_identifier
10
+ request.headers['authorization']&.delete_prefix('Bearer ')
11
+ end
12
+
13
+ def make_response
14
+ response.format = :json
15
+ subscription = find_subscription(test_run.test_session_id)
16
+
17
+ unless subscription.present?
18
+ not_found
19
+ return
20
+ end
21
+
22
+ subscription_id = request.params[:id]
23
+
24
+ # Handle resource-level status params
25
+ unless subscription_id.present?
26
+ begin
27
+ params = FHIR.from_contents(request.body.string)
28
+ rescue StandardError
29
+ response.status = 400
30
+ response.body = operation_outcome('error', 'invalid', 'Invalid Parameters in request body').to_json
31
+ return
32
+ end
33
+
34
+ unless subscription_params_match?(params, subscription)
35
+ not_found
36
+ return
37
+ end
38
+ end
39
+
40
+ subscription_url = "#{base_subscription_url}/#{subscription.id}"
41
+ subscription_topic = subscription.criteria
42
+ status_code = determine_subscription_status_code(subscription_id)
43
+ event_count = determine_event_count(test_run.test_session_id)
44
+
45
+ notification_json = notification_bundle_input(result)
46
+ if notification_json.blank?
47
+ notification_timestamp = Time.now.utc
48
+ mock_status_bundle = FHIR::Bundle.new(
49
+ id: SecureRandom.uuid,
50
+ timestamp: notification_timestamp.iso8601,
51
+ type: 'history'
52
+ )
53
+ mock_notification_status = build_mock_notification_status(notification_timestamp, subscription_url,
54
+ subscription_topic, nil, nil)
55
+ mock_status_bundle.entry << build_mock_notification_status_entry(mock_notification_status, subscription_url)
56
+ notification_json = mock_status_bundle.to_json
57
+ end
58
+ response.body = derive_status_bundle(notification_json, subscription_url, subscription_topic, status_code,
59
+ event_count, request.url).to_json
60
+ response.status = 200
61
+ end
62
+
63
+ def subscription_params_match?(params, subscription)
64
+ id_params = find_params(params, 'id')
65
+
66
+ return false if id_params&.any? && id_params&.none? { |p| p.valueString == subscription.id }
67
+
68
+ status_params = find_params(params, 'status')
69
+ subscription_status = determine_subscription_status_code(subscription.id)
70
+ status_params.blank? || status_params.any? { |p| p.valueString == subscription_status }
71
+ end
72
+
73
+ def tags
74
+ [SUBSCRIPTION_STATUS_TAG]
75
+ end
76
+
77
+ def not_found
78
+ response.status = 404
79
+ response.body = operation_outcome('error', 'not-found').to_json
80
+ end
81
+
82
+ def find_params(params, name)
83
+ params&.parameter&.filter { |p| p.name == name }
84
+ end
85
+
86
+ def base_subscription_url
87
+ request.url.sub(/(#{Regexp.escape(FHIR_SUBSCRIPTION_PATH)}).*/, '\1')
88
+ end
89
+ end
90
+ end
@@ -68,8 +68,6 @@
68
68
  :tests:
69
69
  - :id: pas_server_v201_pas_inquiry_request_bundle_validation_test
70
70
  :file_name: server_pas_inquiry_request_bundle_validation_test.rb
71
- - :id: pas_client_v201_pended_pas_inquiry_request_bundle_validation_test
72
- :file_name: client_pended_pas_inquiry_request_bundle_validation_test.rb
73
71
  - :id: pas_server_inquire_request_v201_pas_inquiry_request_bundle_must_support_test
74
72
  :file_name: server_inquire_request_pas_inquiry_request_bundle_must_support_test.rb
75
73
  - :id: pas_client_inquire_request_v201_pas_inquiry_request_bundle_must_support_test
@@ -11,9 +11,11 @@ module DaVinciPASTestKit
11
11
  **USER INPUT VALIDATION**: This test validates input provided by the user instead of the system under test.
12
12
  Errors encountered will be treated as a skip instead of a failure.
13
13
 
14
+
14
15
  This test validates the conformity of the
15
16
  user input to the
16
- [PAS Inquiry Request Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-inquiry-request-bundle) structure, ensuring subsequent tests can accurately simulate content.
17
+ [PAS Inquiry Request Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-inquiry-request-bundle)
18
+ structure, ensuring subsequent tests can accurately simulate content.
17
19
 
18
20
  It also checks that other conformance requirements defined in the [PAS Formal
19
21
  Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
@@ -10,7 +10,8 @@ module DaVinciPASTestKit
10
10
  description %(
11
11
  This test validates the conformity of the
12
12
  server's response to the
13
- [PAS Inquiry Response Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-inquiry-response-bundle) structure.
13
+ [PAS Inquiry Response Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-inquiry-response-bundle)
14
+ structure.
14
15
 
15
16
  It also checks that other conformance requirements defined in the [PAS Formal
16
17
  Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
@@ -68,8 +68,6 @@
68
68
  :tests:
69
69
  - :id: pas_server_v201_pas_request_bundle_validation_test
70
70
  :file_name: server_pas_request_bundle_validation_test.rb
71
- - :id: pas_client_v201_pas_request_bundle_validation_test
72
- :file_name: client_pas_request_bundle_validation_test.rb
73
71
  - :id: pas_server_submit_request_v201_pas_request_bundle_must_support_test
74
72
  :file_name: server_submit_request_pas_request_bundle_must_support_test.rb
75
73
  - :id: pas_client_submit_request_v201_pas_request_bundle_must_support_test
@@ -11,9 +11,11 @@ module DaVinciPASTestKit
11
11
  **USER INPUT VALIDATION**: This test validates input provided by the user instead of the system under test.
12
12
  Errors encountered will be treated as a skip instead of a failure.
13
13
 
14
+
14
15
  This test validates the conformity of the
15
16
  user input to the
16
- [PAS Request Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-request-bundle) structure, ensuring subsequent tests can accurately simulate content.
17
+ [PAS Request Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-request-bundle)
18
+ structure, ensuring subsequent tests can accurately simulate content.
17
19
 
18
20
  It also checks that other conformance requirements defined in the [PAS Formal
19
21
  Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
@@ -62,10 +62,6 @@
62
62
  :tests:
63
63
  - :id: pas_server_v201_pas_response_bundle_validation_test
64
64
  :file_name: server_pas_response_bundle_validation_test.rb
65
- - :id: pas_client_v201_denial_pas_response_bundle_validation_test
66
- :file_name: client_denial_pas_response_bundle_validation_test.rb
67
- - :id: pas_client_v201_pended_pas_response_bundle_validation_test
68
- :file_name: client_pended_pas_response_bundle_validation_test.rb
69
65
  - :id: pas_server_submit_response_v201_pas_response_bundle_must_support_test
70
66
  :file_name: server_submit_response_pas_response_bundle_must_support_test.rb
71
67
  :delayed_references: []
@@ -10,7 +10,8 @@ module DaVinciPASTestKit
10
10
  description %(
11
11
  This test validates the conformity of the
12
12
  server's response to the
13
- [PAS Response Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-response-bundle) structure.
13
+ [PAS Response Bundle](http://hl7.org/fhir/us/davinci-pas/StructureDefinition/profile-pas-response-bundle)
14
+ structure.
14
15
 
15
16
  It also checks that other conformance requirements defined in the [PAS Formal
16
17
  Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
@@ -9,7 +9,7 @@ module DaVinciPASTestKit
9
9
  title 'Successful Denial Workflow'
10
10
  description %(
11
11
  Demonstrate the ability of the server to respond to a prior
12
- authorization request with an `denied` decision.
12
+ authorization request with a `denied` decision.
13
13
 
14
14
  )
15
15
 
@@ -13,12 +13,13 @@ module DaVinciPASTestKit
13
13
  title 'Successful Pended Workflow'
14
14
  description %(
15
15
  Demonstrate a complete prior authorization workflow including a period
16
- during which the final decision is pending. This includes
16
+ during which the final decision is pending. This includes demonstrating
17
+ the ability of the server to
17
18
 
18
- - Demonstrating the ability of the server to respond to a prior
19
- authorization request with an `pended` status.
20
- - Demonstrating the ability of the server to respond to a subsequent
21
- inquiry request with a final decision for the request
19
+ - Respond to a prior authorization request with a `pended` status.
20
+ - Accept a Subscription creation request and send a notification when
21
+ the pended claim has been finalized.
22
+ - Respond to a subsequent inquiry request with a final decision for the request.
22
23
 
23
24
  )
24
25
 
@@ -1,3 +1,4 @@
1
+ require 'subscriptions_test_kit'
1
2
  require_relative '../../validator_suppressions'
2
3
  require_relative '../../custom_groups/v2.0.1/pas_error_group'
3
4
  require_relative 'pas_server_approval_use_case_group'
@@ -276,7 +276,7 @@ module DaVinciPASTestKit
276
276
  else
277
277
  client_inquiry_request_must_support_test_ids
278
278
  end
279
- elsif use_case == 'approval' || use_case == 'denial'
279
+ elsif ['approval', 'denial'].include?(use_case)
280
280
  grouped_approval_denial_test_ids
281
281
  elsif use_case == 'pended'
282
282
  grouped_pended_test_ids
@@ -292,7 +292,7 @@ module DaVinciPASTestKit
292
292
  else
293
293
  client_inquiry_request_must_support_test_file_list
294
294
  end
295
- elsif use_case == 'approval' || use_case == 'denial'
295
+ elsif ['approval', 'denial'].include?(use_case)
296
296
  approval_denial_test_file_list
297
297
  elsif use_case == 'pended'
298
298
  pended_test_file_list
@@ -375,17 +375,18 @@ module DaVinciPASTestKit
375
375
  when 'denial'
376
376
  <<~DESCRIPTION
377
377
  Demonstrate the ability of the server to respond to a prior
378
- authorization request with an `denied` decision.
378
+ authorization request with a `denied` decision.
379
379
  DESCRIPTION
380
380
  when 'pended'
381
381
  <<~DESCRIPTION
382
382
  Demonstrate a complete prior authorization workflow including a period
383
- during which the final decision is pending. This includes
383
+ during which the final decision is pending. This includes demonstrating
384
+ the ability of the server to
384
385
 
385
- - Demonstrating the ability of the server to respond to a prior
386
- authorization request with an `pended` status.
387
- - Demonstrating the ability of the server to respond to a subsequent
388
- inquiry request with a final decision for the request
386
+ - Respond to a prior authorization request with a `pended` status.
387
+ - Accept a Subscription creation request and send a notification when
388
+ the pended claim has been finalized.
389
+ - Respond to a subsequent inquiry request with a final decision for the request.
389
390
  DESCRIPTION
390
391
  else # must_support
391
392
  <<~DESCRIPTION
@@ -130,7 +130,9 @@ module DaVinciPASTestKit
130
130
  end
131
131
 
132
132
  def conformance_expectation
133
- resource_capabilities&.extension&.first&.valueCode
133
+ return unless resource_capabilities.present?
134
+
135
+ resource_capabilities.extension&.first&.valueCode
134
136
  end
135
137
 
136
138
  def profile_name
@@ -155,7 +157,8 @@ module DaVinciPASTestKit
155
157
  resource_capabilities.interaction.map do |interaction|
156
158
  {
157
159
  code: interaction.code,
158
- expectation: interaction&.extension&.first&.valueCode # TODO: fix expectation extension finding
160
+ # TODO: fix expectation extension finding
161
+ expectation: interaction.present? ? interaction.extension&.first&.valueCode : nil
159
162
  }
160
163
  end
161
164
  end
@@ -165,7 +168,8 @@ module DaVinciPASTestKit
165
168
  resource_capabilities.operation.map do |operation|
166
169
  {
167
170
  code: operation.name,
168
- expectation: operation&.extension&.first&.valueCode # TODO: fix expectation extension finding
171
+ # TODO: fix expectation extension finding
172
+ expectation: operation.present? ? operation.extension&.first&.valueCode : nil
169
173
  }
170
174
  end
171
175
  end
@@ -1,3 +1,4 @@
1
+ require 'subscriptions_test_kit'
1
2
  require_relative '../../validator_suppressions'
2
3
  require_relative '<%= error_group_file_name %>'
3
4
  <% group_file_list.each do |file_name| %>require_relative '<%= file_name %>'
@@ -6,42 +6,23 @@ module DaVinciPASTestKit
6
6
  class ValidationTestGenerator
7
7
  class << self
8
8
  def generate(ig_metadata, base_output_dir)
9
- ['server', 'client'].each do |system|
10
- if system == 'server'
11
- ig_metadata.bundle_groups.each do |group|
12
- new(group, system, base_output_dir:).generate
13
- end
14
- else
15
- ig_metadata.bundle_groups.each do |group|
16
- case group.profile_name
17
- when 'PAS Request Bundle'
18
- new(group, system, base_output_dir:).generate
19
- when 'PAS Inquiry Request Bundle'
20
- new(group, system, 'pended_inquiry', base_output_dir:).generate
21
- when 'PAS Response Bundle'
22
- ['denial', 'pended'].each do |workflow|
23
- new(group, system, workflow, base_output_dir:).generate
24
- end
25
- end
26
- end
27
- end
9
+ ig_metadata.bundle_groups.each do |group|
10
+ new(group, base_output_dir:).generate
28
11
  end
29
12
  end
30
13
  end
31
14
 
32
- attr_accessor :group_metadata, :medication_request_metadata, :base_output_dir, :system, :workflow
15
+ attr_accessor :group_metadata, :medication_request_metadata, :base_output_dir, :workflow
33
16
 
34
- def initialize(group_metadata, system, workflow = nil, medication_request_metadata = nil, base_output_dir:)
17
+ def initialize(group_metadata, workflow = nil, medication_request_metadata = nil, base_output_dir:)
35
18
  self.group_metadata = group_metadata
36
- self.system = system
37
19
  self.workflow = workflow
38
20
  self.medication_request_metadata = medication_request_metadata
39
21
  self.base_output_dir = base_output_dir
40
22
  end
41
23
 
42
24
  def template
43
- temp = system == 'server' ? 'validation.rb.erb' : 'validation_client.rb.erb'
44
- @template ||= File.read(File.join(__dir__, 'templates', temp))
25
+ @template ||= File.read(File.join(__dir__, 'templates', 'validation.rb.erb'))
45
26
  end
46
27
 
47
28
  def output
@@ -61,8 +42,6 @@ module DaVinciPASTestKit
61
42
  end
62
43
 
63
44
  def directory_name
64
- return 'client_tests' if system == 'client'
65
-
66
45
  Naming.snake_case_for_profile(medication_request_metadata || group_metadata)
67
46
  end
68
47
 
@@ -87,12 +66,12 @@ module DaVinciPASTestKit
87
66
  end
88
67
 
89
68
  def test_id
90
- pref = "pas_#{system}_#{group_metadata.reformatted_version}_#{formatted_workflow}".delete_suffix('_')
69
+ pref = "pas_server_#{group_metadata.reformatted_version}_#{formatted_workflow}".delete_suffix('_')
91
70
  "#{pref}_#{profile_identifier}_validation_test"
92
71
  end
93
72
 
94
73
  def class_name
95
- pref = "#{system.capitalize}#{formatted_workflow.camelize}"
74
+ pref = "Server#{formatted_workflow.camelize}"
96
75
  "#{pref}#{Naming.upper_camel_case_for_profile(group_metadata)}ValidationTest"
97
76
  end
98
77
 
@@ -135,14 +114,23 @@ module DaVinciPASTestKit
135
114
  end
136
115
 
137
116
  def user_input?
138
- (system == 'server' && request_type.include?('request')) ||
139
- (system == 'client' && request_type.include?('response'))
117
+ request_type.include?('request')
140
118
  end
141
119
 
142
120
  def description
143
121
  <<~DESCRIPTION
144
122
  #{description_user_input_validation if user_input?}
145
- #{system == 'server' ? description_intro_server : description_intro_client}
123
+
124
+ This test validates the conformity of the
125
+ #{request_type.include?('request') ? 'user input' : "server's response"} to the
126
+ [#{profile_name}](#{profile_url})#{' '}
127
+ structure#{request_type.include?('request') ? ', ensuring subsequent tests can accurately simulate content.' : '.'}
128
+
129
+ It also checks that other conformance requirements defined in the [PAS Formal
130
+ Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
131
+ such as the presence of all referenced instances within the bundle and the
132
+ conformance of those instances to the appropriate profiles, are met.
133
+
146
134
  It verifies the presence of mandatory elements and that elements with
147
135
  required bindings contain appropriate values. CodeableConcept element
148
136
  bindings will fail if none of their codings have a code/system belonging
@@ -162,31 +150,6 @@ module DaVinciPASTestKit
162
150
  DESCRIPTION
163
151
  end
164
152
 
165
- def description_intro_server
166
- <<~GENERIC_INTRO
167
- This test validates the conformity of the
168
- #{request_type.include?('request') ? 'user input' : "server's response"} to the
169
- [#{profile_name}](#{profile_url}) structure#{request_type.include?('request') ? ', ensuring subsequent tests can accurately simulate content.' : '.'}
170
-
171
- It also checks that other conformance requirements defined in the [PAS Formal
172
- Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
173
- such as the presence of all referenced instances within the bundle and the
174
- conformance of those instances to the appropriate profiles, are met.
175
- GENERIC_INTRO
176
- end
177
-
178
- def description_intro_client
179
- <<~GENERIC_INTRO
180
- This test validates the conformity of the
181
- #{request_type.include?('response') ? 'user input' : "client's request"} to the
182
- [#{profile_name}](#{profile_url}) structure.
183
- It also checks that other conformance requirements defined in the [PAS Formal
184
- Specification](https://hl7.org/fhir/us/davinci-pas/STU2/specification.html),
185
- such as the presence of all referenced instances within the bundle and the
186
- conformance of those instances to the appropriate profiles, are met.
187
- GENERIC_INTRO
188
- end
189
-
190
153
  def description_user_input_validation
191
154
  <<~USER_INPUT_INTRO
192
155
  **USER INPUT VALIDATION**: This test validates input provided by the user instead of the system under test.
@@ -17,7 +17,10 @@ module DaVinciPASTestKit
17
17
  end
18
18
 
19
19
  def bound_systems(the_element)
20
- value_set(the_element)&.compose&.include&.reject { |code| code.concept.nil? }
20
+ vs = value_set(the_element)
21
+ return unless vs.present?
22
+
23
+ vs.compose&.include&.reject { |code| code.concept.nil? }
21
24
  end
22
25
 
23
26
  def values_from_value_set_binding(the_element)
@@ -38,7 +38,7 @@ module DaVinciPASTestKit
38
38
  end
39
39
 
40
40
  def load_ig_package
41
- FHIR.logger = Logger.new('/dev/null')
41
+ FHIR.logger = Logger.new(File::NULL)
42
42
  self.ig_resources = IGLoader.new(ig_file_name).load
43
43
  end
44
44