inferno_core 0.4.43 → 0.4.44
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/inferno/apps/cli/execute/console_outputter.rb +152 -0
- data/lib/inferno/apps/cli/execute.rb +269 -0
- data/lib/inferno/apps/cli/main.rb +73 -4
- data/lib/inferno/apps/cli/templates/.env.development +2 -1
- data/lib/inferno/apps/cli/templates/.env.production +2 -1
- data/lib/inferno/apps/cli/templates/.env.test +1 -0
- data/lib/inferno/apps/cli/templates/.gitignore +1 -0
- data/lib/inferno/apps/cli/templates/config/nginx.background.conf.tt +15 -0
- data/lib/inferno/apps/cli/templates/docker-compose.background.yml.tt +5 -0
- data/lib/inferno/apps/cli/templates/docker-compose.yml.tt +4 -0
- data/lib/inferno/apps/cli.rb +0 -1
- data/lib/inferno/apps/web/controllers/test_runs/create.rb +7 -32
- data/lib/inferno/apps/web/serializers/serializer.rb +3 -0
- data/lib/inferno/config/boot/executor.rb +14 -0
- data/lib/inferno/dsl/auth_info.rb +77 -72
- data/lib/inferno/dsl/fhir_client_builder.rb +2 -2
- data/lib/inferno/dsl/fhir_resource_validation.rb +4 -0
- data/lib/inferno/dsl/http_client_builder.rb +2 -2
- data/lib/inferno/dsl/links.rb +100 -0
- data/lib/inferno/dsl/runnable.rb +6 -1
- data/lib/inferno/entities/has_runnable.rb +1 -1
- data/lib/inferno/entities/test.rb +4 -4
- data/lib/inferno/entities/test_group.rb +2 -2
- data/lib/inferno/entities/test_suite.rb +2 -24
- data/lib/inferno/exceptions.rb +6 -0
- data/lib/inferno/ext/fhir_models.rb +3 -3
- data/lib/inferno/jobs.rb +4 -4
- data/lib/inferno/public/237.bundle.js +1 -0
- data/lib/inferno/public/assets.json +1 -1
- data/lib/inferno/public/bundle.js +42 -63
- data/lib/inferno/public/bundle.js.LICENSE.txt +5 -33
- data/lib/inferno/repositories/repository.rb +1 -1
- data/lib/inferno/result_summarizer.rb +1 -1
- data/lib/inferno/test_runner.rb +2 -2
- data/lib/inferno/utils/middleware/request_logger.rb +1 -1
- data/lib/inferno/utils/persist_inputs.rb +30 -0
- data/lib/inferno/utils/preset_template_generator.rb +1 -1
- data/lib/inferno/utils/verify_runnable.rb +15 -0
- data/lib/inferno/version.rb +1 -1
- data/spec/factories/result.rb +4 -0
- data/spec/fixtures/basic_test_group.rb +2 -1
- data/spec/fixtures/run_as_group_test_group.rb +11 -0
- metadata +24 -170
@@ -0,0 +1,14 @@
|
|
1
|
+
Inferno::Application.register_provider(:executor) do
|
2
|
+
prepare do
|
3
|
+
target_container.start :logging
|
4
|
+
|
5
|
+
require 'oj'
|
6
|
+
require 'blueprinter'
|
7
|
+
|
8
|
+
Blueprinter.configure do |config|
|
9
|
+
config.generator = Oj
|
10
|
+
end
|
11
|
+
|
12
|
+
target_container.start :suites
|
13
|
+
end
|
14
|
+
end
|
@@ -3,71 +3,73 @@ require_relative 'jwks'
|
|
3
3
|
|
4
4
|
module Inferno
|
5
5
|
module DSL
|
6
|
-
# AuthInfo
|
7
|
-
# needed for a
|
6
|
+
# AuthInfo provides a user with a single input which contains the information
|
7
|
+
# needed for a FHIR client to perform authorization and refresh an access
|
8
8
|
# token when necessary.
|
9
9
|
#
|
10
10
|
# AuthInfo supports the following `auth_type`:
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
11
|
+
#
|
12
|
+
# - `public` - Client id only
|
13
|
+
# - `symmetric` - Confidential symmetric (i.e., with a static client id and
|
14
|
+
# secret)
|
15
|
+
# - `asymmetric` - Confidential asymmetric (i.e., a client id with a signed
|
16
|
+
# JWT rather than a client secret)
|
17
|
+
# - `backend_services`
|
17
18
|
#
|
18
19
|
# When configuring an AuthInfo input, the invdidual fields are exposed as
|
19
20
|
# `components` in the input's options, and can be configured there similar
|
20
21
|
# to normal inputs.
|
21
22
|
#
|
22
23
|
# The AuthInfo input type supports two different modes in the UI. Different
|
23
|
-
# fields will be presented to the user depending on which mode is selected
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
24
|
+
# fields will be presented to the user depending on which mode is selected:
|
25
|
+
#
|
26
|
+
# - `auth` - This presents the inputs needed to perform authorization, and
|
27
|
+
# is appropriate to use as an input to test groups which perform
|
28
|
+
# authorization.
|
29
|
+
# - `access` - This presents the inputs needed to access resources assuming
|
30
|
+
# that authorization has already happened, and is appropriate to use as an
|
31
|
+
# input to test groups which access resources using previously granted
|
32
|
+
# authorization.
|
31
33
|
#
|
32
34
|
# @example
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
35
|
+
# class AuthInfoExampleSuite < Inferno::TestSuite
|
36
|
+
# input :url,
|
37
|
+
# title: 'Base FHIR url'
|
36
38
|
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
39
|
+
# group do
|
40
|
+
# title 'Perform public authorization'
|
41
|
+
# input :fhir_auth,
|
42
|
+
# type: :auth_info,
|
43
|
+
# options: {
|
44
|
+
# mode: 'auth',
|
45
|
+
# components: [
|
46
|
+
# {
|
47
|
+
# name: :auth_type,
|
48
|
+
# default: 'public',
|
49
|
+
# locked: true
|
50
|
+
# }
|
51
|
+
# ]
|
52
|
+
# }
|
51
53
|
#
|
52
|
-
#
|
53
|
-
#
|
54
|
+
# # Some tests here to perform authorization
|
55
|
+
# end
|
54
56
|
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
57
|
+
# group do
|
58
|
+
# title 'FHIR API Tests'
|
59
|
+
# input :fhir_auth,
|
60
|
+
# type: :auth_info,
|
61
|
+
# options: {
|
62
|
+
# mode: 'access'
|
63
|
+
# }
|
62
64
|
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
65
|
+
# fhir_client do
|
66
|
+
# url :url
|
67
|
+
# auth_info :fhir_auth
|
68
|
+
# end
|
67
69
|
#
|
68
|
-
#
|
70
|
+
# # Some tests here to access FHIR API
|
71
|
+
# end
|
69
72
|
# end
|
70
|
-
# end
|
71
73
|
class AuthInfo
|
72
74
|
ATTRIBUTES = [
|
73
75
|
:auth_type,
|
@@ -95,35 +97,38 @@ module Inferno
|
|
95
97
|
|
96
98
|
attr_accessor :client
|
97
99
|
|
98
|
-
# @!attribute [rw] auth_type
|
99
|
-
# One of `public`, `symmetric`, `asymmetric`, or `backend_services`
|
100
|
-
# @!attribute [rw] token_url
|
101
|
-
#
|
102
|
-
# @!attribute [rw]
|
103
|
-
#
|
100
|
+
# @!attribute [rw] auth_type
|
101
|
+
# The type of authorization to be performed. One of `public`, `symmetric`, `asymmetric`, or `backend_services`
|
102
|
+
# @!attribute [rw] token_url
|
103
|
+
# The url of the auth server's token endpoint
|
104
|
+
# @!attribute [rw] auth_url
|
105
|
+
# The url of the authorization endpoint
|
106
|
+
# @!attribute [rw] requested_scopes
|
107
|
+
# The scopes which will be requested during authorization
|
104
108
|
# @!attribute [rw] client_id
|
105
109
|
# @!attribute [rw] client_secret
|
106
110
|
# @!attribute [rw] redirect_url
|
107
|
-
# @!attribute [rw] pkce_support
|
108
|
-
# authorization. Either `enabled` or `disabled`.
|
109
|
-
# @!attribute [rw] pkce_code_challenge_method
|
110
|
-
# `plain`
|
111
|
-
# @!attribute [rw] auth_request_method
|
112
|
-
# to perform the request to the authorization endpoint.
|
113
|
-
# (default) or `post`
|
114
|
-
# @!attribute [rw] encryption_algorithm
|
115
|
-
# will be used to sign the JWT client credentials.
|
116
|
-
# (default) or `rs384`
|
117
|
-
# @!attribute [rw] kid
|
118
|
-
#
|
119
|
-
# encryption algorithm will be used
|
120
|
-
# @!attribute [rw] jwks
|
121
|
-
# instead of Inferno's default JWKS if provided
|
111
|
+
# @!attribute [rw] pkce_support
|
112
|
+
# Whether PKCE will be used during authorization. Either `enabled` or `disabled`.
|
113
|
+
# @!attribute [rw] pkce_code_challenge_method
|
114
|
+
# Either `S256` (default) or `plain`
|
115
|
+
# @!attribute [rw] auth_request_method
|
116
|
+
# The http method which will be used to perform the request to the authorization endpoint.
|
117
|
+
# Either `get` (default) or `post`
|
118
|
+
# @!attribute [rw] encryption_algorithm
|
119
|
+
# The encryption algorithm which will be used to sign the JWT client credentials.
|
120
|
+
# Either `es384` (default) or `rs384`
|
121
|
+
# @!attribute [rw] kid
|
122
|
+
# The key id for the keys to be used to sign the JWT client credentials.
|
123
|
+
# When blank, the first key for the selected encryption algorithm will be used
|
124
|
+
# @!attribute [rw] jwks
|
125
|
+
# A JWKS (including private keys) which will be used instead of Inferno's default JWKS if provided
|
122
126
|
# @!attribute [rw] access_token
|
123
127
|
# @!attribute [rw] refresh_token
|
124
|
-
# @!attribute [rw] issue_time
|
125
|
-
# time the access token was issued
|
126
|
-
# @!attribute [rw] expires_in
|
128
|
+
# @!attribute [rw] issue_time
|
129
|
+
# An iso8601 formatted string representing the time the access token was issued
|
130
|
+
# @!attribute [rw] expires_in
|
131
|
+
# The lifetime of the access token in seconds
|
127
132
|
# @!attribute [rw] name
|
128
133
|
|
129
134
|
# @private
|
@@ -118,8 +118,8 @@ module Inferno
|
|
118
118
|
end
|
119
119
|
|
120
120
|
# @private
|
121
|
-
def method_missing(name,
|
122
|
-
return runnable.send(name,
|
121
|
+
def method_missing(name, ...)
|
122
|
+
return runnable.send(name, ...) if runnable.respond_to? name
|
123
123
|
|
124
124
|
super
|
125
125
|
end
|
@@ -73,19 +73,23 @@ module Inferno
|
|
73
73
|
# there is no check that the fields are correct.
|
74
74
|
#
|
75
75
|
# @example
|
76
|
+
# # Passing fields in a block
|
76
77
|
# fhir_resource_validator do
|
77
78
|
# url 'http://example.com/validator'
|
78
79
|
# cli_context do
|
79
80
|
# noExtensibleBindingMessages true
|
81
|
+
# allowExampleUrls true
|
80
82
|
# txServer nil
|
81
83
|
# end
|
82
84
|
# end
|
83
85
|
#
|
84
86
|
# @example
|
87
|
+
# # Passing fields in a Hash
|
85
88
|
# fhir_resource_validator do
|
86
89
|
# url 'http://example.org/validator'
|
87
90
|
# cli_context({
|
88
91
|
# noExtensibleBindingMessages: true,
|
92
|
+
# allowExampleUrls: true,
|
89
93
|
# txServer: nil
|
90
94
|
# })
|
91
95
|
# end
|
@@ -44,8 +44,8 @@ module Inferno
|
|
44
44
|
end
|
45
45
|
|
46
46
|
# @private
|
47
|
-
def method_missing(name,
|
48
|
-
return runnable.send(name,
|
47
|
+
def method_missing(name, ...)
|
48
|
+
return runnable.send(name, ...) if runnable.respond_to? name
|
49
49
|
|
50
50
|
super
|
51
51
|
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Inferno
|
2
|
+
module DSL
|
3
|
+
# This module contains methods to add test suite links which are displayed in the footer of the UI
|
4
|
+
module Links
|
5
|
+
DEFAULT_TYPES = {
|
6
|
+
'report_issue' => 'Report Issue',
|
7
|
+
'source_code' => 'Open Source',
|
8
|
+
'download' => 'Download',
|
9
|
+
'ig' => 'Implementation Guide'
|
10
|
+
}.freeze
|
11
|
+
|
12
|
+
# Set/get a list of links which are displayed in the footer of the UI.
|
13
|
+
#
|
14
|
+
# @param links [Array<Hash>] A list of Hashes for the links to be
|
15
|
+
# displayed. Each hash needs a `type:`, `label:`, and `url:` entry.
|
16
|
+
# Default types: `report_issue`, `source_code`, `download`, or `ig`.
|
17
|
+
#
|
18
|
+
# @return [Array<Hash>] an array of hashes or an empty array
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# links [
|
22
|
+
# {
|
23
|
+
# type: 'report_issue',
|
24
|
+
# label: 'Report Issue',
|
25
|
+
# url: 'https://github.com/onc-healthit/onc-certification-g10-test-kit/issues/'
|
26
|
+
# },
|
27
|
+
# {
|
28
|
+
# type: 'source_code'
|
29
|
+
# label: 'Open Source',
|
30
|
+
# url: 'https://github.com/onc-healthit/onc-certification-g10-test-kit/'
|
31
|
+
# }
|
32
|
+
# ]
|
33
|
+
def links(links = nil)
|
34
|
+
@links ||= []
|
35
|
+
return @links if links.nil?
|
36
|
+
|
37
|
+
@links.concat(links)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Add a link to the test suit links list.
|
41
|
+
#
|
42
|
+
# @param type [String] The type of the link. Default types: report_issue, source_code, download, or ig.
|
43
|
+
# Custom types are also allowed.
|
44
|
+
# @param label [String] The label for the link, describing its purpose.
|
45
|
+
# @param url [String] The URL the link points to.
|
46
|
+
# @return [Array<Hash>] The updated array of links.
|
47
|
+
#
|
48
|
+
# @example
|
49
|
+
# add_link('source_code', 'Source Code', 'https://github.com/onc-healthit/onc-certification-g10-test-kit/')
|
50
|
+
# add_link('custom_type', 'Custom Link', 'https://custom-link.com')
|
51
|
+
def add_link(type, label, url)
|
52
|
+
links << { type:, label:, url: }
|
53
|
+
end
|
54
|
+
|
55
|
+
# Add a link to the source code repository.
|
56
|
+
#
|
57
|
+
# @param url [String] The URL to the source code repository.
|
58
|
+
# @param label [String] (optional) A custom label for the link.
|
59
|
+
# @return [Array<Hash>] The updated array of links.
|
60
|
+
def source_code_url(url, label: nil)
|
61
|
+
add_predefined_link('source_code', url, label)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Add a link to the implementation guide.
|
65
|
+
#
|
66
|
+
# @param url [String] The URL to the implementation guide.
|
67
|
+
# @param label [String] (optional) A custom label for the link.
|
68
|
+
# @return [Array<Hash>] The updated array of links.
|
69
|
+
def ig_url(url, label: nil)
|
70
|
+
add_predefined_link('ig', url, label)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Add a link to the latest release version of the test kit.
|
74
|
+
#
|
75
|
+
# @param url [String] The URL to the latest release version of the test kit.
|
76
|
+
# @param label [String] (optional) A custom label for the link.
|
77
|
+
# @return [Array<Hash>] The updated array of links.
|
78
|
+
def download_url(url, label: nil)
|
79
|
+
add_predefined_link('download', url, label)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Add a link to report an issue in the footer of the UI.
|
83
|
+
#
|
84
|
+
# @param url [String] The URL for reporting an issue.
|
85
|
+
# @param label [String] (optional) A custom label for the link.
|
86
|
+
# @return [Array<Hash>] The updated array of links.
|
87
|
+
def report_issue_url(url, label: nil)
|
88
|
+
add_predefined_link('report_issue', url, label)
|
89
|
+
end
|
90
|
+
|
91
|
+
# @private
|
92
|
+
def add_predefined_link(type, url, label = nil)
|
93
|
+
label ||= DEFAULT_TYPES[type]
|
94
|
+
raise ArgumentError, "Invalid link type: #{type}" unless label
|
95
|
+
|
96
|
+
add_link(type, label, url)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/inferno/dsl/runnable.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require_relative 'configurable'
|
2
2
|
require_relative 'input_output_handling'
|
3
3
|
require_relative 'resume_test_route'
|
4
|
+
require_relative '../exceptions'
|
4
5
|
require_relative '../utils/markdown_formatter'
|
5
6
|
|
6
7
|
module Inferno
|
@@ -200,7 +201,11 @@ module Inferno
|
|
200
201
|
|
201
202
|
@base_id = new_id || @base_id || default_id
|
202
203
|
|
203
|
-
|
204
|
+
final_id = "#{prefix}#{@base_id}"
|
205
|
+
|
206
|
+
raise Exceptions::InvalidRunnableIdException, final_id if final_id.length > 255
|
207
|
+
|
208
|
+
@id = final_id
|
204
209
|
end
|
205
210
|
|
206
211
|
# Set/Get a runnable's title
|
@@ -44,10 +44,10 @@ module Inferno
|
|
44
44
|
end
|
45
45
|
|
46
46
|
# @private
|
47
|
-
def method_missing(name,
|
47
|
+
def method_missing(name, ...)
|
48
48
|
parent_instance = self.class.parent&.new
|
49
49
|
if parent_instance.respond_to?(name)
|
50
|
-
parent_instance.send(name,
|
50
|
+
parent_instance.send(name, ...)
|
51
51
|
else
|
52
52
|
super
|
53
53
|
end
|
@@ -133,10 +133,10 @@ module Inferno
|
|
133
133
|
end
|
134
134
|
|
135
135
|
# @private
|
136
|
-
def method_missing(name,
|
136
|
+
def method_missing(name, ...)
|
137
137
|
parent_instance = parent&.new
|
138
138
|
if parent_instance.respond_to?(name)
|
139
|
-
parent_instance.send(name,
|
139
|
+
parent_instance.send(name, ...)
|
140
140
|
else
|
141
141
|
super
|
142
142
|
end
|
@@ -25,10 +25,10 @@ module Inferno
|
|
25
25
|
end
|
26
26
|
|
27
27
|
# @private
|
28
|
-
def method_missing(name,
|
28
|
+
def method_missing(name, ...)
|
29
29
|
parent_instance = self.class.parent&.new
|
30
30
|
if parent_instance.respond_to?(name)
|
31
|
-
parent_instance.send(name,
|
31
|
+
parent_instance.send(name, ...)
|
32
32
|
else
|
33
33
|
super
|
34
34
|
end
|
@@ -2,6 +2,7 @@ require_relative 'test_group'
|
|
2
2
|
require_relative '../dsl/runnable'
|
3
3
|
require_relative '../dsl/suite_option'
|
4
4
|
require_relative '../dsl/messages'
|
5
|
+
require_relative '../dsl/links'
|
5
6
|
require_relative '../repositories/test_groups'
|
6
7
|
require_relative '../repositories/test_suites'
|
7
8
|
require_relative '../result_collection'
|
@@ -12,6 +13,7 @@ module Inferno
|
|
12
13
|
# single Implementation Guide
|
13
14
|
class TestSuite
|
14
15
|
extend DSL::Runnable
|
16
|
+
extend DSL::Links
|
15
17
|
extend DSL::FHIRClient::ClassMethods
|
16
18
|
extend DSL::HTTPClient::ClassMethods
|
17
19
|
include DSL::FHIRValidation
|
@@ -173,30 +175,6 @@ module Inferno
|
|
173
175
|
@suite_options ||= []
|
174
176
|
end
|
175
177
|
|
176
|
-
# Set/get a list of links which are displayed in the footer of the UI.
|
177
|
-
#
|
178
|
-
# @param links [Array<Hash>] A list of Hashes for the links to be
|
179
|
-
# displayed. Each hash needs a `label:` and `url:` entry.
|
180
|
-
#
|
181
|
-
# @return [Array<Hash>, nil]
|
182
|
-
#
|
183
|
-
# @example
|
184
|
-
# links [
|
185
|
-
# {
|
186
|
-
# label: 'Report Issue',
|
187
|
-
# url: 'https://github.com/onc-healthit/onc-certification-g10-test-kit/issues/'
|
188
|
-
# },
|
189
|
-
# {
|
190
|
-
# label: 'Open Source',
|
191
|
-
# url: 'https://github.com/onc-healthit/onc-certification-g10-test-kit/'
|
192
|
-
# }
|
193
|
-
# ]
|
194
|
-
def links(links = nil)
|
195
|
-
return @links if links.nil?
|
196
|
-
|
197
|
-
@links = links
|
198
|
-
end
|
199
|
-
|
200
178
|
# Set/get a description which for this test suite which will be
|
201
179
|
# displayed in the UI.
|
202
180
|
#
|
data/lib/inferno/exceptions.rb
CHANGED
@@ -113,5 +113,11 @@ module Inferno
|
|
113
113
|
super("Expected '#{name}' to be a #{expected_class_names}, but found a #{actual_class.name}.")
|
114
114
|
end
|
115
115
|
end
|
116
|
+
|
117
|
+
class InvalidRunnableIdException < StandardError
|
118
|
+
def initialize(id)
|
119
|
+
super("ID '#{id}' exceeds the maximum id length of 255 characters")
|
120
|
+
end
|
121
|
+
end
|
116
122
|
end
|
117
123
|
end
|
@@ -7,7 +7,7 @@ module InfernoFHIRModelExtensions
|
|
7
7
|
attr_accessor :source_hash, :source_text
|
8
8
|
|
9
9
|
def initialize(hash = {})
|
10
|
-
super
|
10
|
+
super
|
11
11
|
@source_hash = hash
|
12
12
|
end
|
13
13
|
|
@@ -26,7 +26,7 @@ end
|
|
26
26
|
# allows us to call super() on from_json
|
27
27
|
module InfernoJson
|
28
28
|
def from_json(json)
|
29
|
-
resource = super
|
29
|
+
resource = super
|
30
30
|
resource&.source_text = json
|
31
31
|
resource
|
32
32
|
end
|
@@ -36,7 +36,7 @@ end
|
|
36
36
|
# allows us to call super() on from_xml
|
37
37
|
module InfernoXml
|
38
38
|
def from_xml(xml)
|
39
|
-
resource = super
|
39
|
+
resource = super
|
40
40
|
resource&.source_text = xml
|
41
41
|
resource
|
42
42
|
end
|
data/lib/inferno/jobs.rb
CHANGED
@@ -6,11 +6,11 @@ require_relative 'jobs/invoke_validator_session'
|
|
6
6
|
|
7
7
|
module Inferno
|
8
8
|
module Jobs
|
9
|
-
def self.perform(job_klass, *params)
|
10
|
-
if Application['async_jobs']
|
11
|
-
job_klass.perform_async(*params)
|
12
|
-
else
|
9
|
+
def self.perform(job_klass, *params, force_synchronous: false)
|
10
|
+
if force_synchronous || (Application['async_jobs'] == false)
|
13
11
|
job_klass.new.perform(*params)
|
12
|
+
else
|
13
|
+
job_klass.perform_async(*params)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
"use strict";(self.webpackChunkinferno_web_app=self.webpackChunkinferno_web_app||[]).push([[237],{237:(e,n,t)=>{t.r(n),t.d(n,{CLSThresholds:()=>P,FCPThresholds:()=>w,FIDThresholds:()=>ne,INPThresholds:()=>j,LCPThresholds:()=>G,TTFBThresholds:()=>Q,onCLS:()=>A,onFCP:()=>I,onFID:()=>te,onINP:()=>z,onLCP:()=>K,onTTFB:()=>V});var r,i,o,a,c,u=-1,s=function(e){addEventListener("pageshow",(function(n){n.persisted&&(u=n.timeStamp,e(n))}),!0)},f=function(){var e=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e},d=function(){var e=f();return e&&e.activationStart||0},l=function(e,n){var t=f(),r="navigate";return u>=0?r="back-forward-cache":t&&(document.prerendering||d()>0?r="prerender":document.wasDiscarded?r="restore":t.type&&(r=t.type.replace(/_/g,"-"))),{name:e,value:void 0===n?-1:n,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:r}},p=function(e,n,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){var r=new PerformanceObserver((function(e){Promise.resolve().then((function(){n(e.getEntries())}))}));return r.observe(Object.assign({type:e,buffered:!0},t||{})),r}}catch(e){}},v=function(e,n,t,r){var i,o;return function(a){n.value>=0&&(a||r)&&((o=n.value-(i||0))||void 0===i)&&(i=n.value,n.delta=o,n.rating=function(e,n){return e>n[1]?"poor":e>n[0]?"needs-improvement":"good"}(n.value,t),e(n))}},m=function(e){requestAnimationFrame((function(){return requestAnimationFrame((function(){return e()}))}))},h=function(e){document.addEventListener("visibilitychange",(function(){"hidden"===document.visibilityState&&e()}))},g=function(e){var n=!1;return function(){n||(e(),n=!0)}},T=-1,y=function(){return"hidden"!==document.visibilityState||document.prerendering?1/0:0},E=function(e){"hidden"===document.visibilityState&&T>-1&&(T="visibilitychange"===e.type?e.timeStamp:0,b())},C=function(){addEventListener("visibilitychange",E,!0),addEventListener("prerenderingchange",E,!0)},b=function(){removeEventListener("visibilitychange",E,!0),removeEventListener("prerenderingchange",E,!0)},L=function(){return T<0&&(T=y(),C(),s((function(){setTimeout((function(){T=y(),C()}),0)}))),{get firstHiddenTime(){return T}}},S=function(e){document.prerendering?addEventListener("prerenderingchange",(function(){return e()}),!0):e()},w=[1800,3e3],I=function(e,n){n=n||{},S((function(){var t,r=L(),i=l("FCP"),o=p("paint",(function(e){e.forEach((function(e){"first-contentful-paint"===e.name&&(o.disconnect(),e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-d(),0),i.entries.push(e),t(!0)))}))}));o&&(t=v(e,i,w,n.reportAllChanges),s((function(r){i=l("FCP"),t=v(e,i,w,n.reportAllChanges),m((function(){i.value=performance.now()-r.timeStamp,t(!0)}))})))}))},P=[.1,.25],A=function(e,n){n=n||{},I(g((function(){var t,r=l("CLS",0),i=0,o=[],a=function(e){e.forEach((function(e){if(!e.hadRecentInput){var n=o[0],t=o[o.length-1];i&&e.startTime-t.startTime<1e3&&e.startTime-n.startTime<5e3?(i+=e.value,o.push(e)):(i=e.value,o=[e])}})),i>r.value&&(r.value=i,r.entries=o,t())},c=p("layout-shift",a);c&&(t=v(e,r,P,n.reportAllChanges),h((function(){a(c.takeRecords()),t(!0)})),s((function(){i=0,r=l("CLS",0),t=v(e,r,P,n.reportAllChanges),m((function(){return t()}))})),setTimeout(t,0))})))},F=0,k=1/0,M=0,D=function(e){e.forEach((function(e){e.interactionId&&(k=Math.min(k,e.interactionId),M=Math.max(M,e.interactionId),F=M?(M-k)/7+1:0)}))},B=function(){return r?F:performance.interactionCount||0},R=function(){"interactionCount"in performance||r||(r=p("event",D,{type:"event",buffered:!0,durationThreshold:0}))},_=[],x=new Map,H=0,N=[],q=function(e){if(N.forEach((function(n){return n(e)})),e.interactionId||"first-input"===e.entryType){var n=_[_.length-1],t=x.get(e.interactionId);if(t||_.length<10||e.duration>n.latency){if(t)e.duration>t.latency?(t.entries=[e],t.latency=e.duration):e.duration===t.latency&&e.startTime===t.entries[0].startTime&&t.entries.push(e);else{var r={id:e.interactionId,latency:e.duration,entries:[e]};x.set(r.id,r),_.push(r)}_.sort((function(e,n){return n.latency-e.latency})),_.length>10&&_.splice(10).forEach((function(e){return x.delete(e.id)}))}}},O=function(e){var n=self.requestIdleCallback||self.setTimeout,t=-1;return e=g(e),"hidden"===document.visibilityState?e():(t=n(e),h(e)),t},j=[200,500],z=function(e,n){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(n=n||{},S((function(){var t;R();var r,i=l("INP"),o=function(e){O((function(){e.forEach(q);var n=function(){var e=Math.min(_.length-1,Math.floor((B()-H)/50));return _[e]}();n&&n.latency!==i.value&&(i.value=n.latency,i.entries=n.entries,r())}))},a=p("event",o,{durationThreshold:null!==(t=n.durationThreshold)&&void 0!==t?t:40});r=v(e,i,j,n.reportAllChanges),a&&(a.observe({type:"first-input",buffered:!0}),h((function(){o(a.takeRecords()),r(!0)})),s((function(){H=B(),_.length=0,x.clear(),i=l("INP"),r=v(e,i,j,n.reportAllChanges)})))})))},G=[2500,4e3],J={},K=function(e,n){n=n||{},S((function(){var t,r=L(),i=l("LCP"),o=function(e){n.reportAllChanges||(e=e.slice(-1)),e.forEach((function(e){e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-d(),0),i.entries=[e],t())}))},a=p("largest-contentful-paint",o);if(a){t=v(e,i,G,n.reportAllChanges);var c=g((function(){J[i.id]||(o(a.takeRecords()),a.disconnect(),J[i.id]=!0,t(!0))}));["keydown","click"].forEach((function(e){addEventListener(e,(function(){return O(c)}),!0)})),h(c),s((function(r){i=l("LCP"),t=v(e,i,G,n.reportAllChanges),m((function(){i.value=performance.now()-r.timeStamp,J[i.id]=!0,t(!0)}))}))}}))},Q=[800,1800],U=function e(n){document.prerendering?S((function(){return e(n)})):"complete"!==document.readyState?addEventListener("load",(function(){return e(n)}),!0):setTimeout(n,0)},V=function(e,n){n=n||{};var t=l("TTFB"),r=v(e,t,Q,n.reportAllChanges);U((function(){var i=f();i&&(t.value=Math.max(i.responseStart-d(),0),t.entries=[i],r(!0),s((function(){t=l("TTFB",0),(r=v(e,t,Q,n.reportAllChanges))(!0)})))}))},W={passive:!0,capture:!0},X=new Date,Y=function(e,n){i||(i=n,o=e,a=new Date,ee(removeEventListener),Z())},Z=function(){if(o>=0&&o<a-X){var e={entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+o};c.forEach((function(n){n(e)})),c=[]}},$=function(e){if(e.cancelable){var n=(e.timeStamp>1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,n){var t=function(){Y(e,n),i()},r=function(){i()},i=function(){removeEventListener("pointerup",t,W),removeEventListener("pointercancel",r,W)};addEventListener("pointerup",t,W),addEventListener("pointercancel",r,W)}(n,e):Y(n,e)}},ee=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return e(n,$,W)}))},ne=[100,300],te=function(e,n){n=n||{},S((function(){var t,r=L(),a=l("FID"),u=function(e){e.startTime<r.firstHiddenTime&&(a.value=e.processingStart-e.startTime,a.entries.push(e),t(!0))},f=function(e){e.forEach(u)},d=p("first-input",f);t=v(e,a,ne,n.reportAllChanges),d&&(h(g((function(){f(d.takeRecords()),d.disconnect()}))),s((function(){var r;a=l("FID"),t=v(e,a,ne,n.reportAllChanges),c=[],o=-1,i=null,ee(addEventListener),r=u,c.push(r),Z()})))}))}}}]);
|