subscriptions_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.
- checksums.yaml +7 -0
- data/LICENSE +201 -0
- data/lib/inferno_requirements_tools/ext/inferno_core/runnable.rb +22 -0
- data/lib/inferno_requirements_tools/tasks/collect_requirements.rb +222 -0
- data/lib/inferno_requirements_tools/tasks/requirements_coverage.rb +264 -0
- data/lib/subscriptions_test_kit/common/notification_conformance_verification.rb +310 -0
- data/lib/subscriptions_test_kit/common/subscription_conformance_verification.rb +87 -0
- data/lib/subscriptions_test_kit/docs/samples/Subscription_empty.json +37 -0
- data/lib/subscriptions_test_kit/docs/samples/Subscription_full-resource.json +37 -0
- data/lib/subscriptions_test_kit/docs/samples/Subscription_id-only.json +38 -0
- data/lib/subscriptions_test_kit/docs/subscriptions_r5_backport_r4_client_suite_description.md +120 -0
- data/lib/subscriptions_test_kit/docs/subscriptions_r5_backport_r4_server_suite_description.md +170 -0
- data/lib/subscriptions_test_kit/endpoints/subscription_create_endpoint.rb +90 -0
- data/lib/subscriptions_test_kit/endpoints/subscription_read_endpoint.rb +32 -0
- data/lib/subscriptions_test_kit/endpoints/subscription_rest_hook_endpoint.rb +66 -0
- data/lib/subscriptions_test_kit/endpoints/subscription_status_endpoint.rb +70 -0
- data/lib/subscriptions_test_kit/igs/README.md +21 -0
- data/lib/subscriptions_test_kit/jobs/send_subscription_notifications.rb +130 -0
- data/lib/subscriptions_test_kit/requirements/generated/subscriptions-test-kit_requirements_coverage.csv +136 -0
- data/lib/subscriptions_test_kit/requirements/subscriptions-test-kit_out_of_scope_requirements.csv +23 -0
- data/lib/subscriptions_test_kit/requirements/subscriptions-test-kit_requirements.csv +145 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/common/subscription_simulation_utils.rb +140 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/fixtures/capability_statement.json +57 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/workflow/conformance_verification/notification_input_payload_verification_test.rb +50 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/workflow/conformance_verification/notification_input_verification_test.rb +25 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/workflow/conformance_verification/processing_attestation_test.rb +38 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/workflow/conformance_verification/subscription_verification_test.rb +28 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/workflow/conformance_verification_group.rb +20 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/workflow/interaction_test.rb +128 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/workflow/interaction_verification/event_notification_verification_test.rb +40 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/workflow/interaction_verification/handshake_notification_verification_test.rb +40 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/workflow/interaction_verification_group.rb +16 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client/workflow_group.rb +33 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_client_suite.rb +66 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/common/interaction/creation_response_conformance_test.rb +51 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/common/interaction/notification_delivery_test.rb +56 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/common/interaction/subscription_conformance_test.rb +72 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/common/interaction_group.rb +24 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/common/interaction_verification/notification_conformance_test.rb +73 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/common/interaction_verification_group.rb +19 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/common/subscription_creation.rb +63 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/common/subscription_status_operation.rb +58 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/capability_statement/cs_conformance_test.rb +49 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/capability_statement/topic_discovery_test.rb +106 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/capability_statement_group.rb +21 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/event_notification/empty_content/empty_conformance_test.rb +63 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/event_notification/empty_content_group.rb +58 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/event_notification/full_resource_content/full_resource_conformance_test.rb +68 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/event_notification/full_resource_content_group.rb +58 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/event_notification/id_only_content/id_only_conformance_test.rb +66 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/event_notification/id_only_content_group.rb +58 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/event_notification_group.rb +25 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/handshake_heartbeat/handshake_conformance_test.rb +67 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/handshake_heartbeat/heartbeat_conformance_test.rb +74 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/handshake_heartbeat_group.rb +19 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/status_operation/status_invocation_test.rb +43 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/status_operation_group.rb +15 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/subscription_rejection/reject_subscriptions_test.rb +181 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage/subscription_rejection_group.rb +21 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/coverage_group.rb +26 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server/workflow_group.rb +27 -0
- data/lib/subscriptions_test_kit/suites/subscriptions_r5_backport_r4_server_suite.rb +79 -0
- data/lib/subscriptions_test_kit/tags.rb +10 -0
- data/lib/subscriptions_test_kit/urls.rb +37 -0
- data/lib/subscriptions_test_kit/version.rb +5 -0
- data/lib/subscriptions_test_kit.rb +3 -0
- metadata +194 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module SubscriptionsTestKit
|
|
2
|
+
module SubscriptionsR5BackportR4Server
|
|
3
|
+
module SubscriptionCreation
|
|
4
|
+
def no_error_verification(message)
|
|
5
|
+
assert messages.none? { |msg| msg[:type] == 'error' }, message
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def json_parse(json)
|
|
9
|
+
JSON.parse(json)
|
|
10
|
+
rescue JSON::ParserError
|
|
11
|
+
add_message('error', "#{request_number}Invalid JSON.")
|
|
12
|
+
false
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def get_new_subscription_value(subscription, field_path)
|
|
16
|
+
field_path.reduce(subscription) { |obj, path| obj[path] }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def send_unsupported_subscription(subscription, unsupported_type, field_paths, subscription_field_old_values)
|
|
20
|
+
fhir_operation('/Subscription', body: subscription)
|
|
21
|
+
|
|
22
|
+
return if request.status != 201
|
|
23
|
+
|
|
24
|
+
new_subscription = json_parse(request.response_body)
|
|
25
|
+
return unless new_subscription
|
|
26
|
+
|
|
27
|
+
altered_field = false
|
|
28
|
+
field_paths.each_with_index do |field_path, index|
|
|
29
|
+
subscription_field_new_value = get_new_subscription_value(new_subscription, field_path)
|
|
30
|
+
if subscription_field_new_value != subscription_field_old_values[index]
|
|
31
|
+
altered_field = true
|
|
32
|
+
break
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
return if altered_field
|
|
37
|
+
|
|
38
|
+
add_message('error', %(
|
|
39
|
+
Sending a Subscription with #{unsupported_type} should be rejected, or the Subscription should be
|
|
40
|
+
altered to fix the unsupported value.))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def subscription_payload_type(subscription)
|
|
44
|
+
return unless subscription['channel']['_payload']
|
|
45
|
+
|
|
46
|
+
payload_extension = subscription['channel']['_payload']['extension'].find do |ext|
|
|
47
|
+
ext['url'].ends_with?('/backport-payload-content')
|
|
48
|
+
end
|
|
49
|
+
payload_extension['valueCode']
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def send_subscription(subscription)
|
|
53
|
+
tags = ['subscription_creation']
|
|
54
|
+
payload_type = subscription_payload_type(subscription)
|
|
55
|
+
tags.append(payload_type) if payload_type.present?
|
|
56
|
+
|
|
57
|
+
fhir_operation('/Subscription', body: subscription, tags:)
|
|
58
|
+
assert_response_status(201)
|
|
59
|
+
payload_type
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module SubscriptionsTestKit
|
|
2
|
+
module SubscriptionsR5BackportR4Server
|
|
3
|
+
module SubscriptionStatusOperation
|
|
4
|
+
def no_error_verification(message)
|
|
5
|
+
assert messages.none? { |msg| msg[:type] == 'error' }, message
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def find_elem(resource_array, param_name)
|
|
9
|
+
resource_array.find do |param|
|
|
10
|
+
param.name == param_name
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def execute_subscription_status_operation(subscription_id)
|
|
15
|
+
fhir_operation("Subscription/#{subscription_id}/$status", operation_method: :get)
|
|
16
|
+
assert_response_status(200)
|
|
17
|
+
assert_resource_type('Bundle')
|
|
18
|
+
|
|
19
|
+
unless resource.type == 'searchset'
|
|
20
|
+
add_message('error', "Bundle returned from $status operation should be type 'searchset', was #{resource.type}")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
assert_valid_resource
|
|
24
|
+
|
|
25
|
+
resource.entry
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def subscription_ref_found?(entry, subscription_id)
|
|
29
|
+
subscription_param = find_elem(entry.resource.parameter, 'subscription')
|
|
30
|
+
subscription_ref = subscription_param.valueReference.reference
|
|
31
|
+
return false if subscription_ref.blank?
|
|
32
|
+
|
|
33
|
+
subscription_ref.split('/').last == subscription_id
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def perform_subscription_status_test(subscription_id, status = nil)
|
|
37
|
+
bundle_entries = execute_subscription_status_operation(subscription_id)
|
|
38
|
+
subscription_status_entry = bundle_entries.find do |entry|
|
|
39
|
+
entry.resource.resourceType == 'Parameters' && subscription_ref_found?(entry, subscription_id)
|
|
40
|
+
end
|
|
41
|
+
assert(subscription_status_entry,
|
|
42
|
+
"No Subscription status with id #{subscription_id} returned from $status operation")
|
|
43
|
+
|
|
44
|
+
subscription_status_resource = subscription_status_entry.resource
|
|
45
|
+
assert_valid_resource(resource: subscription_status_resource,
|
|
46
|
+
profile_url: 'http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-subscription-status-r4')
|
|
47
|
+
|
|
48
|
+
subscription_status = find_elem(subscription_status_resource.parameter, 'status')
|
|
49
|
+
|
|
50
|
+
return unless status.present?
|
|
51
|
+
|
|
52
|
+
assert(subscription_status.valueCode == status, %(
|
|
53
|
+
The Subscription resource should have it's `status` set to #{status}, was
|
|
54
|
+
`#{subscription_status.valueCode}`))
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module SubscriptionsTestKit
|
|
2
|
+
module SubscriptionsR5BackportR4Server
|
|
3
|
+
class CSConformanceTest < Inferno::Test
|
|
4
|
+
id :subscriptions_r5_backport_r4_server_cs_conformance
|
|
5
|
+
title 'Capability Statement Conformance Verification'
|
|
6
|
+
description %(
|
|
7
|
+
This test attempts to retreive the server's Capability Statement in order to verify that it
|
|
8
|
+
declares support for the Backport Subscription Profile by including its official URL in the server's
|
|
9
|
+
CapabilityStatement.rest.resource.supportedProfile element: http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-subscription
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
verifies_requirements 'hl7.fhir.uv.subscriptions_1.1.0@52',
|
|
13
|
+
'hl7.fhir.uv.subscriptions_1.1.0@114',
|
|
14
|
+
'hl7.fhir.uv.subscriptions_1.1.0@120'
|
|
15
|
+
|
|
16
|
+
def subscription_profile_url
|
|
17
|
+
'http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-subscription'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
run do
|
|
21
|
+
fhir_get_capability_statement
|
|
22
|
+
assert_response_status(200)
|
|
23
|
+
assert_resource_type(:capability_statement)
|
|
24
|
+
assert_valid_resource
|
|
25
|
+
|
|
26
|
+
scratch[:capability_statement] ||= resource
|
|
27
|
+
|
|
28
|
+
assert(resource.rest.present?, 'Capability Statement missing the `rest` field')
|
|
29
|
+
rest_server = resource.rest.find { |elem| elem.mode == 'server' }
|
|
30
|
+
assert(rest_server.present?, "Capability Statement missing entry in `rest` with a `mode` set to 'server'")
|
|
31
|
+
|
|
32
|
+
rest_subscription = rest_server.resource.find { |elem| elem.type == 'Subscription' }
|
|
33
|
+
assert(rest_subscription.present?, 'Capability Statement missing `Subscription` resource in `rest` field')
|
|
34
|
+
|
|
35
|
+
assert(rest_subscription.supportedProfile.present?,
|
|
36
|
+
'Capability Statement missing the `supportedProfile` field in `Subscription` resource')
|
|
37
|
+
|
|
38
|
+
subscription_profile_present = rest_subscription.supportedProfile.any? do |profile|
|
|
39
|
+
profile == subscription_profile_url
|
|
40
|
+
end
|
|
41
|
+
unless subscription_profile_present
|
|
42
|
+
add_message('warning', %(
|
|
43
|
+
Subscription resource should declare support for the Backport Subscription Profile by including its
|
|
44
|
+
official URL))
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
require_relative '../../../../common/subscription_conformance_verification'
|
|
2
|
+
|
|
3
|
+
module SubscriptionsTestKit
|
|
4
|
+
module SubscriptionsR5BackportR4Server
|
|
5
|
+
class TopicDiscoveryTest < Inferno::Test
|
|
6
|
+
include SubscriptionConformanceVerification
|
|
7
|
+
|
|
8
|
+
id :subscriptions_r5_backport_r4_server_topic_discovery
|
|
9
|
+
title 'Attempt topic discovery'
|
|
10
|
+
description %(
|
|
11
|
+
This test attempts to perform topic discovery with the server. In order to allow for [discovery of supported
|
|
12
|
+
subscription topics in R4](https://hl7.org/fhir/uv/subscriptions-backport/STU1.1/components.html#subscription-topics-in-r4),
|
|
13
|
+
the Subscriptions Backport IG defines the CapabilityStatement [SubscriptionTopic Canonical extension](https://hl7.org/fhir/uv/subscriptions-backport/STU1.1/StructureDefinition-capabilitystatement-subscriptiontopic-canonical.html).
|
|
14
|
+
The extension allows server implementers to advertise the canonical URLs of topics available to clients and
|
|
15
|
+
allows clients to see the list of supported topics on a server.
|
|
16
|
+
|
|
17
|
+
The extension is expected to appear, if supported, on the Subscription resource entry. Note that servers are NOT
|
|
18
|
+
required to advertise supported topics via this extension, so this test it optional. Supported topics can also
|
|
19
|
+
be advertised, for example, by the CapabilityStatement.instantiates or CapabilityStatement.implementationGuide
|
|
20
|
+
elements of a CapabilityStatement, as defined by another Implementation Guide. Finally, FHIR R4 servers MAY
|
|
21
|
+
choose to leave topic discovery completely out-of-band and part of other steps, such as registration or
|
|
22
|
+
integration.
|
|
23
|
+
|
|
24
|
+
In order to claim conformance with this IG for R4, a server SHOULD support topic discovery
|
|
25
|
+
via the CapabilityStatement SubscriptionTopic Canonical extension.
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
verifies_requirements 'hl7.fhir.uv.subscriptions_1.1.0@2',
|
|
29
|
+
'hl7.fhir.uv.subscriptions_1.1.0@48'
|
|
30
|
+
|
|
31
|
+
optional
|
|
32
|
+
|
|
33
|
+
def backport_subscription_server_url
|
|
34
|
+
'http://hl7.org/fhir/uv/subscriptions-backport/CapabilityStatement/backport-subscription-server-r4'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def subscription_profile_url
|
|
38
|
+
'http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-subscription'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def capability_statement_subscriptiontopic_extension
|
|
42
|
+
'http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/capabilitystatement-subscriptiontopic-canonical'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def scratch_resource
|
|
46
|
+
scratch[:capability_statement] ||= {}
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
run do
|
|
50
|
+
resource = scratch_resource
|
|
51
|
+
|
|
52
|
+
skip_if resource.blank?, 'No Capability Statement received in previous test'
|
|
53
|
+
|
|
54
|
+
assert(resource.rest.present?, 'Capability Statement missing the `rest` field')
|
|
55
|
+
rest_server = resource.rest.find { |elem| elem.mode == 'server' }
|
|
56
|
+
assert(rest_server.present?, "Capability Statement missing entry in `rest` with a `mode` set to 'server'")
|
|
57
|
+
|
|
58
|
+
rest_subscription = rest_server.resource.find { |elem| elem.type == 'Subscription' }
|
|
59
|
+
assert(rest_subscription.present?, 'Capability Statement missing `Subscription` resource in `rest` field')
|
|
60
|
+
|
|
61
|
+
assert(rest_subscription.extension.present?,
|
|
62
|
+
'Capability Statement missing the `extension` field on the Subscription resource')
|
|
63
|
+
subscription_topic_extension = rest_subscription.extension.select do |elem|
|
|
64
|
+
elem.url == capability_statement_subscriptiontopic_extension
|
|
65
|
+
end
|
|
66
|
+
assert(subscription_topic_extension.any?, %(
|
|
67
|
+
The server SHOULD support topic discovery via the CapabilityStatement SubscriptionTopic Canonical
|
|
68
|
+
extension))
|
|
69
|
+
|
|
70
|
+
subscription_requests = load_tagged_requests('subscription_creation')
|
|
71
|
+
|
|
72
|
+
if subscription_requests.any?
|
|
73
|
+
subscription_topics =
|
|
74
|
+
subscription_requests
|
|
75
|
+
.select { |request| request.status == 201 }
|
|
76
|
+
.uniq(&:response_body)
|
|
77
|
+
.map { |request| JSON.parse(request.response_body) }
|
|
78
|
+
.map { |subscription| subscription['criteria'] }
|
|
79
|
+
.uniq
|
|
80
|
+
|
|
81
|
+
if subscription_topics.any?
|
|
82
|
+
subscription_topics.each do |subscription_topic|
|
|
83
|
+
next if subscription_topic_extension.any? { |elem| elem.valueCanonical == subscription_topic }
|
|
84
|
+
|
|
85
|
+
add_message('error', %(
|
|
86
|
+
The SubscriptionTopic Canonical extension should include the Subscription Topic URLs found in
|
|
87
|
+
Subscription.criteria: #{subscription_topic}))
|
|
88
|
+
end
|
|
89
|
+
else
|
|
90
|
+
add_message('warning', %(
|
|
91
|
+
Subscriptions missing criteria field containing a Subscription topic URL. Could not verify any
|
|
92
|
+
topics found in the SubscriptionTopic Canonical extension))
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
no_error_verification(
|
|
96
|
+
"Subscription.criteria value(s) not found in Capability Statement's SubscriptionTopic Canonical extension"
|
|
97
|
+
)
|
|
98
|
+
else
|
|
99
|
+
add_message('warning', %(
|
|
100
|
+
No Subscription requests have been made in previous tests. Run the Subscription workflow tests first in order
|
|
101
|
+
to verify topics found in the SubscriptionTopic Canonical extension))
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require_relative 'capability_statement/cs_conformance_test'
|
|
2
|
+
require_relative 'capability_statement/topic_discovery_test'
|
|
3
|
+
|
|
4
|
+
module SubscriptionsTestKit
|
|
5
|
+
module SubscriptionsR5BackportR4Server
|
|
6
|
+
class CapabilityStatementGroup < Inferno::TestGroup
|
|
7
|
+
id :subscriptions_r5_backport_r4_server_capability_statement
|
|
8
|
+
title 'Capability Statement Verification'
|
|
9
|
+
description %(
|
|
10
|
+
Verify the Backport Subscriptions Server has a conformant Capability Statement and that it declares support for the
|
|
11
|
+
Backport Subscription Profile on the Subscription resource in the rest field. Then the group will verify if the
|
|
12
|
+
server supports topic discovert via the Capability Statement, which is an optional requirement.
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
run_as_group
|
|
16
|
+
|
|
17
|
+
test from: :subscriptions_r5_backport_r4_server_cs_conformance
|
|
18
|
+
test from: :subscriptions_r5_backport_r4_server_topic_discovery
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require_relative '../../../../../common/notification_conformance_verification'
|
|
2
|
+
|
|
3
|
+
module SubscriptionsTestKit
|
|
4
|
+
module SubscriptionsR5BackportR4Server
|
|
5
|
+
class EmptyConformanceTest < Inferno::Test
|
|
6
|
+
include NotificationConformanceVerification
|
|
7
|
+
|
|
8
|
+
id :subscriptions_r5_backport_r4_server_empty_conformance
|
|
9
|
+
title 'Subscription Empty Notification Verification'
|
|
10
|
+
description %(
|
|
11
|
+
This test takes the received empty notification bundle and ensures it is conformant to the
|
|
12
|
+
[R4 Topic-Based Subscription Notification Bundle](https://hl7.org/fhir/uv/subscriptions-backport/STU1.1/StructureDefinition-backport-subscription-notification-r4.html)
|
|
13
|
+
profle and to the requirements listed for empty notifications.
|
|
14
|
+
|
|
15
|
+
With the content type of empty, no information about the resources involved in triggering the notification is
|
|
16
|
+
available via the subscription channel. When populating the SubscriptionStatus.notificationEvent structure for a
|
|
17
|
+
notification with an empty payload, a server SHALL NOT include references to resources
|
|
18
|
+
(e.g., SubscriptionStatus.notificationEvent.focus and SubscriptionStatus.notificationEvent.additionalContext
|
|
19
|
+
SHALL NOT be present).
|
|
20
|
+
|
|
21
|
+
When the content type is empty, notification bundles SHALL not contain Bundle.entry
|
|
22
|
+
elements other than the SubscriptionStatus for the notification.
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
verifies_requirements 'hl7.fhir.uv.subscriptions_1.1.0@14',
|
|
26
|
+
'hl7.fhir.uv.subscriptions_1.1.0@15',
|
|
27
|
+
'hl7.fhir.uv.subscriptions_1.1.0@28',
|
|
28
|
+
'hl7.fhir.uv.subscriptions_1.1.0@69',
|
|
29
|
+
'hl7.fhir.uv.subscriptions_1.1.0@70',
|
|
30
|
+
'hl7.fhir.uv.subscriptions_1.1.0@38',
|
|
31
|
+
'hl7.fhir.uv.subscriptions_1.1.0@39',
|
|
32
|
+
'hl7.fhir.uv.subscriptions_1.1.0@35',
|
|
33
|
+
'hl7.fhir.uv.subscriptions_1.1.0@67',
|
|
34
|
+
'hl7.fhir.uv.subscriptions_1.1.0@51',
|
|
35
|
+
'hl7.fhir.uv.subscriptions_1.1.0@53',
|
|
36
|
+
'hl7.fhir.uv.subscriptions_1.1.0@65',
|
|
37
|
+
'hl7.fhir.uv.subscriptions_1.1.0@99',
|
|
38
|
+
'hl7.fhir.uv.subscriptions_1.1.0@138',
|
|
39
|
+
'hl7.fhir.uv.subscriptions_1.1.0@139'
|
|
40
|
+
|
|
41
|
+
run do
|
|
42
|
+
subscription_requests = load_tagged_requests('subscription_creation', 'empty')
|
|
43
|
+
omit_if subscription_requests.empty?, 'No Subscriptions sent with notification payload type of `empty`'
|
|
44
|
+
|
|
45
|
+
subscription_requests.each do |subscription_request|
|
|
46
|
+
assert_valid_json(subscription_request.response_body)
|
|
47
|
+
subscription = JSON.parse(subscription_request.response_body)
|
|
48
|
+
|
|
49
|
+
requests = load_tagged_requests('event-notification', subscription['id'])
|
|
50
|
+
skip_if requests.empty?, 'No event-notification requests were made in a previous test as expected.'
|
|
51
|
+
|
|
52
|
+
requests = requests.uniq(&:request_body)
|
|
53
|
+
|
|
54
|
+
requests.each do |request|
|
|
55
|
+
empty_event_notification_verification(request.request_body)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
no_error_verification('Received empty notification-events are not conformant.')
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require_relative '../../common/interaction_group'
|
|
2
|
+
require_relative '../../common/interaction_verification_group'
|
|
3
|
+
require_relative 'empty_content/empty_conformance_test'
|
|
4
|
+
|
|
5
|
+
module SubscriptionsTestKit
|
|
6
|
+
module SubscriptionsR5BackportR4Server
|
|
7
|
+
class EmptyContentGroup < Inferno::TestGroup
|
|
8
|
+
id :subscriptions_r5_backport_r4_server_empty_content
|
|
9
|
+
title 'Empty Notification Verification'
|
|
10
|
+
description %(
|
|
11
|
+
Verify that the received Notifications are conformant to the
|
|
12
|
+
[R4 Topic-Based Subscription Notification Bundle](https://hl7.org/fhir/uv/subscriptions-backport/STU1.1/StructureDefinition-backport-subscription-notification-r4.html)
|
|
13
|
+
profile, including additional requirements around the `empty` content type ([example empty
|
|
14
|
+
Subscription](https://github.com/inferno-framework/subscriptions-test-kit/blob/main/lib/subscriptions_test_kit/docs/samples/Subscription_empty.json)).
|
|
15
|
+
)
|
|
16
|
+
run_as_group
|
|
17
|
+
optional
|
|
18
|
+
|
|
19
|
+
input_order :url, :credentials, :access_token, :empty_subscription_resource
|
|
20
|
+
|
|
21
|
+
group from: :subscriptions_r5_backport_r4_server_interaction do
|
|
22
|
+
id :subscriptions_r5_backport_r4_server_empty_content_interaction
|
|
23
|
+
optional
|
|
24
|
+
|
|
25
|
+
config(
|
|
26
|
+
options: { subscription_type: 'empty' },
|
|
27
|
+
inputs: {
|
|
28
|
+
subscription_resource: {
|
|
29
|
+
name: :empty_subscription_resource,
|
|
30
|
+
title: 'Empty Notification Subscription Resource',
|
|
31
|
+
type: 'textarea',
|
|
32
|
+
description: %(
|
|
33
|
+
A Subscription resource in JSON format that Inferno will send to the server under test
|
|
34
|
+
so that it can demonstrate its ability to send an empty Notification.
|
|
35
|
+
The instance must be conformant to the R4/B Topic-Based Subscription profile.
|
|
36
|
+
Inferno may modify the Subscription before submission, e.g., to point to Inferno's notification endpoint.
|
|
37
|
+
),
|
|
38
|
+
optional: true
|
|
39
|
+
},
|
|
40
|
+
updated_subscription: { name: :empty_updated_subscription }
|
|
41
|
+
},
|
|
42
|
+
outputs: {
|
|
43
|
+
updated_subscription: { name: :empty_updated_subscription }
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
end
|
|
47
|
+
group from: :subscriptions_r5_backport_r4_server_interaction_verification do
|
|
48
|
+
id :subscriptions_r5_backport_r4_server_empty_content_interaction_verification
|
|
49
|
+
optional
|
|
50
|
+
|
|
51
|
+
config(
|
|
52
|
+
options: { subscription_type: 'empty' }
|
|
53
|
+
)
|
|
54
|
+
test from: :subscriptions_r5_backport_r4_server_empty_conformance
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require_relative '../../../../../common/notification_conformance_verification'
|
|
2
|
+
|
|
3
|
+
module SubscriptionsTestKit
|
|
4
|
+
module SubscriptionsR5BackportR4Server
|
|
5
|
+
class FullResourceConformanceTest < Inferno::Test
|
|
6
|
+
include NotificationConformanceVerification
|
|
7
|
+
|
|
8
|
+
id :subscriptions_r5_backport_r4_server_full_resource_conformance
|
|
9
|
+
title 'Subscription Full-Resource Notification Verification'
|
|
10
|
+
description %(
|
|
11
|
+
This test takes the received notification bundle and ensures it is conformant to the
|
|
12
|
+
[R4 Topic-Based Subscription Notification Bundle](https://hl7.org/fhir/uv/subscriptions-backport/STU1.1/StructureDefinition-backport-subscription-notification-r4.html)
|
|
13
|
+
profle.
|
|
14
|
+
|
|
15
|
+
With the content type of full-resource, the resources involved in triggering the notification are included in the
|
|
16
|
+
notification bundle.
|
|
17
|
+
|
|
18
|
+
When the content type is full-resource, notification bundles SHALL include references to the
|
|
19
|
+
appropriate focus resources in the SubscriptionStatus.notificationEvent.focus element.
|
|
20
|
+
|
|
21
|
+
Notification bundles for full-resource subscriptions SHALL contain, in addition to the SubscriptionStatus, at
|
|
22
|
+
least one Bundle.entry for each resource relevant to the notification.
|
|
23
|
+
|
|
24
|
+
Each Bundle.entry for a full-resource notification SHALL contain a relevant resource in the
|
|
25
|
+
entry.resource element. If a server cannot include the resource contents due to an issue with a specific
|
|
26
|
+
notification, the server SHALL populate the entry.request and/or entry.response elements.
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
verifies_requirements 'hl7.fhir.uv.subscriptions_1.1.0@14',
|
|
30
|
+
'hl7.fhir.uv.subscriptions_1.1.0@15',
|
|
31
|
+
'hl7.fhir.uv.subscriptions_1.1.0@28',
|
|
32
|
+
'hl7.fhir.uv.subscriptions_1.1.0@69',
|
|
33
|
+
'hl7.fhir.uv.subscriptions_1.1.0@70',
|
|
34
|
+
'hl7.fhir.uv.subscriptions_1.1.0@43',
|
|
35
|
+
'hl7.fhir.uv.subscriptions_1.1.0@44',
|
|
36
|
+
'hl7.fhir.uv.subscriptions_1.1.0@45',
|
|
37
|
+
'hl7.fhir.uv.subscriptions_1.1.0@35',
|
|
38
|
+
'hl7.fhir.uv.subscriptions_1.1.0@67',
|
|
39
|
+
'hl7.fhir.uv.subscriptions_1.1.0@51',
|
|
40
|
+
'hl7.fhir.uv.subscriptions_1.1.0@53',
|
|
41
|
+
'hl7.fhir.uv.subscriptions_1.1.0@65',
|
|
42
|
+
'hl7.fhir.uv.subscriptions_1.1.0@101',
|
|
43
|
+
'hl7.fhir.uv.subscriptions_1.1.0@138',
|
|
44
|
+
'hl7.fhir.uv.subscriptions_1.1.0@139'
|
|
45
|
+
|
|
46
|
+
run do
|
|
47
|
+
subscription_requests = load_tagged_requests('subscription_creation', 'full-resource')
|
|
48
|
+
omit_if subscription_requests.empty?, 'No Subscriptions sent with notification payload type of `full-resource`'
|
|
49
|
+
|
|
50
|
+
subscription_requests.each do |subscription_request|
|
|
51
|
+
assert_valid_json(subscription_request.response_body)
|
|
52
|
+
subscription = JSON.parse(subscription_request.response_body)
|
|
53
|
+
|
|
54
|
+
requests = load_tagged_requests('event-notification', subscription['id'])
|
|
55
|
+
skip_if requests.empty?, 'No event-notification requests were made in a previous test as expected.'
|
|
56
|
+
|
|
57
|
+
criteria_resource_type = subscription_criteria(subscription)
|
|
58
|
+
requests = requests.uniq(&:request_body)
|
|
59
|
+
|
|
60
|
+
requests.each do |request|
|
|
61
|
+
full_resource_event_notification_verification(request.request_body, criteria_resource_type)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
no_error_verification('Received notification-events are not conformant.')
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require_relative '../../common/interaction_group'
|
|
2
|
+
require_relative '../../common/interaction_verification_group'
|
|
3
|
+
require_relative 'full_resource_content/full_resource_conformance_test'
|
|
4
|
+
|
|
5
|
+
module SubscriptionsTestKit
|
|
6
|
+
module SubscriptionsR5BackportR4Server
|
|
7
|
+
class FullResourceContentGroup < Inferno::TestGroup
|
|
8
|
+
id :subscriptions_r5_backport_r4_server_full_resource_content
|
|
9
|
+
title 'Full Resource Notification Verification'
|
|
10
|
+
description %(
|
|
11
|
+
Verify that the received Notifications are conformant to the
|
|
12
|
+
[R4 Topic-Based Subscription Notification Bundle](https://hl7.org/fhir/uv/subscriptions-backport/STU1.1/StructureDefinition-backport-subscription-notification-r4.html)
|
|
13
|
+
profile, including additional requirements around the `full-resource` content type ([example full-resource
|
|
14
|
+
Subscription](https://github.com/inferno-framework/subscriptions-test-kit/blob/main/lib/subscriptions_test_kit/docs/samples/Subscription_full-resource.json)).
|
|
15
|
+
)
|
|
16
|
+
run_as_group
|
|
17
|
+
optional
|
|
18
|
+
|
|
19
|
+
input_order :url, :credentials, :access_token, :full_resource_subscription_resource
|
|
20
|
+
|
|
21
|
+
group from: :subscriptions_r5_backport_r4_server_interaction do
|
|
22
|
+
id :subscriptions_r5_backport_r4_server_full_resource_content_interaction
|
|
23
|
+
optional
|
|
24
|
+
|
|
25
|
+
config(
|
|
26
|
+
options: { subscription_type: 'full-resource' },
|
|
27
|
+
inputs: {
|
|
28
|
+
subscription_resource: {
|
|
29
|
+
name: :full_resource_subscription_resource,
|
|
30
|
+
title: 'Full-Resource Notification Subscription Resource',
|
|
31
|
+
type: 'textarea',
|
|
32
|
+
description: %(
|
|
33
|
+
A Subscription resource in JSON format that Inferno will send to the server under test
|
|
34
|
+
so that it can demonstrate its ability to send a full-resource Notification.
|
|
35
|
+
The instance must be conformant to the R4/B Topic-Based Subscription profile.
|
|
36
|
+
Inferno may modify the Subscription before submission, e.g., to point to Inferno's notification endpoint.
|
|
37
|
+
),
|
|
38
|
+
optional: true
|
|
39
|
+
},
|
|
40
|
+
updated_subscription: { name: :full_resource_updated_subscription }
|
|
41
|
+
},
|
|
42
|
+
outputs: {
|
|
43
|
+
updated_subscription: { name: :full_resource_updated_subscription }
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
end
|
|
47
|
+
group from: :subscriptions_r5_backport_r4_server_interaction_verification do
|
|
48
|
+
id :subscriptions_r5_backport_r4_server_full_resource_content_interaction_verification
|
|
49
|
+
optional
|
|
50
|
+
|
|
51
|
+
config(
|
|
52
|
+
options: { subscription_type: 'full-resource' }
|
|
53
|
+
)
|
|
54
|
+
test from: :subscriptions_r5_backport_r4_server_full_resource_conformance
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require_relative '../../../../../common/notification_conformance_verification'
|
|
2
|
+
|
|
3
|
+
module SubscriptionsTestKit
|
|
4
|
+
module SubscriptionsR5BackportR4Server
|
|
5
|
+
class IdOnlyConformanceTest < Inferno::Test
|
|
6
|
+
include NotificationConformanceVerification
|
|
7
|
+
|
|
8
|
+
id :subscriptions_r5_backport_r4_server_id_only_conformance
|
|
9
|
+
title 'Subscription Id-Only Notification Verification'
|
|
10
|
+
description %(
|
|
11
|
+
This test takes the received notification bundle and ensures it is conformant to the
|
|
12
|
+
[R4 Topic-Based Subscription Notification Bundle](https://hl7.org/fhir/uv/subscriptions-backport/STU1.1/StructureDefinition-backport-subscription-notification-r4.html)
|
|
13
|
+
profle.
|
|
14
|
+
|
|
15
|
+
With the content type of id-only, the resources involved in triggering the notification are only available
|
|
16
|
+
through other channels, but notifications include URLs which can be used to access those resources.
|
|
17
|
+
|
|
18
|
+
When the content type is id-only, notification bundles SHALL include references to the appropriate focus resources
|
|
19
|
+
in the SubscriptionStatus.notificationEvent.focus element.
|
|
20
|
+
|
|
21
|
+
Additionally, notification bundles MAY contain, in addition to the SubscriptionStatus used to convey status
|
|
22
|
+
information, at least one Bundle.entry for each resource relevant to the notification.
|
|
23
|
+
|
|
24
|
+
Each Bundle.entry for id-only notification SHALL contain a relevant resource URL in the fullUrl and request
|
|
25
|
+
elements, as is required for history bundles.
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
verifies_requirements 'hl7.fhir.uv.subscriptions_1.1.0@14',
|
|
29
|
+
'hl7.fhir.uv.subscriptions_1.1.0@15',
|
|
30
|
+
'hl7.fhir.uv.subscriptions_1.1.0@28',
|
|
31
|
+
'hl7.fhir.uv.subscriptions_1.1.0@69',
|
|
32
|
+
'hl7.fhir.uv.subscriptions_1.1.0@70',
|
|
33
|
+
'hl7.fhir.uv.subscriptions_1.1.0@40',
|
|
34
|
+
'hl7.fhir.uv.subscriptions_1.1.0@42',
|
|
35
|
+
'hl7.fhir.uv.subscriptions_1.1.0@35',
|
|
36
|
+
'hl7.fhir.uv.subscriptions_1.1.0@67',
|
|
37
|
+
'hl7.fhir.uv.subscriptions_1.1.0@51',
|
|
38
|
+
'hl7.fhir.uv.subscriptions_1.1.0@53',
|
|
39
|
+
'hl7.fhir.uv.subscriptions_1.1.0@65',
|
|
40
|
+
'hl7.fhir.uv.subscriptions_1.1.0@100',
|
|
41
|
+
'hl7.fhir.uv.subscriptions_1.1.0@138',
|
|
42
|
+
'hl7.fhir.uv.subscriptions_1.1.0@139'
|
|
43
|
+
|
|
44
|
+
run do
|
|
45
|
+
subscription_requests = load_tagged_requests('subscription_creation', 'id-only')
|
|
46
|
+
omit_if subscription_requests.empty?, 'No Subscriptions sent with notification payload type of `id-only`'
|
|
47
|
+
|
|
48
|
+
subscription_requests.each do |subscription_request|
|
|
49
|
+
assert_valid_json(subscription_request.response_body)
|
|
50
|
+
subscription = JSON.parse(subscription_request.response_body)
|
|
51
|
+
|
|
52
|
+
requests = load_tagged_requests('event-notification', subscription['id'])
|
|
53
|
+
skip_if requests.empty?, 'No event-notification requests were made in a previous test as expected.'
|
|
54
|
+
|
|
55
|
+
criteria_resource_type = subscription_criteria(subscription)
|
|
56
|
+
requests = requests.uniq(&:request_body)
|
|
57
|
+
|
|
58
|
+
requests.each do |request|
|
|
59
|
+
id_only_event_notification_verification(request.request_body, criteria_resource_type)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
no_error_verification('Received notification-events are not conformant.')
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|