davinci_crd_test_kit 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/davinci_crd_test_kit/card_responses/propose_alternate_request.json +2 -52
  3. data/lib/davinci_crd_test_kit/card_responses/request_form_completion.json +46 -31
  4. data/lib/davinci_crd_test_kit/cards_validation.rb +8 -4
  5. data/lib/davinci_crd_test_kit/client_hooks_group.rb +22 -660
  6. data/lib/davinci_crd_test_kit/client_tests/appointment_book_receive_request_test.rb +17 -6
  7. data/lib/davinci_crd_test_kit/client_tests/client_appointment_book_group.rb +70 -0
  8. data/lib/davinci_crd_test_kit/client_tests/client_encounter_discharge_group.rb +71 -0
  9. data/lib/davinci_crd_test_kit/client_tests/client_encounter_start_group.rb +70 -0
  10. data/lib/davinci_crd_test_kit/client_tests/client_order_dispatch_group.rb +70 -0
  11. data/lib/davinci_crd_test_kit/client_tests/client_order_select_group.rb +72 -0
  12. data/lib/davinci_crd_test_kit/client_tests/client_order_sign_group.rb +71 -0
  13. data/lib/davinci_crd_test_kit/client_tests/decode_auth_token_test.rb +43 -23
  14. data/lib/davinci_crd_test_kit/client_tests/encounter_discharge_receive_request_test.rb +19 -6
  15. data/lib/davinci_crd_test_kit/client_tests/encounter_start_receive_request_test.rb +18 -6
  16. data/lib/davinci_crd_test_kit/client_tests/hook_request_optional_fields_test.rb +26 -10
  17. data/lib/davinci_crd_test_kit/client_tests/hook_request_required_fields_test.rb +20 -11
  18. data/lib/davinci_crd_test_kit/client_tests/hook_request_valid_context_test.rb +14 -10
  19. data/lib/davinci_crd_test_kit/client_tests/hook_request_valid_prefetch_test.rb +27 -110
  20. data/lib/davinci_crd_test_kit/client_tests/order_dispatch_receive_request_test.rb +18 -6
  21. data/lib/davinci_crd_test_kit/client_tests/order_select_receive_request_test.rb +18 -6
  22. data/lib/davinci_crd_test_kit/client_tests/order_sign_receive_request_test.rb +18 -6
  23. data/lib/davinci_crd_test_kit/client_tests/retrieve_jwks_test.rb +66 -29
  24. data/lib/davinci_crd_test_kit/client_tests/submitted_response_validation.rb +44 -0
  25. data/lib/davinci_crd_test_kit/client_tests/token_header_test.rb +45 -14
  26. data/lib/davinci_crd_test_kit/client_tests/token_payload_test.rb +43 -26
  27. data/lib/davinci_crd_test_kit/crd_client_suite.rb +0 -4
  28. data/lib/davinci_crd_test_kit/hook_request_field_validation.rb +240 -50
  29. data/lib/davinci_crd_test_kit/mock_service_response.rb +134 -120
  30. data/lib/davinci_crd_test_kit/routes/hook_request_endpoint.rb +26 -42
  31. data/lib/davinci_crd_test_kit/server_encounter_discharge_group.rb +24 -0
  32. data/lib/davinci_crd_test_kit/server_encounter_start_group.rb +24 -0
  33. data/lib/davinci_crd_test_kit/server_order_select_group.rb +24 -0
  34. data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_received_test.rb +4 -1
  35. data/lib/davinci_crd_test_kit/server_tests/service_request_optional_fields_validation_test.rb +8 -10
  36. data/lib/davinci_crd_test_kit/server_tests/service_request_required_fields_validation_test.rb +5 -10
  37. data/lib/davinci_crd_test_kit/tags.rb +6 -6
  38. data/lib/davinci_crd_test_kit/version.rb +1 -1
  39. metadata +9 -2
@@ -7,13 +7,13 @@ module DaVinciCRDTestKit
7
7
  id :crd_appointment_book_request
8
8
  title 'Request received for appointment-book hook'
