inferno_core 0.1.3.pre → 0.1.4.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/lib/inferno/apps/cli/main.rb +10 -0
  3. data/lib/inferno/apps/cli/suite.rb +19 -0
  4. data/lib/inferno/apps/cli/suite_input_template.rb +30 -0
  5. data/lib/inferno/apps/cli/suites.rb +23 -0
  6. data/lib/inferno/apps/web/controllers/test_sessions/create.rb +5 -2
  7. data/lib/inferno/apps/web/controllers/test_sessions/session_data/apply_preset.rb +43 -0
  8. data/lib/inferno/apps/web/controllers/test_suites/check_configuration.rb +17 -0
  9. data/lib/inferno/apps/web/index.html.erb +5 -5
  10. data/lib/inferno/apps/web/router.rb +38 -25
  11. data/lib/inferno/apps/web/serializers/preset.rb +17 -0
  12. data/lib/inferno/apps/web/serializers/test.rb +2 -0
  13. data/lib/inferno/apps/web/serializers/test_group.rb +1 -0
  14. data/lib/inferno/apps/web/serializers/test_suite.rb +3 -0
  15. data/lib/inferno/config/application.rb +9 -1
  16. data/lib/inferno/config/boot/db.rb +16 -1
  17. data/lib/inferno/config/boot/presets.rb +15 -0
  18. data/lib/inferno/db/schema.rb +22 -22
  19. data/lib/inferno/dsl/oauth_credentials.rb +1 -1
  20. data/lib/inferno/dsl/resume_test_route.rb +1 -1
  21. data/lib/inferno/dsl/runnable.rb +18 -0
  22. data/lib/inferno/entities/preset.rb +24 -0
  23. data/lib/inferno/entities/test.rb +8 -0
  24. data/lib/inferno/entities/test_group.rb +8 -0
  25. data/lib/inferno/entities/test_suite.rb +31 -0
  26. data/lib/inferno/public/bundle.js +38 -38
  27. data/lib/inferno/repositories/in_memory_repository.rb +3 -2
  28. data/lib/inferno/repositories/presets.rb +22 -0
  29. data/lib/inferno/repositories/session_data.rb +1 -1
  30. data/lib/inferno/repositories/test_sessions.rb +12 -1
  31. data/lib/inferno/utils/preset_template_generator.rb +38 -0
  32. data/lib/inferno/utils/static_assets.rb +33 -0
  33. data/lib/inferno/version.rb +1 -1
  34. data/lib/inferno.rb +7 -6
  35. metadata +20 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e77fe0b6b1077a64dce0244964847c57ed6c57aa6a388bae212658f300563486
4
- data.tar.gz: 52259f5560f7838e1d9c3763cff3a7686b0be12601e3e2cd5f5b7e9e380d6050
3
+ metadata.gz: 01e79c40f1051646f284439abdf537dfff524de78fee0837511b66681e997e16
4
+ data.tar.gz: '00759057270c563dc193cc76ecd869febfd767fa3ac4de51de0dc000f74103e5'
5
5
  SHA512:
6
- metadata.gz: 38665e97697ea4bb570d7721197e05f16345e8e09b05fb2d573b10ed3b25cde28734433e9bf2be8cc874beaa9849c379e10acf70310e3aea7df00941fad8216f
7
- data.tar.gz: fd44ae1fb46bac9358cc7b0b8a444bd1dcdf545fbd75588afc10d175f489601c6b2211d143f7387119bf6ac363644dfe9984b9e706efaf2fe4968b147ce479c2
6
+ metadata.gz: 89b46a4683518f552a13f62d6ef241af0feb31d93eefaa8553576ba0242fca2c85a316f81513034bcb48cf4a0644c3aabd1ab165e84b39faebb8f97913f487c7
7
+ data.tar.gz: 728d39ce5ef5c407d232912f9c09ab89b1b4bf7c33290fdc9200d4ccea3185b0a6ec7007c6ad6fd0e92c15ba80b94440658c26d57a0f36ba253e4566abd0bfc4
@@ -1,5 +1,7 @@
1
1
  require_relative 'console'
