Skip to content

Commit 6c22b72

Browse files
committed
Refs #39167 - add tests for job wizard templates
1 parent 0588a71 commit 6c22b72

File tree

1 file changed

+213
-0
lines changed

1 file changed

+213
-0
lines changed
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
# frozen_string_literal: true
2+
3+
require File.expand_path('../test_plugin_helper', __dir__)
4+
require 'integration_test_helper'
5+
6+
class JobWizardCategoryJsTest < IntegrationTestWithJavascript
7+
WIZARD_INPUT_NAME = 'wizard_integration_input'
8+
9+
setup do
10+
@original_rex_form_template = Setting[:remote_execution_form_job_template]
11+
as_admin do
12+
@default_job_template = FactoryBot.create(
13+
:job_template,
14+
:name => 'Integration Default REX Form Template',
15+
:job_category => 'Default Form Category'
16+
)
17+
@feature_job_template = FactoryBot.create(
18+
:job_template,
19+
:name => 'Integration Feature REX Template',
20+
:job_category => 'Feature Linked Category'
21+
)
22+
add_plain_template_input!(@default_job_template)
23+
add_plain_template_input!(@feature_job_template)
24+
Setting[:remote_execution_form_job_template] = @default_job_template.name
25+
@remote_execution_feature = FactoryBot.create(
26+
:remote_execution_feature,
27+
:label => 'integration_rex_category_feature',
28+
:name => 'Integration REX Category Feature',
29+
:job_template => @feature_job_template
30+
)
31+
@rex_host = FactoryBot.create(:host, :with_execution)
32+
end
33+
end
34+
35+
teardown do
36+
Setting[:remote_execution_form_job_template] = @original_rex_form_template
37+
end
38+
39+
test 'job wizard shows feature template job category when feature query param is present' do
40+
visit new_job_invocation_path(:feature => @remote_execution_feature.label)
41+
assert_text 'Category and template', :wait => 30
42+
wait_for_ajax
43+
assert_selector(:ouia_component_id, 'job_category', :text => 'Feature Linked Category', :wait => 30)
44+
end
45+
46+
test 'job wizard shows default form category when no feature query param' do
47+
visit new_job_invocation_path
48+
assert_text 'Category and template', :wait => 30
49+
wait_for_ajax
50+
assert_selector(:ouia_component_id, 'job_category', :text => 'Default Form Category', :wait => 30)
51+
end
52+
53+
test 'job wizard prefills template input from inputs query param' do
54+
visit new_job_invocation_path(
55+
:inputs => { WIZARD_INPUT_NAME => 'from_query_string' },
56+
:search => ''
57+
)
58+
go_to_target_hosts_and_inputs_step!
59+
assert_selector "textarea##{WIZARD_INPUT_NAME}", :wait => 30
60+
assert_equal 'from_query_string', find("textarea##{WIZARD_INPUT_NAME}").value
61+
end
62+
63+
test 'job wizard does not prefill template input when inputs query param is omitted' do
64+
visit new_job_invocation_path(:search => '')
65+
go_to_target_hosts_and_inputs_step!
66+
assert_selector "textarea##{WIZARD_INPUT_NAME}", :wait => 30
67+
assert_equal '', find("textarea##{WIZARD_INPUT_NAME}").value
68+
end
69+
70+
test 'job wizard prefills template input when feature and inputs query params are present' do
71+
visit new_job_invocation_path(
72+
:feature => @remote_execution_feature.label,
73+
:inputs => { WIZARD_INPUT_NAME => 'feature_and_inputs' },
74+
:search => ''
75+
)
76+
go_to_target_hosts_and_inputs_step!
77+
assert_selector "textarea##{WIZARD_INPUT_NAME}", :wait => 30
78+
assert_equal 'feature_and_inputs', find("textarea##{WIZARD_INPUT_NAME}").value
79+
end
80+
81+
test 'job wizard run on selected hosts is enabled on review and posts to job invocations API' do
82+
posted_to_job_invocations_create = false
83+
subscriber = ActiveSupport::Notifications.subscribe('start_processing.action_controller') do |_n, _s, _f, _i, payload|
84+
if payload[:controller].to_s.end_with?('JobInvocationsController') && payload[:action].to_s == 'create'
85+
posted_to_job_invocations_create = true
86+
end
87+
end
88+
89+
begin
90+
visit new_job_invocation_path(:search => "id = #{@rex_host.id}")
91+
navigate_job_wizard_to_review_step!
92+
93+
assert_selector(:ouia_component_id, 'run-on-selected-hosts-footer', :wait => 30)
94+
run_on_hosts = find(:ouia_component_id, 'run-on-selected-hosts-footer')
95+
assert_includes [nil, 'false'], run_on_hosts[:'aria-disabled']
96+
assert_text 'Run on selected hosts'
97+
find(:ouia_component_id, 'run-on-selected-hosts-footer').click
98+
wait_for_ajax
99+
assert posted_to_job_invocations_create, 'expected Api::V2::JobInvocationsController#create to run'
100+
assert_match(%r{\A/job_invocations/\d+\z}, page.current_path)
101+
ensure
102+
ActiveSupport::Notifications.unsubscribe(subscriber)
103+
end
104+
end
105+
106+
test 'job wizard create API request sends job_template_id and inputs for default template' do
107+
input_value = 'api_payload_default_template'
108+
job_inv_params = capture_api_job_invocation_params_during do
109+
visit new_job_invocation_path(
110+
:search => "id = #{@rex_host.id}",
111+
:inputs => { WIZARD_INPUT_NAME => input_value }
112+
)
113+
navigate_job_wizard_to_review_step!
114+
find(:ouia_component_id, 'run-on-selected-hosts-footer').click
115+
wait_for_ajax
116+
end
117+
118+
assert job_inv_params, 'expected job_invocation key in POST /api/job_invocations'
119+
assert job_inv_params[:job_template_id].present?, 'expected job_template_id to be present'
120+
assert_equal @default_job_template.id, job_inv_params[:job_template_id].to_i
121+
assert job_inv_params[:feature].blank?
122+
assert_equal input_value, hash_from_params_object(job_inv_params[:inputs])[WIZARD_INPUT_NAME]
123+
job_invocation_id = page.current_path.split('/').last.to_i
124+
assert_equal @default_job_template.job_category, JobInvocation.find(job_invocation_id).job_category, 'expected job category to be the default template category'
125+
end
126+
127+
test 'job wizard create API request sends feature label and inputs without job_template_id' do
128+
input_value = 'api_payload_feature_template'
129+
job_inv_params = capture_api_job_invocation_params_during do
130+
visit new_job_invocation_path(
131+
:feature => @remote_execution_feature.label,
132+
:search => "id = #{@rex_host.id}",
133+
:inputs => { WIZARD_INPUT_NAME => input_value }
134+
)
135+
navigate_job_wizard_to_review_step!
136+
find(:ouia_component_id, 'run-on-selected-hosts-footer').click
137+
wait_for_ajax
138+
end
139+
140+
assert job_inv_params, 'expected job_invocation key in POST /api/job_invocations'
141+
assert_not job_inv_params[:job_template_id].present?
142+
assert_equal @remote_execution_feature.label, job_inv_params[:feature]
143+
assert_equal input_value, hash_from_params_object(job_inv_params[:inputs])[WIZARD_INPUT_NAME]
144+
job_invocation_id = page.current_path.split('/').last.to_i
145+
assert_equal @feature_job_template.job_category, JobInvocation.find(job_invocation_id).job_category, 'expected job category to be the feature template category'
146+
end
147+
148+
private
149+
150+
def capture_api_job_invocation_params_during
151+
captured = nil
152+
subscriber = ActiveSupport::Notifications.subscribe('start_processing.action_controller') do |_n, _s, _f, _i, payload|
153+
next unless payload[:controller].to_s.end_with?('JobInvocationsController') && payload[:action].to_s == 'create'
154+
root = payload[:params]
155+
root = root.to_unsafe_h if root.respond_to?(:to_unsafe_h)
156+
job_inv_params = root[:job_invocation] || root['job_invocation']
157+
next unless job_inv_params
158+
job_inv_params = job_inv_params.to_unsafe_h if job_inv_params.respond_to?(:to_unsafe_h)
159+
captured = job_inv_params.with_indifferent_access
160+
end
161+
begin
162+
yield
163+
ensure
164+
ActiveSupport::Notifications.unsubscribe(subscriber)
165+
end
166+
captured
167+
end
168+
169+
def hash_from_params_object(obj)
170+
return {}.with_indifferent_access if obj.blank?
171+
h = obj.respond_to?(:to_unsafe_h) ? obj.to_unsafe_h : obj.to_h
172+
h.with_indifferent_access
173+
end
174+
175+
def add_plain_template_input!(job_template)
176+
job_template.template_inputs << FactoryBot.build(
177+
:template_input,
178+
:name => WIZARD_INPUT_NAME,
179+
:input_type => 'user',
180+
:value_type => 'plain',
181+
:required => false
182+
)
183+
job_template.save!
184+
end
185+
186+
def job_wizard_click_next!
187+
wait_for_ajax
188+
find(:ouia_component_id, 'next-footer').click
189+
wait_for_ajax
190+
end
191+
192+
def go_to_target_hosts_and_inputs_step!
193+
assert_text 'Category and template', :wait => 30
194+
wait_for_ajax
195+
job_wizard_click_next!
196+
assert_text 'Target hosts and inputs', :wait => 30
197+
wait_for_ajax
198+
end
199+
200+
def navigate_job_wizard_to_review_step!
201+
assert_text 'Category and template', :wait => 30
202+
wait_for_ajax
203+
job_wizard_click_next!
204+
assert_text 'Target hosts and inputs', :wait => 30
205+
job_wizard_click_next!
206+
assert_text 'Advanced fields', :wait => 30
207+
job_wizard_click_next!
208+
assert_text 'Immediate execution', :wait => 30
209+
job_wizard_click_next!
210+
assert_text 'Review details', :wait => 30
211+
wait_for_ajax
212+
end
213+
end

0 commit comments

Comments
 (0)