9
9
  description %(
10
- This test waits for an incoming [appointment-book](https://hl7.org/fhir/us/davinci-crd/STU2/hooks.html#appointment-book)
11
- hook request and responds to the client with the response types selected as an input. This hook is a 'primary'
10
+ This test waits for multiple incoming [appointment-book](https://hl7.org/fhir/us/davinci-crd/STU2/hooks.html#appointment-book)
11
+ hook requests and responds to the client with the response types selected as an input. This hook is a 'primary'
12
12
  hook, meaning that CRD Servers SHALL, at minimum, return a [Coverage Information](https://hl7.org/fhir/us/davinci-crd/STU2/StructureDefinition-ext-coverage-information.html)
13
13
  system action for these hooks, even if the response indicates that further information is needed or that the
14
14
  level of detail provided is insufficient to determine coverage.
15
15
  )
16
- receives_request :appointment_book
16
+ config options: { accepts_multiple_requests: true }
17
17
 
18
18
  input :iss
19
19
  input :appointment_book_selected_response_types,
@@ -23,7 +23,8 @@ module DaVinciCRDTestKit
23
23
  response type that will be returned for this hook is the `Coverage Information` card type.
24
24
  ),
25
25
  type: 'checkbox',
26
- default: ['coverage_information'],
26
+ default: ['coverage_information', 'external_reference', 'instructions'],
27
+ optional: true,
27
28
  options: {
28
29
  list_options: [
29
30
  {
@@ -52,6 +53,14 @@ module DaVinciCRDTestKit
52
53
  }
53
54
  ]
54
55
  }
56
+ input :appointment_book_custom_response,
57
+ title: 'Custom response for appointment-book hook requests',
58
+ description: %(
59
+ A JSON string may be provided here to replace the normal response
60
+ from the hook request endpoint
61
+ ),
62
+ type: 'textarea',
63
+ optional: true
55
64
 
56
65
  run do
57
66
  wait(
@@ -59,11 +68,13 @@ module DaVinciCRDTestKit
59
68
  message: %(
60
69
  **Appointment Book CDS Service Test**:
61
70
 
62
- Invoke the appointment-book hook and send a request to:
71
+ Invoke the appointment-book hook and send requests to:
63
72
 
64
73
  `#{appointment_book_url}`
65
74
 
66
- Inferno will process the request and return CDS cards if successful.
75
+ Inferno will process the requests and return CDS cards if successful.
76
+
77
+ [Click here](#{resume_pass_url}?token=appointment-book%20#{iss}) when you have finished submitting requests.
67
78
  )
68
79
  )
69
80
  end
@@ -0,0 +1,70 @@
1
+ require_relative 'appointment_book_receive_request_test'
2
+ require_relative 'client_display_cards_attest'
3
+ require_relative 'decode_auth_token_test'
4
+ require_relative 'hook_request_optional_fields_test'
5
+ require_relative 'hook_request_required_fields_test'
6
+ require_relative 'hook_request_valid_context_test'
7
+ require_relative 'hook_request_valid_prefetch_test'
8
+ require_relative 'retrieve_jwks_test'
9
+ require_relative 'submitted_response_validation'
10
+ require_relative 'token_header_test'
11
+ require_relative 'token_payload_test'
12
+
13
+ module DaVinciCRDTestKit
14
+ class ClientAppointmentBookGroup < Inferno::TestGroup
15
+ title 'appointment-book'
16
+ id :crd_client_appointment_book
17
+ description <<~DESCRIPTION
18
+ The appointment-book hook is invoked when the user is scheduling one or more future encounters/visits for the
19
+ patient. These tests are based on the following criteria:
20
+ * [CRD IG requirements for this hook](https://hl7.org/fhir/us/davinci-crd/STU2/hooks.html#appointment-book),
21
+ which include the profiles that are expected to be used for the resources resolved to by `context` FHIR ID
22
+ fields
23
+ * Specific [appointment-book `context` requirements](https://cds-hooks.hl7.org/hooks/appointment-book/2023SepSTU1Ballot/appointment-book/)
24
+ defined in the CDS Hooks specification
25
+
26
+ This version of the CRD implementation guide refers to version 1.0 of the hook.
27
+ DESCRIPTION
28
+
29
+ run_as_group
30
+
31
+ config(
32
+ inputs: {
33
+ auth_token_headers_json: { name: :appointment_book_auth_token_headers_json },
34
+ auth_tokens: { name: :appointment_book_auth_tokens },
35
+ auth_tokens_jwk_json: { name: :appointment_book_auth_tokens_jwk_json },
36
+ client_access_token: { name: :appointment_book_client_access_token },
37
+ client_fhir_server: { name: :appointment_book_client_fhir_server },
38
+ crd_jwks_keys_json: { name: :appointment_book_crd_jwks_keys_json },
39
+ custom_response: { name: :appointment_book_custom_response },
40
+ selected_response_types: { name: :appointment_book_selected_response_types }
41
+ },
42
+ outputs: {
43
+ auth_token_headers_json: { name: :appointment_book_auth_token_headers_json },
44
+ auth_token_payloads_json: { name: :appointment_book_auth_token_payloads_json },
45
+ auth_tokens: { name: :appointment_book_auth_tokens },
46
+ auth_tokens_jwk_json: { name: :appointment_book_auth_tokens_jwk_json },
47
+ client_access_token: { name: :appointment_book_client_access_token },
48
+ client_fhir_server: { name: :appointment_book_client_fhir_server },
49
+ crd_jwks_json: { name: :appointment_book_crd_jwks_json },
50
+ crd_jwks_keys_json: { name: :appointment_book_crd_jwks_keys_json }
51
+ },
52
+ options: {
53
+ hook_name: 'appointment-book',
54
+ hook_path: APPOINTMENT_BOOK_PATH
55
+ }
56
+ )
57
+
58
+ test from: :crd_submitted_response_validation
59
+ test from: :crd_appointment_book_request
60
+ test from: :crd_decode_auth_token
61
+ test from: :crd_retrieve_jwks
62
+ test from: :crd_token_header
63
+ test from: :crd_token_payload
64
+ test from: :crd_hook_request_required_fields
65
+ test from: :crd_hook_request_optional_fields
66
+ test from: :crd_hook_request_valid_context
67
+ test from: :crd_hook_request_valid_prefetch
68
+ test from: :crd_card_display_attest_test
69
+ end
70
+ end
@@ -0,0 +1,71 @@
1
+ require_relative 'encounter_discharge_receive_request_test'
2
+ require_relative 'client_display_cards_attest'
3
+ require_relative 'decode_auth_token_test'
4
+ require_relative 'hook_request_optional_fields_test'
5
+ require_relative 'hook_request_required_fields_test'
6
+ require_relative 'hook_request_valid_context_test'
7
+ require_relative 'hook_request_valid_prefetch_test'
8
+ require_relative 'retrieve_jwks_test'
9
+ require_relative 'submitted_response_validation'
10
+ require_relative 'token_header_test'
11
+ require_relative 'token_payload_test'
12
+
13
+ module DaVinciCRDTestKit
14
+ class ClientEncounterDischargeGroup < Inferno::TestGroup
15
+ title 'encounter-discharge'
16
+ id :crd_client_encounter_discharge
17
+ description <<~DESCRIPTION
18
+ The encounter-discharge hook is invoked when the user is performing the discharge process for an encounter where
19
+ the notion of 'discharge' is relevant - typically an inpatient encounter. These tests are based on the
20
+ following criteria:
21
+ * [CRD IG requirements for this hook](https://hl7.org/fhir/us/davinci-crd/STU2/hooks.html#encounter-discharge),
22
+ which includes the profiles that are expected to be used for the resources resolved to by `context`
23
+ FHIR ID fields
24
+ * Specific [encounter-discharge `context` requirements](https://cds-hooks.hl7.org/hooks/encounter-discharge/2023SepSTU1Ballot/encounter-discharge/)
25
+ defined in the CDS Hooks specification
26
+
27
+ This version of the CRD implementation guide refers to version 1.0 of the hook.
28
+ DESCRIPTION
29
+
30
+ run_as_group
31
+
32
+ config(
33
+ inputs: {
34
+ auth_token_headers_json: { name: :encounter_discharge_auth_token_headers_json },
35
+ auth_tokens: { name: :encounter_discharge_auth_tokens },
36
+ auth_tokens_jwk_json: { name: :encounter_discharge_auth_tokens_jwk_json },
37
+ client_access_token: { name: :encounter_discharge_client_access_token },
38
+ client_fhir_server: { name: :encounter_discharge_client_fhir_server },
39
+ crd_jwks_keys_json: { name: :encounter_discharge_crd_jwks_keys_json },
40
+ custom_response: { name: :encounter_discharge_custom_response },
41
+ selected_response_types: { name: :encounter_discharge_selected_response_types }
42
+ },
43
+ outputs: {
44
+ auth_token_headers_json: { name: :encounter_discharge_auth_token_headers_json },
45
+ auth_token_payloads_json: { name: :encounter_discharge_auth_token_payloads_json },
46
+ auth_tokens: { name: :encounter_discharge_auth_tokens },
47
+ auth_tokens_jwk_json: { name: :encounter_discharge_auth_tokens_jwk_json },
48
+ client_access_token: { name: :encounter_discharge_client_access_token },
49
+ client_fhir_server: { name: :encounter_discharge_client_fhir_server },
50
+ crd_jwks_json: { name: :encounter_discharge_crd_jwks_json },
51
+ crd_jwks_keys_json: { name: :encounter_discharge_crd_jwks_keys_json }
52
+ },
53
+ options: {
54
+ hook_name: 'encounter-discharge',
55
+ hook_path: ENCOUNTER_DISCHARGE_PATH
56
+ }
57
+ )
58
+
59
+ test from: :crd_submitted_response_validation
60
+ test from: :crd_encounter_discharge_request
61
+ test from: :crd_decode_auth_token
62
+ test from: :crd_retrieve_jwks
63
+ test from: :crd_token_header
64
+ test from: :crd_token_payload
65
+ test from: :crd_hook_request_required_fields
66
+ test from: :crd_hook_request_optional_fields
67
+ test from: :crd_hook_request_valid_context
68
+ test from: :crd_hook_request_valid_prefetch
69
+ test from: :crd_card_display_attest_test
70
+ end
71
+ end
@@ -0,0 +1,70 @@
1
+ require_relative 'encounter_start_receive_request_test'
2
+ require_relative 'client_display_cards_attest'
3
+ require_relative 'decode_auth_token_test'
4
+ require_relative 'hook_request_optional_fields_test'
5
+ require_relative 'hook_request_required_fields_test'
6
+ require_relative 'hook_request_valid_context_test'
7
+ require_relative 'hook_request_valid_prefetch_test'
8
+ require_relative 'retrieve_jwks_test'
9
+ require_relative 'submitted_response_validation'
10
+ require_relative 'token_header_test'
11
+ require_relative 'token_payload_test'
12
+
13
+ module DaVinciCRDTestKit
14
+ class ClientEncounterStartGroup < Inferno::TestGroup
15
+ title 'encounter-start'
16
+ id :crd_client_encounter_start
17
+ description <<~DESCRIPTION
18
+ The encounter-start hook is invoked when the user is initiating a new encounter. These tests are based on the
19
+ following criteria:
20
+ * [CRD IG requirements for this hook](https://hl7.org/fhir/us/davinci-crd/STU2/hooks.html#encounter-start),
21
+ which include the profiles that are expected to be used for the resources resolved to by `context` FHIR ID
22
+ fields
23
+ * Specific [encounter-start `context` requirements](https://cds-hooks.hl7.org/hooks/encounter-start/2023SepSTU1Ballot/encounter-start/)
24
+ defined in the CDS Hooks specification
25
+
26
+ This version of the CRD implementation guide refers to version 1.0 of the hook.
27
+ DESCRIPTION
28
+
29
+ run_as_group
30
+
31
+ config(
32
+ inputs: {
33
+ auth_token_headers_json: { name: :encounter_start_auth_token_headers_json },
34
+ auth_tokens: { name: :encounter_start_auth_tokens },
35
+ auth_tokens_jwk_json: { name: :encounter_start_auth_tokens_jwk_json },
36
+ client_access_token: { name: :encounter_start_client_access_token },
37
+ client_fhir_server: { name: :encounter_start_client_fhir_server },
38
+ crd_jwks_keys_json: { name: :encounter_start_crd_jwks_keys_json },
39
+ custom_response: { name: :encounter_start_custom_response },
40
+ selected_response_types: { name: :encounter_start_selected_response_types }
41
+ },
42
+ outputs: {
43
+ auth_token_headers_json: { name: :encounter_start_auth_token_headers_json },
44
+ auth_token_payloads_json: { name: :encounter_start_auth_token_payloads_json },
45
+ auth_tokens: { name: :encounter_start_auth_tokens },
46
+ auth_tokens_jwk_json: { name: :encounter_start_auth_tokens_jwk_json },
47
+ client_access_token: { name: :encounter_start_client_access_token },
48
+ client_fhir_server: { name: :encounter_start_client_fhir_server },
49
+ crd_jwks_json: { name: :encounter_start_crd_jwks_json },
50
+ crd_jwks_keys_json: { name: :encounter_start_crd_jwks_keys_json }
51
+ },
52
+ options: {
53
+ hook_name: 'encounter-start',
54
+ hook_path: ENCOUNTER_START_PATH
55
+ }
56
+ )
57
+
58
+ test from: :crd_submitted_response_validation
59
+ test from: :crd_encounter_start_request
60
+ test from: :crd_decode_auth_token
61
+ test from: :crd_retrieve_jwks
62
+ test from: :crd_token_header
63
+ test from: :crd_token_payload
64
+ test from: :crd_hook_request_required_fields
65
+ test from: :crd_hook_request_optional_fields
66
+ test from: :crd_hook_request_valid_context
67
+ test from: :crd_hook_request_valid_prefetch
68
+ test from: :crd_card_display_attest_test
69
+ end
70
+ end
@@ -0,0 +1,70 @@
1
+ require_relative 'order_dispatch_receive_request_test'
2
+ require_relative 'client_display_cards_attest'
3
+ require_relative 'decode_auth_token_test'
4
+ require_relative 'hook_request_optional_fields_test'
5
+ require_relative 'hook_request_required_fields_test'
6
+ require_relative 'hook_request_valid_context_test'
7
+ require_relative 'hook_request_valid_prefetch_test'
8
+ require_relative 'retrieve_jwks_test'
9
+ require_relative 'submitted_response_validation'
10
+ require_relative 'token_header_test'
11
+ require_relative 'token_payload_test'
12
+
13
+ module DaVinciCRDTestKit
14
+ class ClientOrderDispatchGroup < Inferno::TestGroup
15
+ title 'order-dispatch'
16
+ id :crd_client_order_dispatch
17
+ description <<~DESCRIPTION
18
+ The order-dispatch hook fires when a practitioner is selecting a candidate performer for a pre-existing order
19
+ that was not tied to a specific performer. These tests are based on the following criteria:
20
+ * [CRD IG requirements for this hook](https://hl7.org/fhir/us/davinci-crd/STU2/hooks.html#order-dispatch),
21
+ which includes the profiles that are expected to be used for the resources resolved to by `context`
22
+ FHIR ID fields
23
+ * Specific [order-dispatch `context` requirements](https://cds-hooks.hl7.org/hooks/order-dispatch/2023SepSTU1Ballot/order-dispatch/)
24
+ defined in the CDS Hooks specification
25
+
26
+ This version of the CRD implementation guide refers to version 1.0 of the hook.
27
+ DESCRIPTION
28
+
29
+ run_as_group
30
+
31
+ config(
32
+ inputs: {
33
+ auth_token_headers_json: { name: :order_dispatch_auth_token_headers_json },
34
+ auth_tokens: { name: :order_dispatch_auth_tokens },
35
+ auth_tokens_jwk_json: { name: :order_dispatch_auth_tokens_jwk_json },
36
+ client_access_token: { name: :order_dispatch_client_access_token },
37
+ client_fhir_server: { name: :order_dispatch_client_fhir_server },
38
+ crd_jwks_keys_json: { name: :order_dispatch_crd_jwks_keys_json },
39
+ custom_response: { name: :order_dispatch_custom_response },
40
+ selected_response_types: { name: :order_dispatch_selected_response_types }
41
+ },
42
+ outputs: {
43
+ auth_token_headers_json: { name: :order_dispatch_auth_token_headers_json },
44
+ auth_token_payloads_json: { name: :order_dispatch_auth_token_payloads_json },
45
+ auth_tokens: { name: :order_dispatch_auth_tokens },
46
+ auth_tokens_jwk_json: { name: :order_dispatch_auth_tokens_jwk_json },
47
+ client_access_token: { name: :order_dispatch_client_access_token },
48
+ client_fhir_server: { name: :order_dispatch_client_fhir_server },
49
+ crd_jwks_json: { name: :order_dispatch_crd_jwks_json },
50
+ crd_jwks_keys_json: { name: :order_dispatch_crd_jwks_keys_json }
51
+ },
52
+ options: {
53
+ hook_name: 'order-dispatch',
54
+ hook_path: ORDER_DISPATCH_PATH
55
+ }
56
+ )
57
+
58
+ test from: :crd_submitted_response_validation
59
+ test from: :crd_order_dispatch_request
60
+ test from: :crd_decode_auth_token
61
+ test from: :crd_retrieve_jwks
62
+ test from: :crd_token_header
63
+ test from: :crd_token_payload
64
+ test from: :crd_hook_request_required_fields
65
+ test from: :crd_hook_request_optional_fields
66
+ test from: :crd_hook_request_valid_context
67
+ test from: :crd_hook_request_valid_prefetch
68
+ test from: :crd_card_display_attest_test
69
+ end
70
+ end
@@ -0,0 +1,72 @@
1
+ require_relative 'order_select_receive_request_test'
2
+ require_relative 'client_display_cards_attest'
3
+ require_relative 'decode_auth_token_test'
4
+ require_relative 'hook_request_optional_fields_test'
5
+ require_relative 'hook_request_required_fields_test'
6
+ require_relative 'hook_request_valid_context_test'
7
+ require_relative 'hook_request_valid_prefetch_test'
8
+ require_relative 'retrieve_jwks_test'
9
+ require_relative 'submitted_response_validation'
10
+ require_relative 'token_header_test'
11
+ require_relative 'token_payload_test'
12
+
13
+ module DaVinciCRDTestKit
14
+ class ClientOrderSelectGroup < Inferno::TestGroup
15
+ title 'order-select'
16
+ id :crd_client_order_select
17
+ description <<~DESCRIPTION
18
+ The order-select hook fires when a clinician selects one or more orders to place for a patient,
19
+ (including orders for medications, procedures, labs and other orders). If supported by the CDS Client, this
20
+ hook may also be invoked each time the clinician selects a detail regarding the order. These tests are based on
21
+ the following criteria:
22
+ * [CRD IG requirements for this hook](https://hl7.org/fhir/us/davinci-crd/STU2/hooks.html#order-selecte),
23
+ which includes the profiles that are expected to be used for the resources resolved to by `context`
24
+ FHIR ID fields
25
+ * Specific [order-select `context` requirements](https://cds-hooks.hl7.org/hooks/order-select/2023SepSTU1Ballot/order-select/)
26
+ defined in the CDS Hooks specification
27
+
28
+ This version of the CRD implementation guide refers to version 1.0 of the hook.
29
+ DESCRIPTION
30
+
31
+ run_as_group
32
+
33
+ config(
34
+ inputs: {
35
+ auth_token_headers_json: { name: :order_select_auth_token_headers_json },
36
+ auth_tokens: { name: :order_select_auth_tokens },
37
+ auth_tokens_jwk_json: { name: :order_select_auth_tokens_jwk_json },
38
+ client_access_token: { name: :order_select_client_access_token },
39
+ client_fhir_server: { name: :order_select_client_fhir_server },
40
+ crd_jwks_keys_json: { name: :order_select_crd_jwks_keys_json },
41
+ custom_response: { name: :order_select_custom_response },
42
+ selected_response_types: { name: :order_select_selected_response_types }
43
+ },
44
+ outputs: {
45
+ auth_token_headers_json: { name: :order_select_auth_token_headers_json },
46
+ auth_token_payloads_json: { name: :order_select_auth_token_payloads_json },
47
+ auth_tokens: { name: :order_select_auth_tokens },
48
+ auth_tokens_jwk_json: { name: :order_select_auth_tokens_jwk_json },
49
+ client_access_token: { name: :order_select_client_access_token },
50
+ client_fhir_server: { name: :order_select_client_fhir_server },
51
+ crd_jwks_json: { name: :order_select_crd_jwks_json },
52
+ crd_jwks_keys_json: { name: :order_select_crd_jwks_keys_json }
53
+ },
54
+ options: {
55
+ hook_name: 'order-select',
56
+ hook_path: ORDER_SELECT_PATH
57
+ }
58
+ )
59
+
60
+ test from: :crd_submitted_response_validation
61
+ test from: :crd_order_select_request
62
+ test from: :crd_decode_auth_token
63
+ test from: :crd_retrieve_jwks
64
+ test from: :crd_token_header
65
+ test from: :crd_token_payload
66
+ test from: :crd_hook_request_required_fields
67
+ test from: :crd_hook_request_optional_fields
68
+ test from: :crd_hook_request_valid_context
69
+ test from: :crd_hook_request_valid_prefetch
70
+ test from: :crd_card_display_attest_test
71
+ end
72
+ end
@@ -0,0 +1,71 @@
1
+ require_relative 'order_sign_receive_request_test'
2
+ require_relative 'client_display_cards_attest'
3
+ require_relative 'decode_auth_token_test'
4
+ require_relative 'hook_request_optional_fields_test'
5
+ require_relative 'hook_request_required_fields_test'
6
+ require_relative 'hook_request_valid_context_test'
7
+ require_relative 'hook_request_valid_prefetch_test'
8
+ require_relative 'retrieve_jwks_test'
9
+ require_relative 'submitted_response_validation'
10
+ require_relative 'token_header_test'
11
+ require_relative 'token_payload_test'
12
+
13
+ module DaVinciCRDTestKit
14
+ class ClientOrderSignGroup < Inferno::TestGroup
15
+ title 'order-sign'
16
+ id :crd_client_order_sign
17
+ description <<~DESCRIPTION
18
+ The order-sign hook fires when a clinician is ready to sign one or more orders for a patient, (including orders
19
+ for medications, procedures, labs and other orders). These tests are based on the following criteria:
20
+ * [CRD IG requirements for this hook](https://hl7.org/fhir/us/davinci-crd/STU2/hooks.html#order-sign),
21
+ which includes the profiles that are expected to be used for the resources resolved to by `context`
22
+ FHIR ID fields
23
+ * Specific [order-sign `context` requirements](https://cds-hooks.org/hooks/order-sign/)
24
+ defined in the CDS Hooks specification
25
+
26
+ This version of the CRD implementation guide refers to version 1.1 of the hook which, at the time of publication,
27
+ was not available as a snapshot. Therefore the preceding link refers to the CDS hooks current build.
28
+ DESCRIPTION
29
+
30
+ run_as_group
31
+
32
+ config(
33
+ inputs: {
34
+ auth_token_headers_json: { name: :order_sign_auth_token_headers_json },
35
+ auth_tokens: { name: :order_sign_auth_tokens },
36
+ auth_tokens_jwk_json: { name: :order_sign_auth_tokens_jwk_json },
37
+ client_access_token: { name: :order_sign_client_access_token },
38
+ client_fhir_server: { name: :order_sign_client_fhir_server },
39
+ crd_jwks_keys_json: { name: :order_sign_crd_jwks_keys_json },
40
+ custom_response: { name: :order_sign_custom_response },
41
+ selected_response_types: { name: :order_sign_selected_response_types }
42
+ },
43
+ outputs: {
44
+ auth_token_headers_json: { name: :order_sign_auth_token_headers_json },
45
+ auth_token_payloads_json: { name: :order_sign_auth_token_payloads_json },
46
+ auth_tokens: { name: :order_sign_auth_tokens },
47
+ auth_tokens_jwk_json: { name: :order_sign_auth_tokens_jwk_json },
48
+ client_access_token: { name: :order_sign_client_access_token },
49
+ client_fhir_server: { name: :order_sign_client_fhir_server },
50
+ crd_jwks_json: { name: :order_sign_crd_jwks_json },
51
+ crd_jwks_keys_json: { name: :order_sign_crd_jwks_keys_json }
52
+ },
53
+ options: {
54
+ hook_name: 'order-sign',
55
+ hook_path: ORDER_SIGN_PATH
56
+ }
57
+ )
58
+
59
+ test from: :crd_submitted_response_validation
60
+ test from: :crd_order_sign_request
61
+ test from: :crd_decode_auth_token
62
+ test from: :crd_retrieve_jwks
63
+ test from: :crd_token_header
64
+ test from: :crd_token_payload
65
+ test from: :crd_hook_request_required_fields
66
+ test from: :crd_hook_request_optional_fields
67
+ test from: :crd_hook_request_valid_context
68
+ test from: :crd_hook_request_valid_prefetch
69
+ test from: :crd_card_display_attest_test
70
+ end
71
+ end
@@ -1,5 +1,8 @@
1
+ require_relative '../client_hook_request_validation'
2
+
1
3
  module DaVinciCRDTestKit
2
4
  class DecodeAuthTokenTest < Inferno::Test
5
+ include ClientHookRequestValidation
3
6
  id :crd_decode_auth_token
4
7
  title 'Bearer token can be decoded'
5
8
  description %(
@@ -8,33 +11,50 @@ module DaVinciCRDTestKit
8
11
  include an Authorization header presenting the JWT as a "Bearer" token.
9
12
  )
10
13
 
11
- output :auth_token, :auth_token_payload_json, :auth_token_header_json
14
+ output :auth_tokens, :auth_token_payloads_json, :auth_token_headers_json
12
15
 
13
- uses_request :hook_request
16
+ def hook_name
17
+ config.options[:hook_name]
18
+ end
14
19
 
15
20
  run do
16
- authorization_header = request.request_header('Authorization')&.value
17
- skip_if authorization_header.blank?, 'Request does not include an Authorization header'
18
-
19
- assert(authorization_header.start_with?('Bearer '),
20
- 'Authorization token must be a JWT presented as a `Bearer` token')
21
-
22
- auth_token = authorization_header.delete_prefix('Bearer ')
23
- output(auth_token:)
24
-
25
- begin
26
- payload, header =
27
- JWT.decode(
28
- auth_token,
29
- nil,
30
- false
31
- )
32
-
33
- output auth_token_payload_json: payload.to_json,
34
- auth_token_header_json: header.to_json
35
- rescue StandardError => e
36
- assert false, "Token is not a properly constructed JWT: #{e.message}"
21
+ load_tagged_requests(hook_name)
22
+ skip_if requests.empty?, "No #{hook_name} requests were made in a previous test as expected."
23
+ auth_tokens = []
24
+ auth_token_payloads_json = []
25
+ auth_token_headers_json = []
26
+
27
+ requests.each_with_index do |request, index|
28
+ @request_number = index + 1
29
+
30
+ authorization_header = request.request_header('Authorization')&.value
31
+
32
+ unless authorization_header.start_with?('Bearer ')
33
+ add_message('error', "#{request_number}Authorization token must be a JWT presented as a `Bearer` token")
34
+ end
35
+
36
+ auth_token = authorization_header.delete_prefix('Bearer ')
37
+ auth_tokens << auth_token
38
+
39
+ begin
40
+ payload, header =
41
+ JWT.decode(
42
+ auth_token,
43
+ nil,
44
+ false
45
+ )
46
+
47
+ auth_token_payloads_json << payload.to_json
48
+ auth_token_headers_json << header.to_json
49
+ rescue StandardError => e
50
+ add_message('error', "#{request_number}Token is not a properly constructed JWT: #{e.message}")
51
+ end
37
52
  end
53
+ output auth_tokens: auth_tokens.to_json,
54
+ auth_token_payloads_json: auth_token_payloads_json.to_json,
55
+ auth_token_headers_json: auth_token_headers_json.to_json
56
+
57
+ no_error_validation('Decoding Authorization header Bearer tokens failed.')
38
58
  end
39
59
  end
40
60
  end
@@ -7,10 +7,11 @@ module DaVinciCRDTestKit
7
7
  id :crd_encounter_discharge_request
8
8
  title 'Request received for encounter-discharge hook'
9
9
  description %(
10
- This test waits for an incoming [encounter-discharge](https://hl7.org/fhir/us/davinci-crd/STU2/hooks.html#encounter-discharge)
11
- hook request and responds to the client with the response types selected as an input.
10
+ This test waits for multiple incoming [encounter-discharge](https://hl7.org/fhir/us/davinci-crd/STU2/hooks.html#encounter-discharge)
11
+ hook requests and responds to the client with the response types selected as an input.
12
12
  )
13
- receives_request :encounter_discharge
13
+
14
+ config options: { accepts_multiple_requests: true }
14
15
 
15
16
  input :iss
16
17
  input :encounter_discharge_selected_response_types,
@@ -20,7 +21,8 @@ module DaVinciCRDTestKit
20
21
  response type that will be returned for this hook is the `Instructions` card type.
21
22
  ),
22
23
  type: 'checkbox',
23
- default: ['instructions'],
24
+ default: ['coverage_information', 'external_reference', 'instructions'],
25
+ optional: true,
24
26
  options: {
25
27
  list_options: [
26
28
  {
@@ -49,6 +51,14 @@ module DaVinciCRDTestKit
49
51
  }
50
52
  ]
51
53
  }
54
+ input :encounter_discharge_custom_response,
55
+ title: 'Custom response for encounter-discharge hook requests',
56
+ description: %(
57
+ A JSON string may be provided here to replace the normal response
58
+ from the hook request endpoint
59
+ ),
60
+ type: 'textarea',
61
+ optional: true
52
62
 
53
63
  run do
54
64
  wait(
@@ -56,11 +66,14 @@ module DaVinciCRDTestKit
56
66
  message: %(
57
67
  **Encounter Discharge CDS Service Test**:
58
68
 
59
- Invoke the encounter-discharge hook and send a request to:
69
+ Invoke the encounter-discharge hook and send requests to:
60
70
 
61
71
  `#{encounter_discharge_url}`
62
72
 
63
- Inferno will process the request and return CDS cards if successful.
73
+ Inferno will process the requests and return CDS cards if successful.
74
+
75
+ [Click here](#{resume_pass_url}?token=encounter-discharge%20#{iss}) when you have finished submitting
76
+ requests.
64
77
  )
65
78
  )
66
79
  end