2
2
  require_relative 'migration'
3
+ require_relative 'suite'
4
+ require_relative 'suites'
3
5
 
4
6
  module Inferno
5
7
  module CLI
@@ -13,6 +15,14 @@ module Inferno
13
15
  def migrate
14
16
  Migration.new.run
15
17
  end
18
+
19
+ desc 'suites', 'List available test suites'
20
+ def suites
21
+ Suites.new.run
22
+ end
23
+
24
+ desc 'suite SUBCOMMAND ...ARGS', 'Perform suite-based operations'
25
+ subcommand 'suite', Suite
16
26
  end
17
27
  end
18
28
  end
@@ -0,0 +1,19 @@
1
+ require_relative 'suite_input_template'
2
+
3
+ module Inferno
4
+ module CLI
5
+ class Suite < Thor
6
+ desc 'input_template SUITE_ID', 'Create a template for preset inputs'
7
+ long_desc <<~LONGDESC
8
+ Generates a template for creating an input preset for a Test Suite.
9
+
10
+ With -f option, the preset template is written to the specified
11
+ filename.
12
+ LONGDESC
13
+ option :filename, banner: '<filename>', aliases: [:f]
14
+ def input_template(suite_id)
15
+ SuiteInputTemplate.new.run(suite_id, options)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ require_relative '../../utils/preset_template_generator'
2
+
3
+ module Inferno
4
+ module CLI
5
+ class SuiteInputTemplate
6
+ def run(suite_id, options)
7
+ require_relative '../../../inferno'
8
+
9
+ Inferno::Application.start(:suites)
10
+
11
+ suite = Inferno::Repositories::TestSuites.new.find(suite_id)
12
+ if suite.nil?
13
+ puts "No Test Suite found with id: #{suite_id}"
14
+ return 1
15
+ end
16
+
17
+ output = JSON.pretty_generate(Inferno::Utils::PresetTemplateGenerator.new(suite).generate)
18
+
19
+ if options[:filename].present?
20
+ path = File.join(Dir.pwd, 'config', 'presets', options[:filename])
21
+ FileUtils.mkdir_p(File.dirname(path))
22
+
23
+ File.open(path, 'w') { |f| f.puts(output) }
24
+ else
25
+ puts output
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ module Inferno
2
+ module CLI
3
+ class Suites
4
+ def run
5
+ require_relative '../../../inferno'
6
+
7
+ Inferno::Application.start(:suites)
8
+
9
+ suites = Inferno::Repositories::TestSuites.new.all
10
+ suite_hash = suites.each_with_object({}) { |suite, hash| hash[suite.id] = suite.title }
11
+
12
+ id_column_length = suite_hash.keys.map(&:length).max + 1
13
+ title_column_length = suite_hash.values.map(&:length).max
14
+
15
+ puts "#{'ID'.ljust(id_column_length)}| Title"
16
+ puts "#{'-' * id_column_length}+-#{'-' * title_column_length}"
17
+ suite_hash.each do |id, title|
18
+ puts "#{id.ljust(id_column_length)}| #{title}"
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -6,8 +6,11 @@ module Inferno
6
6
  PARAMS = [:test_suite_id].freeze
7
7
 
8
8
  def call(params)
9
- result = repo.create(create_params(params))
10
- self.body = serialize(result)
9
+ session = repo.create(create_params(params))
10
+
11
+ repo.apply_preset(session.id, params[:preset_id]) if params[:preset_id].present?
12
+
13
+ self.body = serialize(session)
11
14
  rescue Sequel::ValidationFailed, Sequel::ForeignKeyConstraintViolation => e
12
15
  self.body = { errors: e.message }.to_json
13
16
  self.status = 422
