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,58 @@
|
|
|
1
|
+
require_relative '../../common/interaction_group'
|
|
2
|
+
require_relative '../../common/interaction_verification_group'
|
|
3
|
+
require_relative 'id_only_content/id_only_conformance_test'
|
|
4
|
+
|
|
5
|
+
module SubscriptionsTestKit
|
|
6
|
+
module SubscriptionsR5BackportR4Server
|
|
7
|
+
class IdOnlyContentGroup < Inferno::TestGroup
|
|
8
|
+
id :subscriptions_r5_backport_r4_server_id_only_content
|
|
9
|
+
title 'Id Only 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 `id-only` content type ([example id-only
|
|
14
|
+
Subscription](https://github.com/inferno-framework/subscriptions-test-kit/blob/main/lib/subscriptions_test_kit/docs/samples/Subscription_id-only.json)).
|
|
15
|
+
)
|
|
16
|
+
run_as_group
|
|
17
|
+
optional
|
|
18
|
+
|
|
19
|
+
input_order :url, :credentials, :access_token, :id_only_subscription_resource
|
|
20
|
+
|
|
21
|
+
group from: :subscriptions_r5_backport_r4_server_interaction do
|
|
22
|
+
id :subscriptions_r5_backport_r4_server_id_only_content_interaction
|
|
23
|
+
optional
|
|
24
|
+
|
|
25
|
+
config(
|
|
26
|
+
options: { subscription_type: 'id-only' },
|
|
27
|
+
inputs: {
|
|
28
|
+
subscription_resource: {
|
|
29
|
+
name: :id_only_subscription_resource,
|
|
30
|
+
title: 'Id-Only 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 id-only 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: :id_only_updated_subscription }
|
|
41
|
+
},
|
|
42
|
+
outputs: {
|
|
43
|
+
updated_subscription: { name: :id_only_updated_subscription }
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
end
|
|
47
|
+
group from: :subscriptions_r5_backport_r4_server_interaction_verification do
|
|
48
|
+
id :subscriptions_r5_backport_r4_server_id_only_content_interaction_verification
|
|
49
|
+
optional
|
|
50
|
+
|
|
51
|
+
config(
|
|
52
|
+
options: { subscription_type: 'id-only' }
|
|
53
|
+
)
|
|
54
|
+
test from: :subscriptions_r5_backport_r4_server_id_only_conformance
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require_relative 'event_notification/empty_content_group'
|
|
2
|
+
require_relative 'event_notification/full_resource_content_group'
|
|
3
|
+
require_relative 'event_notification/id_only_content_group'
|
|
4
|
+
|
|
5
|
+
module SubscriptionsTestKit
|
|
6
|
+
module SubscriptionsR5BackportR4Server
|
|
7
|
+
class EventNotificationGroup < Inferno::TestGroup
|
|
8
|
+
id :subscriptions_r5_backport_r4_server_event_notification
|
|
9
|
+
title 'Backport Subscription 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 content type. This group contains tests for the three options
|
|
14
|
+
available when specifying the contents of a Notification: empty, id-only, and full-resource.
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
input_order :url, :credentials, :access_token, :empty_subscription_resource,
|
|
18
|
+
:id_only_subscription_resource, :full_resource_subscription_resource
|
|
19
|
+
|
|
20
|
+
group from: :subscriptions_r5_backport_r4_server_empty_content
|
|
21
|
+
group from: :subscriptions_r5_backport_r4_server_id_only_content
|
|
22
|
+
group from: :subscriptions_r5_backport_r4_server_full_resource_content
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require_relative '../../../../common/notification_conformance_verification'
|
|
2
|
+
|
|
3
|
+
module SubscriptionsTestKit
|
|
4
|
+
module SubscriptionsR5BackportR4Server
|
|
5
|
+
class HandshakeConformanceTest < Inferno::Test
|
|
6
|
+
include NotificationConformanceVerification
|
|
7
|
+
|
|
8
|
+
id :subscriptions_r5_backport_r4_server_handshake_conformance
|
|
9
|
+
title 'Subscription Handshake Verification'
|
|
10
|
+
description %(
|
|
11
|
+
When a Subscription is created for a REST Hook channel type, the server SHALL set initial status to requested,
|
|
12
|
+
pending verification of the nominated endpoint URL. The Server will then send a handshake bundle to the endpoint.
|
|
13
|
+
After a successful handshake notification has been sent and accepted, the server SHALL update the status to
|
|
14
|
+
active. This test verifies that the incoming handshake request is a conformant
|
|
15
|
+
[R4 Topic-Based Subscription Notification Bundle](https://hl7.org/fhir/uv/subscriptions-backport/STU1.1/StructureDefinition-backport-subscription-notification-r4.html).
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
verifies_requirements 'hl7.fhir.uv.subscriptions_1.1.0@14',
|
|
19
|
+
'hl7.fhir.uv.subscriptions_1.1.0@15',
|
|
20
|
+
'hl7.fhir.uv.subscriptions_1.1.0@28',
|
|
21
|
+
'hl7.fhir.uv.subscriptions_1.1.0@69',
|
|
22
|
+
'hl7.fhir.uv.subscriptions_1.1.0@70',
|
|
23
|
+
'hl7.fhir.uv.subscriptions_1.1.0@24',
|
|
24
|
+
'hl7.fhir.uv.subscriptions_1.1.0@25',
|
|
25
|
+
'hl7.fhir.uv.subscriptions_1.1.0@138',
|
|
26
|
+
'hl7.fhir.uv.subscriptions_1.1.0@139'
|
|
27
|
+
|
|
28
|
+
run do
|
|
29
|
+
subscription_requests = load_tagged_requests('subscription_creation')
|
|
30
|
+
skip_if(subscription_requests.empty?, %(
|
|
31
|
+
No Subscription creation requests were made in previous tests. Must run Subscription Workflow tests first in
|
|
32
|
+
order to run this test.))
|
|
33
|
+
|
|
34
|
+
subscription_request_ids =
|
|
35
|
+
subscription_requests
|
|
36
|
+
.select { |request| request.status == 201 }
|
|
37
|
+
.uniq(&:response_body)
|
|
38
|
+
.map { |request| JSON.parse(request.response_body) }
|
|
39
|
+
.select { |subscription| subscription['channel']['type'] == 'rest-hook' }
|
|
40
|
+
.map { |subscription| subscription['id'] }
|
|
41
|
+
|
|
42
|
+
requests = load_tagged_requests('handshake')
|
|
43
|
+
if requests.empty?
|
|
44
|
+
omit_if subscription_request_ids.empty?, 'No handshake requests were required or received in a previous tests.'
|
|
45
|
+
assert(subscription_request_ids.empty?,
|
|
46
|
+
'Handshake requests are required if a Subscription channel type is `rest-hook`')
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
requests = requests.uniq(&:request_body)
|
|
50
|
+
|
|
51
|
+
requests.each do |request|
|
|
52
|
+
tags = request.tags.dup
|
|
53
|
+
tags -= ['handshake']
|
|
54
|
+
subscription_id = tags.first
|
|
55
|
+
|
|
56
|
+
subscription_request_ids.delete(subscription_id)
|
|
57
|
+
|
|
58
|
+
notification_verification(request.request_body, 'handshake', subscription_id:, status: 'requested')
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
no_error_verification('Received handshakes are not conformant.')
|
|
62
|
+
assert(subscription_request_ids.empty?,
|
|
63
|
+
'Did not receive a handshake notification for some `rest-hook` subscriptions')
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require_relative '../../../../common/notification_conformance_verification'
|
|
2
|
+
|
|
3
|
+
module SubscriptionsTestKit
|
|
4
|
+
module SubscriptionsR5BackportR4Server
|
|
5
|
+
class HeartbeatConformanceTest < Inferno::Test
|
|
6
|
+
include NotificationConformanceVerification
|
|
7
|
+
|
|
8
|
+
id :subscriptions_r5_backport_r4_server_heartbeat_conformance
|
|
9
|
+
title 'Subscription Heartbeat Verification'
|
|
10
|
+
description %(
|
|
11
|
+
When a Subscription is created for a REST Hook channel type, the server Server may send notifications of type
|
|
12
|
+
heartbeat at any time. This test verifies that the incoming heartbeat request is a conformant
|
|
13
|
+
[R4 Topic-Based Subscription Notification Bundle](https://hl7.org/fhir/uv/subscriptions-backport/STU1.1/StructureDefinition-backport-subscription-notification-r4.html).
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
verifies_requirements 'hl7.fhir.uv.subscriptions_1.1.0@14',
|
|
17
|
+
'hl7.fhir.uv.subscriptions_1.1.0@15',
|
|
18
|
+
'hl7.fhir.uv.subscriptions_1.1.0@28',
|
|
19
|
+
'hl7.fhir.uv.subscriptions_1.1.0@69',
|
|
20
|
+
'hl7.fhir.uv.subscriptions_1.1.0@70',
|
|
21
|
+
'hl7.fhir.uv.subscriptions_1.1.0@138',
|
|
22
|
+
'hl7.fhir.uv.subscriptions_1.1.0@139',
|
|
23
|
+
'hl7.fhir.uv.subscriptions_1.1.0@93',
|
|
24
|
+
'hl7.fhir.uv.subscriptions_1.1.0@94'
|
|
25
|
+
|
|
26
|
+
def heartbeat_period?(subscription_extensions)
|
|
27
|
+
return false if subscription_extensions.blank?
|
|
28
|
+
|
|
29
|
+
heartbeat = subscription_extensions.find { |extension| extension['url'].ends_with?('/backport-heartbeat-period') }
|
|
30
|
+
|
|
31
|
+
return false if heartbeat.blank?
|
|
32
|
+
|
|
33
|
+
heartbeat['valueUnsignedInt'].present?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
run do
|
|
37
|
+
subscription_requests = load_tagged_requests('subscription_creation')
|
|
38
|
+
skip_if(subscription_requests.empty?, %(
|
|
39
|
+
No Subscription creation requests were made in previous tests. Must run Subscription Workflow tests first in
|
|
40
|
+
order to run this test.))
|
|
41
|
+
|
|
42
|
+
subscription_request_ids =
|
|
43
|
+
subscription_requests
|
|
44
|
+
.select { |request| request.status == 201 }
|
|
45
|
+
.uniq(&:response_body)
|
|
46
|
+
.map { |request| JSON.parse(request.response_body) }
|
|
47
|
+
.select { |subscription| heartbeat_period?(subscription['channel']['extension']) }
|
|
48
|
+
.map { |subscription| subscription['id'] }
|
|
49
|
+
|
|
50
|
+
requests = load_tagged_requests('heartbeat')
|
|
51
|
+
if requests.empty?
|
|
52
|
+
omit_if subscription_request_ids.empty?, 'No heartbeat requests requested or received in previous tests.'
|
|
53
|
+
assert(subscription_request_ids.empty?, %(
|
|
54
|
+
No Heartbeat notifications received when heartbeat was requested by the subscriber (`heartbeatPeriod` is
|
|
55
|
+
populated)))
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
requests = requests.uniq(&:request_body)
|
|
59
|
+
|
|
60
|
+
requests.each do |request|
|
|
61
|
+
tags = request.tags.dup
|
|
62
|
+
tags -= ['heartbeat']
|
|
63
|
+
subscription_id = tags.first
|
|
64
|
+
|
|
65
|
+
assert(subscription_request_ids.include?(subscription_id),
|
|
66
|
+
'If `heartbeatPeriod` field is not present in the Subscription, heartbeat should not be sent.')
|
|
67
|
+
|
|
68
|
+
notification_verification(request.request_body, 'heartbeat', subscription_id:)
|
|
69
|
+
no_error_verification('Received heartbeats are not conformant.')
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require_relative 'handshake_heartbeat/handshake_conformance_test'
|
|
2
|
+
require_relative 'handshake_heartbeat/heartbeat_conformance_test'
|
|
3
|
+
|
|
4
|
+
module SubscriptionsTestKit
|
|
5
|
+
module SubscriptionsR5BackportR4Server
|
|
6
|
+
class HandshakeHeartbeatGroup < Inferno::TestGroup
|
|
7
|
+
id :subscriptions_r5_backport_r4_server_handshake_heartbeat
|
|
8
|
+
title 'Backport Subscription Handshake and Heartbeat Notification Verification'
|
|
9
|
+
description %(
|
|
10
|
+
Verify that the any received Handshake or Heartbeat Notifications are conformant to the
|
|
11
|
+
[R4 Topic-Based Subscription Notification Bundle](https://hl7.org/fhir/uv/subscriptions-backport/STU1.1/StructureDefinition-backport-subscription-notification-r4.html)
|
|
12
|
+
profile.
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
test from: :subscriptions_r5_backport_r4_server_handshake_conformance
|
|
16
|
+
test from: :subscriptions_r5_backport_r4_server_heartbeat_conformance
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require_relative '../../common/subscription_status_operation'
|
|
2
|
+
|
|
3
|
+
module SubscriptionsTestKit
|
|
4
|
+
module SubscriptionsR5BackportR4Server
|
|
5
|
+
class StatusInvocationTest < Inferno::Test
|
|
6
|
+
include SubscriptionStatusOperation
|
|
7
|
+
|
|
8
|
+
id :subscriptions_r5_backport_r4_server_status_invocation
|
|
9
|
+
title 'Server supports subscription $status operation'
|
|
10
|
+
description %(
|
|
11
|
+
In order to claim conformance with this guide, a server: SHALL support the [$status operation](https://hl7.org/fhir/uv/subscriptions-backport/STU1.1/OperationDefinition-backport-subscription-status.html)
|
|
12
|
+
on the Subscription resource. This operation is used to return the current status information about one or more
|
|
13
|
+
topic-based Subscriptions in R4. The operation returns a bundle containing one or more subscription status
|
|
14
|
+
resources, one per Subscription being queried. The Bundle type is "searchset". The status of the Subscription
|
|
15
|
+
should be set to 'active' after a successful handshake with the rest-hook endpoint.
|
|
16
|
+
|
|
17
|
+
This test ensures the server supports the $status operation by performing the operation and ensuring it receives a
|
|
18
|
+
valid response.
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
verifies_requirements 'hl7.fhir.uv.subscriptions_1.1.0@20',
|
|
22
|
+
'hl7.fhir.uv.subscriptions_1.1.0@30',
|
|
23
|
+
'hl7.fhir.uv.subscriptions_1.1.0@47'
|
|
24
|
+
|
|
25
|
+
run do
|
|
26
|
+
subscription_requests = load_tagged_requests('subscription_creation')
|
|
27
|
+
success_subscription_requests =
|
|
28
|
+
subscription_requests
|
|
29
|
+
.select { |request| request.status == 201 }
|
|
30
|
+
skip_if success_subscription_requests.empty?, %(
|
|
31
|
+
No successful Subscription creation requests were made in previous tests. Must run Subscription Workflow tests
|
|
32
|
+
first in order to run this test.
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
subscription = JSON.parse(success_subscription_requests.first.response_body)
|
|
36
|
+
subscription_id = subscription['id']
|
|
37
|
+
|
|
38
|
+
perform_subscription_status_test(subscription_id)
|
|
39
|
+
no_error_verification('Subscription status response was not conformant.')
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require_relative 'status_operation/status_invocation_test'
|
|
2
|
+
|
|
3
|
+
module SubscriptionsTestKit
|
|
4
|
+
module SubscriptionsR5BackportR4Server
|
|
5
|
+
class StatusOperationGroup < Inferno::TestGroup
|
|
6
|
+
id :subscriptions_r5_backport_r4_server_status_operation
|
|
7
|
+
title 'Subscription $status Operation Verification'
|
|
8
|
+
description %(
|
|
9
|
+
This test group verifies that the Backport Subscriptions Server supports the $status operation.
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
test from: :subscriptions_r5_backport_r4_server_status_invocation
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
require_relative '../../common/subscription_creation'
|
|
2
|
+
|
|
3
|
+
module SubscriptionsTestKit
|
|
4
|
+
module SubscriptionsR5BackportR4Server
|
|
5
|
+
class RejectSubscriptionsTest < Inferno::Test
|
|
6
|
+
include SubscriptionCreation
|
|
7
|
+
|
|
8
|
+
id :subscriptions_r5_backport_r4_server_reject_subscriptions
|
|
9
|
+
title 'Server Handles Unsupported Subscriptions'
|
|
10
|
+
description %(
|
|
11
|
+
When processing a request for a Subscription a server SHOULD verify that the Subscription is supported and does not
|
|
12
|
+
contain any information not implemented by the server. If the Subscription is no supported, the server should reject
|
|
13
|
+
the Subscription create request, or it should attempt to adjust the Subscription. This test checks that the server
|
|
14
|
+
correctly rejects or adjusts the Subscription in the following cases:
|
|
15
|
+
|
|
16
|
+
- The Subscription contains cross-version extension
|
|
17
|
+
- The Subscription contains a Subscription Topic not implemented by the server
|
|
18
|
+
- The Subscription contains a filtering criteria not implemented by the server
|
|
19
|
+
- The Subscription contains channel type not implemented by the server
|
|
20
|
+
- The Subscription contains an unsupported channel endpoint
|
|
21
|
+
- The Subscription contains a payload type not implemented by the server
|
|
22
|
+
- The Subscription contains an unsupported channel and payload type combination
|
|
23
|
+
|
|
24
|
+
The test will pass if the server either
|
|
25
|
+
1. rejects the Subscription by responding with a non-201 response, or
|
|
26
|
+
2. updates the Subscription resource to remove or replace the unsupported value.
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
verifies_requirements 'hl7.fhir.uv.subscriptions_1.1.0@8',
|
|
30
|
+
'hl7.fhir.uv.subscriptions_1.1.0@9',
|
|
31
|
+
'hl7.fhir.uv.subscriptions_1.1.0@10',
|
|
32
|
+
'hl7.fhir.uv.subscriptions_1.1.0@11',
|
|
33
|
+
'hl7.fhir.uv.subscriptions_1.1.0@12',
|
|
34
|
+
'hl7.fhir.uv.subscriptions_1.1.0@13'
|
|
35
|
+
|
|
36
|
+
input :subscription_resource,
|
|
37
|
+
title: 'Workflow Subscription Resource',
|
|
38
|
+
type: 'textarea',
|
|
39
|
+
description: %(
|
|
40
|
+
A Subscription resource in JSON format that Inferno will send to the server under test
|
|
41
|
+
so that it can demonstrate its ability to perform the Subscription creation and Notification
|
|
42
|
+
response workflow. The instance must be conformant to the R4/B Topic-Based Subscription profile.
|
|
43
|
+
Inferno may modify the Subscription before submission, e.g., to point to Inferno's notification endpoint.
|
|
44
|
+
This input is also used by the unsupported Subscription test as the base on which to add unsupported element
|
|
45
|
+
values to test for server rejection.
|
|
46
|
+
)
|
|
47
|
+
input :unsupported_subscription_topic,
|
|
48
|
+
title: 'Unsupported Subscription Topic',
|
|
49
|
+
description: 'A Subscription Topic for the `criteria` element that is not implemented by the server to test for Subscription rejection.',
|
|
50
|
+
optional: true
|
|
51
|
+
input :unsupported_subscription_filter,
|
|
52
|
+
title: 'Unsupported Subscription Filter',
|
|
53
|
+
description: 'A value for `filterCriteria` extension under the `criteria` that is not implemented by the server to test for Subscription rejection.',
|
|
54
|
+
optional: true
|
|
55
|
+
input :unsupported_subscription_channel_type,
|
|
56
|
+
title: 'Unsupported Subscription Channel Type',
|
|
57
|
+
description: 'A value for the `channel.type` element that is not implemented by the server to test for Subscription rejection.',
|
|
58
|
+
optional: true
|
|
59
|
+
input :unsupported_subscription_channel_endpoint,
|
|
60
|
+
title: 'Unsupported Subscription Channel Endpoint',
|
|
61
|
+
description: 'An unsupported value for the `channel.endpoint` element to test for Subscription rejection.',
|
|
62
|
+
optional: true
|
|
63
|
+
input :unsupported_subscription_payload_type,
|
|
64
|
+
title: 'Unsupported Subscription Payload Type',
|
|
65
|
+
description: 'A value for the `content` extension under the `channel.payload` element that is not implemented by the server to test for Subscription rejection.',
|
|
66
|
+
optional: true
|
|
67
|
+
input :unsupported_subscription_channel_payload_combo,
|
|
68
|
+
title: 'Unsupported Subscription Channel and Payload Combination',
|
|
69
|
+
description: %(
|
|
70
|
+
A channel (`channel.type`) and payload type (`content` extension under the `channel.payload` element)
|
|
71
|
+
combination not implemented by the server to test for Subscription
|
|
72
|
+
rejection. Provide in the json format e.g. {channel: <'channel_type'>, payload: <'payload_type'>}.
|
|
73
|
+
),
|
|
74
|
+
optional: true
|
|
75
|
+
|
|
76
|
+
def unsupported_subscriptions
|
|
77
|
+
[
|
|
78
|
+
{
|
|
79
|
+
'unsupported_title' => 'cross-version extensions',
|
|
80
|
+
'field_path' => ['_criteria'],
|
|
81
|
+
'field_value' => { 'extension' => [{
|
|
82
|
+
url: 'http://hl7.org/fhir/5.0/subscriptions-backport/StructureDefinition/backport-filter-criteria',
|
|
83
|
+
valueString: 'Encounter?patient=Patient/123'
|
|
84
|
+
}] }
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
'unsupported_title' => 'unsupported `SubscriptionTopic`',
|
|
88
|
+
'field_path' => ['criteria'],
|
|
89
|
+
'field_value' => unsupported_subscription_topic
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
'unsupported_title' => 'unsupported filter criteria',
|
|
93
|
+
'field_path' => ['_criteria'],
|
|
94
|
+
'field_value' => if unsupported_subscription_filter.nil?
|
|
95
|
+
unsupported_subscription_filter
|
|
96
|
+
else
|
|
97
|
+
{ 'extension' => [{
|
|
98
|
+
url: 'http://hl7.org/fhir/uv/subscriptions-backport/StructureDefinition/backport-filter-criteria',
|
|
99
|
+
valueString: unsupported_subscription_filter
|
|
100
|
+
}] }
|
|
101
|
+
end
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
'unsupported_title' => 'unsupported channel type',
|
|
105
|
+
'field_path' => ['channel', 'type'],
|
|
106
|
+
'field_value' => unsupported_subscription_channel_type
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
'unsupported_title' => 'unsupported channel URL',
|
|
110
|
+
'field_path' => ['channel', 'endpoint'],
|
|
111
|
+
'field_value' => unsupported_subscription_channel_endpoint
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
'unsupported_title' => 'unsupported channel type',
|
|
115
|
+
'field_path' => ['channel', 'type'],
|
|
116
|
+
'field_value' => unsupported_subscription_channel_type
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
'unsupported_title' => 'unsupported payload type',
|
|
120
|
+
'field_path' => ['channel', 'payload'],
|
|
121
|
+
'field_value' => unsupported_subscription_payload_type
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
run do
|
|
127
|
+
assert_valid_json(subscription_resource)
|
|
128
|
+
subscription = JSON.parse(subscription_resource)
|
|
129
|
+
|
|
130
|
+
unsupported_subscriptions.each do |unsupported_info|
|
|
131
|
+
next if unsupported_info['field_value'].blank?
|
|
132
|
+
|
|
133
|
+
field_name = unsupported_info['field_path'].last
|
|
134
|
+
|
|
135
|
+
if unsupported_info['field_path'].length > 1
|
|
136
|
+
outer_field_name = unsupported_info['field_path'].first
|
|
137
|
+
subscription_field = subscription[outer_field_name]
|
|
138
|
+
else
|
|
139
|
+
subscription_field = subscription
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
original_field_value = subscription_field[field_name]
|
|
143
|
+
subscription_field[field_name] = unsupported_info['field_value']
|
|
144
|
+
|
|
145
|
+
send_unsupported_subscription(subscription, unsupported_info['unsupported_title'], [unsupported_info['field_path']],
|
|
146
|
+
[unsupported_info['field_value']])
|
|
147
|
+
|
|
148
|
+
if original_field_value.nil?
|
|
149
|
+
subscription_field.delete(field_name)
|
|
150
|
+
else
|
|
151
|
+
subscription_field[field_name] = original_field_value
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
if unsupported_subscription_channel_payload_combo.present?
|
|
156
|
+
assert_valid_json(unsupported_subscription_channel_payload_combo)
|
|
157
|
+
channel_payload_combo = JSON.parse(unsupported_subscription_channel_payload_combo)
|
|
158
|
+
channel_value = channel_payload_combo['channel']
|
|
159
|
+
payload_value = channel_payload_combo['payload']
|
|
160
|
+
|
|
161
|
+
if channel_value.blank? || payload_value.blank?
|
|
162
|
+
add_message('error', %(
|
|
163
|
+
Channel and payload values are not populated correctly in unsupported channel and payload combination input.))
|
|
164
|
+
else
|
|
165
|
+
subscription_channel = subscription['channel']
|
|
166
|
+
subscription_channel['type'] = channel_value
|
|
167
|
+
subscription_channel['payload'] = payload_value
|
|
168
|
+
|
|
169
|
+
channel_path = ['channel', 'type']
|
|
170
|
+
payload_path = ['channel', 'payload']
|
|
171
|
+
|
|
172
|
+
send_unsupported_subscription(subscription, 'unsupported channel and payload combination', [channel_path, payload_path],
|
|
173
|
+
[channel_value, payload_value])
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
no_error_verification('Unsupported Subscription creation error handling failures.')
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require_relative 'subscription_rejection/reject_subscriptions_test'
|
|
2
|
+
|
|
3
|
+
module SubscriptionsTestKit
|
|
4
|
+
module SubscriptionsR5BackportR4Server
|
|
5
|
+
class SubscriptionRejectionGroup < Inferno::TestGroup
|
|
6
|
+
id :subscriptions_r5_backport_r4_server_subscription_rejection
|
|
7
|
+
title 'Subscription Creation Rejection Verification'
|
|
8
|
+
description %(
|
|
9
|
+
This test group verifies that the Backport Subscriptions Server supports rejecting unsupported
|
|
10
|
+
Subscription creation requests.
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
input_order :url, :credentials, :subscription_resource, :unsupported_subscription_topic,
|
|
14
|
+
:unsupported_subscription_filter, :unsupported_subscription_channel_type,
|
|
15
|
+
:unsupported_subscription_channel_endpoint, :unsupported_subscription_payload_type,
|
|
16
|
+
:unsupported_subscription_channel_payload_combo
|
|
17
|
+
|
|
18
|
+
test from: :subscriptions_r5_backport_r4_server_reject_subscriptions
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require_relative 'coverage/capability_statement_group'
|
|
2
|
+
require_relative 'coverage/event_notification_group'
|
|
3
|
+
require_relative 'coverage/handshake_heartbeat_group'
|
|
4
|
+
require_relative 'coverage/status_operation_group'
|
|
5
|
+
require_relative 'coverage/subscription_rejection_group'
|
|
6
|
+
|
|
7
|
+
module SubscriptionsTestKit
|
|
8
|
+
module SubscriptionsR5BackportR4Server
|
|
9
|
+
module Coverage
|
|
10
|
+
class GroupForCoverage < Inferno::TestGroup
|
|
11
|
+
id :subscriptions_r5_backport_r4_server_coverage
|
|
12
|
+
title 'Demonstrate coverage of all Subscription Backport IG requirements'
|
|
13
|
+
description %(
|
|
14
|
+
Demonstrate that the server covers all requirements placed on
|
|
15
|
+
servers by the IG.
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
group from: :subscriptions_r5_backport_r4_server_capability_statement
|
|
19
|
+
group from: :subscriptions_r5_backport_r4_server_event_notification
|
|
20
|
+
group from: :subscriptions_r5_backport_r4_server_handshake_heartbeat
|
|
21
|
+
group from: :subscriptions_r5_backport_r4_server_status_operation
|
|
22
|
+
group from: :subscriptions_r5_backport_r4_server_subscription_rejection
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require_relative 'common/interaction_group'
|
|
2
|
+
require_relative 'common/interaction_verification_group'
|
|
3
|
+
|
|
4
|
+
module SubscriptionsTestKit
|
|
5
|
+
module SubscriptionsR5BackportR4Server
|
|
6
|
+
class WorkflowGroup < Inferno::TestGroup
|
|
7
|
+
id :subscriptions_r5_backport_r4_server_workflow
|
|
8
|
+
title 'Demonstrate the subscription workflow'
|
|
9
|
+
description %(
|
|
10
|
+
Demonstrate the ability of the server to accept a request for the
|
|
11
|
+
creation of a FHIR Subscription instance and deliver a notification
|
|
12
|
+
for that Subscription. The tester must provide a Subscription instance
|
|
13
|
+
that the server under test supports. Inferno will act as a client,
|
|
14
|
+
creating the Subscription and waiting for a notification based on it.
|
|
15
|
+
Inferno will then verify that the Subscription and the Notification
|
|
16
|
+
match and that the exchange is conformant.
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
run_as_group
|
|
20
|
+
|
|
21
|
+
input_order :url, :credentials, :access_token, :subscription_resource
|
|
22
|
+
|
|
23
|
+
group from: :subscriptions_r5_backport_r4_server_interaction
|
|
24
|
+
group from: :subscriptions_r5_backport_r4_server_interaction_verification
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require_relative 'subscriptions_r5_backport_r4_server/workflow_group'
|
|
2
|
+
require_relative 'subscriptions_r5_backport_r4_server/coverage_group'
|
|
3
|
+
require_relative '../endpoints/subscription_rest_hook_endpoint'
|
|
4
|
+
require_relative '../urls'
|
|
5
|
+
require_relative '../version'
|
|
6
|
+
|
|
7
|
+
module SubscriptionsTestKit
|
|
8
|
+
module SubscriptionsR5BackportR4Server
|
|
9
|
+
class SubscriptionsR5BackportR4ServerSuite < Inferno::TestSuite
|
|
10
|
+
id :subscriptions_r5_backport_r4_server
|
|
11
|
+
title 'Subscriptions R5 Backport IG v1.1.0 FHIR R4 Server Test Suite'
|
|
12
|
+
short_title 'Subscriptions R4 Server'
|
|
13
|
+
version VERSION
|
|
14
|
+
description File.read(File.join(__dir__, '..', 'docs', 'subscriptions_r5_backport_r4_server_suite_description.md'))
|
|
15
|
+
|
|
16
|
+
links [
|
|
17
|
+
{
|
|
18
|
+
label: 'Report Issue',
|
|
19
|
+
url: 'https://github.com/inferno-framework/subscriptions-test-kit/issues'
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
label: 'Open Source',
|
|
23
|
+
url: 'https://github.com/inferno-framework/subscriptions-test-kit'
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
label: 'Download',
|
|
27
|
+
url: 'https://github.com/inferno-framework/subscriptions-test-kit/releases'
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
label: 'Implementation Guide',
|
|
31
|
+
url: 'https://hl7.org/fhir/uv/subscriptions-backport/STU1.1/'
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
# These inputs will be available to all tests in this suite
|
|
36
|
+
input :url,
|
|
37
|
+
title: 'FHIR Server Base URL',
|
|
38
|
+
description: %(
|
|
39
|
+
FHIR base URL for the server under test where Inferno will send
|
|
40
|
+
Subscription Creation, $status, and other requests as a part of
|
|
41
|
+
these tests.
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
input :credentials,
|
|
45
|
+
title: 'OAuth Credentials',
|
|
46
|
+
description: 'Credentials for Inferno to include when making requests against the server under test.',
|
|
47
|
+
type: :oauth_credentials,
|
|
48
|
+
optional: true
|
|
49
|
+
|
|
50
|
+
# All FHIR requests in this suite will use this FHIR client
|
|
51
|
+
fhir_client do
|
|
52
|
+
url :url
|
|
53
|
+
oauth_credentials :credentials
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# All FHIR validation requests will use this FHIR validator
|
|
57
|
+
fhir_resource_validator do
|
|
58
|
+
igs 'hl7.fhir.uv.subscriptions-backport#1.1.0'
|
|
59
|
+
|
|
60
|
+
exclude_message do |message|
|
|
61
|
+
message.message.match?(/\A\S+: \S+: URL value '.*' does not resolve/)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def self.extract_token_from_query_params(request)
|
|
66
|
+
request.query_parameters['token']
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
suite_endpoint :post, SUBSCRIPTION_CHANNEL_PATH, SubscriptionRestHookEndpoint
|
|
70
|
+
|
|
71
|
+
resume_test_route :get, RESUME_PASS_PATH do |request|
|
|
72
|
+
SubscriptionsR5BackportR4ServerSuite.extract_token_from_query_params(request)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
group from: :subscriptions_r5_backport_r4_server_workflow
|
|
76
|
+
group from: :subscriptions_r5_backport_r4_server_coverage
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SubscriptionsTestKit
|
|
4
|
+
NOTIFICATION_TAG = 'subscription_notification'
|
|
5
|
+
SUBSCRIPTION_CREATE_TAG = 'subscription_create'
|
|
6
|
+
SUBSCRIPTION_READ_TAG = 'subscription_read'
|
|
7
|
+
SUBSCRIPTION_STATUS_TAG = 'subscription_status'
|
|
8
|
+
REST_HOOK_HANDSHAKE_NOTIFICATION_TAG = 'rest_hook_handshake_notification'
|
|
9
|
+
REST_HOOK_EVENT_NOTIFICATION_TAG = 'rest_hook_event_notification'
|
|
10
|
+
end
|