@@ -0,0 +1,43 @@
1
+ module Inferno
2
+ module Web
3
+ module Controllers
4
+ module TestSessions
5
+ module SessionData
6
+ class ApplyPreset < Controller
7
+ include Import[
8
+ test_sessions_repo: 'repositories.test_sessions',
9
+ presets_repo: 'repositories.presets'
10
+ ]
11
+
12
+ def self.resource_class
13
+ 'SessionData'
14
+ end
15
+
16
+ def call(params)
17
+ test_session_id = params[:test_session_id]
18
+ test_session = test_sessions_repo.find(test_session_id)
19
+
20
+ if test_session.nil?
21
+ Application[:logger].error("Unknown test session #{test_session_id}")
22
+ self.status = 404
23
+ return
24
+ end
25
+
26
+ preset_id = params[:preset_id]
27
+ preset = presets_repo.find(preset_id)
28
+
29
+ if preset.nil?
30
+ Application[:logger].error("Unknown preset #{preset_id}")
31
+ self.status = 404
32
+ return
33
+ end
34
+
35
+ test_sessions_repo.apply_preset(test_session_id, preset_id)
36
+ self.status = 200
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,17 @@
1
+ module Inferno
2
+ module Web
3
+ module Controllers
4
+ module TestSuites
5
+ class CheckConfiguration < Controller
6
+ def call(params)
7
+ test_suite = repo.find(params[:id])
8
+ halt 404 if test_suite.nil?
9
+
10
+ self.body =
11
+ Inferno::Web::Serializers::Message.render(test_suite.configuration_messages(force_recheck: true))
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,21 +1,21 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
3
  <head>
4
- <base href="/">
5
4
  <meta charset="utf-8" />
6
- <link rel="icon" href="/public/favicon.ico" />
5
+ <link rel="icon" href="<%= Inferno::Application['public_path'] %>/favicon.ico" />
7
6
  <meta name="viewport" content="width=device-width, initial-scale=1" />
8
7
  <meta name="theme-color" content="#000000" />
8
+ <meta id="base-path" name="base-path" content="<%= Inferno::Application['base_path'] %>">
9
9
  <meta
10
10
  name="description"
11
11
  content="FHIR Testing"
12
12
  />
13
- <link rel="apple-touch-icon" href="/public/logo192.png" />
13
+ <link rel="apple-touch-icon" href="<%= Inferno::Application['public_path'] %>/logo192.png" />
14
14
  <!--
15
15
  manifest.json provides metadata used when your web app is installed on a
16
16
  user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
17
17
  -->
18
- <link rel="manifest" href="/public/manifest.json" />
18
+ <link rel="manifest" href="<%= Inferno::Application['public_path'] %>/manifest.json" />
19
19
  <!--
20
20
  Notice the use of %PUBLIC_URL% in the tags above.
21
21
  It will be replaced with the URL of the `public` folder during the build.
@@ -40,6 +40,6 @@
40
40
  To begin the development, run `npm start` or `yarn start`.
41
41
  To create a production bundle, use `npm run build` or `yarn build`.
42
42
  -->
43
- <script src='<%= Inferno::Application['js_host'] %>/public/bundle.js'></script>
43
+ <script src='<%= Inferno::Application['js_host'] %>/bundle.js'></script>
44
44
  </body>
45
45
  </html>
@@ -6,35 +6,48 @@ module Inferno
6
6
  'index.html.erb'))).result
7
7
 
8
8
  Router = Hanami::Router.new(namespace: Inferno::Web::Controllers) do
9
- namespace 'api' do
10
- resources 'test_runs', only: [:create, :show, :destroy] do
11
- resources 'results', only: [:index]
12
- end
9
+ namespace Application['base_path'] do
10
+ namespace 'api' do
11
+ resources 'test_runs', only: [:create, :show, :destroy] do
12
+ resources 'results', only: [:index]
13
+ end
13
14
 
14
- resources 'test_sessions', only: [:create, :show] do
15
- resources 'results', only: [:index]
16
- resources 'session_data', only: [:index]
17
- end
18
- get 'test_sessions/:test_session_id/last_test_run',
19
- to: Inferno::Web::Controllers::TestSessions::LastTestRun,
20
- as: :last_test_run
15
+ resources 'test_sessions', only: [:create, :show] do
16
+ resources 'results', only: [:index]
17
+ resources 'session_data', only: [:index] do
18
+ collection do
19
+ put '/apply_preset',
20
+ to: Inferno::Web::Controllers::TestSessions::SessionData::ApplyPreset,
21
+ as: :apply_preset
22
+ end
23
+ end
24
+ end
25
+ get 'test_sessions/:test_session_id/last_test_run',
26
+ to: Inferno::Web::Controllers::TestSessions::LastTestRun,
27
+ as: :last_test_run
21
28
 
22
- resources 'test_suites', only: [:index, :show]
29
+ resources 'test_suites', only: [:index, :show]
30
+ put 'test_suites/:id/check_configuration',
31
+ to: Inferno::Web::Controllers::TestSuites::CheckConfiguration,
32
+ as: :check_configuration
23
33
 
24
- resources 'requests', only: [:show]
25
- end
34
+ resources 'requests', only: [:show]
35
+
36
+ get '/version', to: ->(_env) { [200, {}, [{ 'version' => Inferno::VERSION.to_s }.to_json]] }, as: :api_version
37
+ end
38
+
39
+ get '/', to: ->(_env) { [200, {}, [client_page]] }
40
+ get '/test_sessions/:id', to: ->(_env) { [200, {}, [client_page]] }
26
41
 
27
- get '/', to: ->(_env) { [200, {}, [client_page]] }
28
- get '/test_sessions/:id', to: ->(_env) { [200, {}, [client_page]] }
29
-
30
- Inferno.routes.each do |route|
31
- cleaned_id = route[:suite].id.gsub(/[^a-zA-Z\d\-._~]/, '_')
32
- path = "/custom/#{cleaned_id}#{route[:path]}"
33
- Application['logger'].info("Registering custom route: #{path}")
34
- if route[:method] == :all
35
- mount route[:handler], at: path
36
- else
37
- send(route[:method], path, to: route[:handler])
42
+ Inferno.routes.each do |route|
43
+ cleaned_id = route[:suite].id.gsub(/[^a-zA-Z\d\-._~]/, '_')
44
+ path = "/custom/#{cleaned_id}#{route[:path]}"
45
+ Application['logger'].info("Registering custom route: #{path}")
46
+ if route[:method] == :all
47
+ mount route[:handler], at: path
48
+ else
49
+ send(route[:method], path, to: route[:handler])
50
+ end
38
51
  end
39
52
  end
40
53
  end
@@ -0,0 +1,17 @@
1
+ module Inferno
2
+ module Web
3
+ module Serializers
4
+ class Preset < Serializer
5
+ view :summary do
6
+ identifier :id
7
+ field :title
8
+ end
9
+
10
+ # view :full do
11
+ # include_view :summary
12
+ # field :inputs, blueprint: Input
13
+ # end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -3,6 +3,8 @@ module Inferno
3
3
  module Serializers
4
4
  class Test < Serializer
5
5
  identifier :id
6
+
7
+ field :short_id
6
8
  field :title
7
9
  field :short_title
8
10
  field :input_definitions, name: :inputs, extractor: HashValueExtractor, blueprint: Input
@@ -4,6 +4,7 @@ module Inferno
4
4
  class TestGroup < Serializer
5
5
  identifier :id
6
6
 
7
+ field :short_id
7
8
  field :title
8
9
  field :short_title
9
10
  field :description
@@ -10,11 +10,14 @@ module Inferno
10
10
  field :short_description
11
11
  field :input_instructions
12
12
  field :test_count
13
+ field :version
14
+ association :presets, view: :summary, blueprint: Preset
13
15
  end
14
16
 
15
17
  view :full do
16
18
  include_view :summary
17
19
  association :groups, name: :test_groups, blueprint: TestGroup
20
+ field :configuration_messages
18
21
  end
19
22
  end
20
23
  end
@@ -10,9 +10,17 @@ module Inferno
10
10
 
11
11
  use :env, inferrer: -> { ENV.fetch('APP_ENV', :development).to_sym }
12
12
 
13
- Application.register('js_host', ENV.fetch('JS_HOST', ''))
13
+ raw_js_host = ENV.fetch('JS_HOST', '')
14
+ base_path = ENV.fetch('BASE_PATH', '')
15
+ public_path = base_path.blank? ? '/public' : "/#{base_path}/public"
16
+ js_host = raw_js_host.present? ? "#{raw_js_host}/public" : public_path
17
+
18
+ Application.register('js_host', js_host)
19
+ Application.register('base_path', base_path)
20
+ Application.register('public_path', public_path)
14
21
  Application.register('async_jobs', ENV['ASYNC_JOBS'] != 'false')
15
22
  Application.register('inferno_host', ENV.fetch('INFERNO_HOST', 'http://localhost:4567'))
23
+ Application.register('base_url', URI.join(Application['inferno_host'], base_path).to_s)
16
24
 
17
25
  configure do |config|
18
26
  config.root = File.expand_path('../../..', __dir__)
@@ -11,7 +11,22 @@ Inferno::Application.boot(:db) do
11
11
  config_path = File.expand_path('database.yml', File.join(Dir.pwd, 'config'))
12
12
  config = YAML.load_file(config_path)[ENV['APP_ENV']]
13
13
  .merge(logger: Inferno::Application['logger'])
14
- connection = Sequel.connect(config)
14
+ connection_attempts_remaining = ENV.fetch('MAX_DB_CONNECTION_ATTEMPTS', '10').to_i
15
+ connection_retry_delay = ENV.fetch('DB_CONNECTION_RETRY_DELAY', '5').to_i
16
+ connection = nil
17
+ loop do
18
+ connection = Sequel.connect(config)
19
+ break
20
+ rescue StandardError => e
21
+ connection_attempts_remaining -= 1
22
+ if connection_attempts_remaining.positive?
23
+ Inferno::Application['logger'].error("Unable to connect to database: #{e.message}")
24
+ Inferno::Application['logger'].error("#{connection_attempts_remaining} connection attempts remaining.")
25
+ sleep connection_retry_delay
26
+ next
27
+ end
28
+ raise
29
+ end
15
30
  connection.sql_log_level = :debug
16
31
 
17
32
  register('db.config', config)
@@ -0,0 +1,15 @@
1
+ require_relative '../../repositories/presets'
2
+
3
+ Inferno::Application.boot(:presets) do
4
+ init do
5
+ use :suites
6
+
7
+ files_to_load = Dir.glob(File.join(Dir.pwd, 'config', 'presets', '*.json'))
8
+ files_to_load.map! { |path| File.realpath(path) }
9
+ presets_repo = Inferno::Repositories::Presets.new
10
+
11
+ files_to_load.each do |path|
12
+ presets_repo.insert_from_file(path)
13
+ end
14
+ end
15
+ end
@@ -5,7 +5,7 @@ Sequel.migration do
5
5
  end
6
6
 
7
7
  create_table(:test_sessions) do
8
- String :id, :size=>255, :null=>false
8
+ String :id, :size=>36, :null=>false
9
9
  String :test_suite_id, :size=>255, :null=>false
10
10
  DateTime :created_at, :null=>false
11
11
  DateTime :updated_at, :null=>false
@@ -15,7 +15,7 @@ Sequel.migration do
15
15
 
16
16
  create_table(:session_data, :ignore_index_errors=>true) do
17
17
  String :id, :size=>255, :null=>false
18
- foreign_key :test_session_id, :test_sessions, :type=>String, :size=>255, :null=>false
18
+ foreign_key :test_session_id, :test_sessions, :type=>String, :size=>36, :null=>false, :key=>[:id]
19
19
  String :name, :size=>255, :null=>false
20
20
  String :value, :text=>true
21
21
 
@@ -25,9 +25,9 @@ Sequel.migration do
25
25
  end
26
26
 
27
27
  create_table(:test_runs, :ignore_index_errors=>true) do
28
- String :id, :size=>255, :null=>false
28
+ String :id, :size=>36, :null=>false
29
29
  String :status, :size=>255
30
- foreign_key :test_session_id, :test_sessions, :type=>String, :size=>255
30
+ foreign_key :test_session_id, :test_sessions, :type=>String, :size=>36, :key=>[:id]
31
31
  String :test_suite_id, :size=>255
32
32
  String :test_group_id, :size=>255
33
33
  String :test_id, :size=>255
@@ -47,11 +47,11 @@ Sequel.migration do
47
47
  end
48
48
 
49
49
  create_table(:results, :ignore_index_errors=>true) do
50
- String :id, :size=>255, :null=>false
51
- foreign_key :test_run_id, :test_runs, :type=>String, :size=>255, :null=>false
52
- foreign_key :test_session_id, :test_sessions, :type=>String, :size=>255, :null=>false
50
+ String :id, :size=>36, :null=>false
51
+ foreign_key :test_run_id, :test_runs, :type=>String, :size=>36, :null=>false, :key=>[:id]
52
+ foreign_key :test_session_id, :test_sessions, :type=>String, :size=>36, :null=>false, :key=>[:id]
53
53
  String :result, :size=>255
54
- String :result_message, :size=>255
54
+ String :result_message, :text=>true
55
55
  String :test_suite_id, :size=>255
56
56
  String :test_group_id, :size=>255
57
57
  String :test_id, :size=>255
@@ -72,10 +72,10 @@ Sequel.migration do
72
72
 
73
73
  create_table(:messages, :ignore_index_errors=>true) do
74
74
  primary_key :index
75
- String :id, :size=>255, :null=>false
76
- foreign_key :result_id, :results, :type=>String, :size=>255, :null=>false
75
+ String :id, :size=>36, :null=>false
76
+ foreign_key :result_id, :results, :type=>String, :size=>36, :null=>false, :key=>[:id]
77
77
  String :type, :size=>255, :null=>false
78
- String :message, :size=>255, :null=>false
78
+ String :message, :text=>true, :null=>false
79
79
  DateTime :created_at, :null=>false
80
80
  DateTime :updated_at, :null=>false
81
81
 
@@ -85,31 +85,31 @@ Sequel.migration do
85
85
 
86
86
  create_table(:requests, :ignore_index_errors=>true) do
87
87
  primary_key :index
88
- String :id, :size=>255, :null=>false
88
+ String :id, :size=>36, :null=>false
89
89
  String :verb, :size=>255, :null=>false
90
- String :url, :size=>255, :null=>false
90
+ String :url, :text=>true, :null=>false
91
91
  String :direction, :size=>255, :null=>false
92
92
  Integer :status
93
93
  String :name, :size=>255
94
94
  String :request_body, :text=>true
95
95
  String :response_body, :text=>true
96
- foreign_key :result_id, :results, :type=>String, :size=>255, :null=>false
97
- foreign_key :test_session_id, :test_sessions, :type=>String, :size=>255, :null=>false
98
- String :"[:test_session_id, :name]"
96
+ foreign_key :result_id, :results, :type=>String, :size=>36, :null=>false, :key=>[:id]
97
+ foreign_key :test_session_id, :test_sessions, :type=>String, :size=>36, :null=>false, :key=>[:id]
99
98
  DateTime :created_at, :null=>false
100
99
  DateTime :updated_at, :null=>false
101
100
 
102
- index [:id]
101
+ index [:id], :unique=>true
103
102
  index [:result_id]
104
103
  index [:test_session_id]
104
+ index [:test_session_id, :name]
105
105
  end
106
106
 
107
107
  create_table(:headers, :ignore_index_errors=>true) do
108
- String :id, :size=>255, :null=>false
109
- foreign_key :request_id, :requests, :type=>String, :size=>255, :null=>false
108
+ String :id, :size=>36, :null=>false
109
+ foreign_key :request_id, :requests, :null=>false, :key=>[:index]
110
110
  String :type, :size=>255, :null=>false
111
111
  String :name, :size=>255, :null=>false
112
- String :value, :size=>255
112
+ String :value, :text=>true
113
113
  DateTime :created_at, :null=>false
114
114
  DateTime :updated_at, :null=>false
115
115
 
@@ -118,8 +118,8 @@ Sequel.migration do
118
118
  end
119
119
 
120
120
  create_table(:requests_results, :ignore_index_errors=>true) do
121
- foreign_key :results_id, :results, :type=>String, :size=>255, :null=>false
122
- foreign_key :requests_id, :requests, :type=>String, :size=>255, :null=>false
121
+ foreign_key :results_id, :results, :type=>String, :size=>36, :null=>false, :key=>[:id]
122
+ foreign_key :requests_id, :requests, :null=>false, :key=>[:index]
123
123
 
124
124
  index [:requests_id]
125
125
  index [:results_id]
@@ -31,7 +31,7 @@ module Inferno
31
31
  instance_variable_set(:"@#{name}", value)
32
32
  end
33
33
 
34
- self.token_retrieval_time = DateTime.now if token_retrieval_time.blank?
34
+ self.token_retrieval_time = DateTime.now if access_token.present? && token_retrieval_time.blank?
35
35
  end
36
36
 
37
37
  # @api private
@@ -55,7 +55,7 @@ module Inferno
55
55
 
56
56
  # @private
57
57
  def redirect_route
58
- "/test_sessions/#{test_run.test_session_id}##{waiting_group_id}"
58
+ "#{Application['base_url']}/test_sessions/#{test_run.test_session_id}##{waiting_group_id}"
59
59
  end
60
60
 
61
61
  # @private
@@ -479,6 +479,24 @@ module Inferno
479
479
  !parent.respond_to?(:run_as_group?) ||
480
480
  (parent.user_runnable? && !parent.run_as_group?)
481
481
  end
482
+
483
+ # @private
484
+ def available_input_definitions(prior_outputs = [])
485
+ available_input_definitions =
486
+ inputs
487
+ .each_with_object({}) do |input, definitions|
488
+ definitions[config.input_name(input)] =
489
+ config.input_config(input)
490
+ end
491
+ available_input_definitions.reject! { |input, _| prior_outputs.include? input }
492
+
493
+ children_available_input_definitions =
494
+ children.each_with_object({}) do |child, definitions|
495
+ definitions.merge!(child.available_input_definitions(prior_outputs))
496
+ end
497
+ prior_outputs.concat(outputs.map { |output| config.output_name(output) })
498
+ children_available_input_definitions.merge(available_input_definitions)
499
+ end
482
500
  end
483
501
  end
484
502
  end
@@ -0,0 +1,24 @@
1
+ require_relative 'attributes'
2
+ require_relative 'entity'
3
+ require_relative 'has_runnable'
4
+
5
+ module Inferno
6
+ module Entities
7
+ # A `Preset` represents a set of input values for a runnable.
8
+ class Preset < Entity
9
+ ATTRIBUTES = [
10
+ :id,
11
+ :test_suite_id,
12
+ :inputs,
13
+ :title
14
+ ].freeze
15
+
16
+ include Inferno::Entities::Attributes
17
+ include Inferno::Entities::HasRunnable
18
+
19
+ def initialize(params)
20
+ super(params, ATTRIBUTES)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -171,6 +171,14 @@ module Inferno
171
171
 
172
172
  alias run block
173
173
 
174
+ def short_id
175
+ @short_id ||= begin
176
+ prefix = parent.respond_to?(:short_id) ? "#{parent.short_id}." : ''
177
+ suffix = parent ? (parent.tests.find_index(self) + 1).to_s.rjust(2, '0') : 'x'
178
+ "#{prefix}#{suffix}"
179
+ end
180
+ end
181
+
174
182
  # @private
175
183
  def default_id
176
184
  return name if name.present?
@@ -65,6 +65,14 @@ module Inferno
65
65
  }
66
66
  end
67
67
 
68
+ def short_id
69
+ @short_id ||= begin
70
+ prefix = parent.respond_to?(:short_id) ? "#{parent.short_id}." : ''
71
+ suffix = parent ? (parent.groups.find_index(self) + 1).to_s : 'X'
72
+ "#{prefix}#{suffix}"
73
+ end
74
+ end
75
+
68
76
  def default_id
69
77
  return name if name.present?
70
78