Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Enable Ruby Proc for require_confirm_worker_params #32

Merged
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ SidekiqAdhocJob.configure do |config|
config.module_names = ['YourProject::Worker']
config.strategy_name = :active_job
config.load_paths = ['app/jobs/**/*.rb']

config.require_confirm_worker_names = %w[YourProject::Worker::A YourProject::Worker::B]
# List of Symbols = %i[YourProject::Worker::A YourProject::Worker::B]
# Apply to workers name ending with "A" = ->(worker_class) { worker_class.end_with?('A') }
# Ruby class that implements #call = CallableObject.new
end
SidekiqAdhocJob.init
```
Expand All @@ -35,7 +40,7 @@ Options:
- `active_job`: check for all classes that extend `ActiveJob::Base`
- `rails_application_job`: check for all classes that extend `ApplicationJob`
- `load_paths` (optional - default `[]`): takes in a list of file paths that the gem should load when initializing, in order to include the necessary classes in the app `ObjectSpace`
- `require_confirm_worker_names` (optional - default `[]`): takes in a list of fully namespaced worker class names that the web UI will request for confirmation before running the job
- `require_confirm_worker_names` (optional - default `[]`): takes in a Ruby callable object, or a Proc, or fully namespaced worker class names that require confirmation before running the job through web UI.
- `require_confirm_prompt_message` (optional - default `confirm`): takes a string that is used for challenge keyword before running jobs included in `require_confirm_worker_names`. This value must be a string, otherwise, an error with message `'require_confirm_prompt_message must be string'` will be raised

### Keyword Arguments Support (>= v2.1.0)
Expand Down
13 changes: 10 additions & 3 deletions lib/sidekiq_adhoc_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,15 @@ def module_names
Array(@module_names).map(&:to_s)
end

def require_confirm
@require_confirm ||= Array(@require_confirm_worker_names).map(&:to_s)
def require_confirm_proc
@require_confirm_proc ||= \
if @require_confirm_worker_names.respond_to?(:call)
@require_confirm_worker_names
else
shortlisted_workers = Array(@require_confirm_worker_names).map(&:to_s)

->(worker_name) { shortlisted_workers.include?(worker_name) }
end
end

def require_confirm_prompt_message=(message)
Expand All @@ -70,7 +77,7 @@ def require_confirm_prompt_message=(message)
end

def require_confirmation?(worker_name)
require_confirm.include?(worker_name)
require_confirm_proc.call(worker_name)
end

def strategy
Expand Down
7 changes: 6 additions & 1 deletion lib/sidekiq_adhoc_job/web/templates/jobs/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,13 @@
<script>
document.getElementById('adhoc-jobs-submit-form').addEventListener('submit', (event) => {
const confirmPrompt = "<%= @presented_job.confirm_prompt_message %>";
if (prompt(`Please enter "${confirmPrompt}" to confirm`) !== confirmPrompt)
const input = prompt(`Please enter "${confirmPrompt}" to confirm`);
if (input !== confirmPrompt) {
event.preventDefault();
if (input !== null) {
alert('Your confirmation input is incorrect, try again.');
}
}
})
</script>
<% end %>
40 changes: 21 additions & 19 deletions spec/sidekiq_adhoc_job/requests/jobs/index_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,27 @@

expect(response_body).to include('<h3>Adhoc Jobs</h3>')

expect(response_body).to include(compact_html(
<<~HTML
<tr>
<td>SidekiqAdhocJob::Test::DummyWorker</td>
<td>dummy</td>
<td>id, overwrite</td>
<td>retry_job, retries, interval, name, options</td>
<td>type</td>
<td>dryrun</td>
<td>false</td>
<td>true</td>
<td class="text-center">
<a class="btn btn-warn btn-xs" href="/adhoc-jobs/sidekiq_adhoc_job_test_dummy_worker">
View Job
</a>
</td>
</tr>
HTML
))
expect(response_body).to include(
compact_html(
<<~HTML
<tr>
<td>SidekiqAdhocJob::Test::DummyWorker</td>
<td>dummy</td>
<td>id, overwrite</td>
<td>retry_job, retries, interval, name, options</td>
<td>type</td>
<td>dryrun</td>
<td>false</td>
<td>true</td>
<td class="text-center">
<a class="btn btn-warn btn-xs" href="/adhoc-jobs/sidekiq_adhoc_job_test_dummy_worker">
View Job
</a>
</td>
</tr>
HTML
)
)
end

end
15 changes: 10 additions & 5 deletions spec/sidekiq_adhoc_job/requests/jobs/schedule_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,19 @@

let(:fake_schedule_job) { double(call: true) }

it 'runs ScheduleAdhocJob service' do
expect(SidekiqAdhocJob::ScheduleAdhocJob).to receive(:new).with('sidekiq_adhoc_job_test_dummy_worker', schedule_job_params) { fake_schedule_job }
expect(fake_schedule_job).to receive(:call)
before do
disable_csrf
allow(SidekiqAdhocJob::ScheduleAdhocJob)
.to receive(:new)
.with('sidekiq_adhoc_job_test_dummy_worker', schedule_job_params)
.and_return(fake_schedule_job)
end

it 'runs ScheduleAdhocJob service' do
post '/adhoc-jobs/sidekiq_adhoc_job_test_dummy_worker/schedule', request_params

expect(last_response.status).to eq 302
expect(fake_schedule_job).to have_received(:call)
expect(last_response.status).to eq(302)
expect(last_response.headers['Location']).to eq "#{last_request.base_url}/adhoc-jobs"
end

end
181 changes: 96 additions & 85 deletions spec/sidekiq_adhoc_job/requests/jobs/show_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,58 +14,62 @@

response_body = compact_html(last_response.body)

expect(response_body).to include(compact_html(
<<~HTML
<form method="POST" action="/adhoc-jobs/sidekiq_adhoc_job_test_dummy_worker/schedule">
HTML
))

expect(response_body).to include(compact_html(
<<~HTML
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="id">*id:</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="id" id="id" required/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="overwrite">*overwrite:</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="overwrite" id="overwrite" required/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="retry_job">retry_job:</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="retry_job" id="retry_job"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="retries">retries:</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="retries" id="retries"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="interval">interval:</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="interval" id="interval"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="name">name:</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="name" id="name"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="options">options:</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="options" id="options"/>
</div>
</div>
HTML
))
expect(response_body).to include(
compact_html(
<<~HTML
<form method="POST" action="/adhoc-jobs/sidekiq_adhoc_job_test_dummy_worker/schedule" id="adhoc-jobs-submit-form">
HTML
)
)

expect(response_body).to include(
compact_html(
<<~HTML
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="id">*id:</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="id" id="id" required/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="overwrite">*overwrite:</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="overwrite" id="overwrite" required/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="retry_job">retry_job:</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="retry_job" id="retry_job"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="retries">retries:</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="retries" id="retries"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="interval">interval:</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="interval" id="interval"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="name">name:</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="name" id="name"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="options">options:</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="options" id="options"/>
</div>
</div>
HTML
)
)
end
end

Expand All @@ -77,33 +81,39 @@

response_body = compact_html(last_response.body)

expect(response_body).to include(compact_html(
<<~HTML
<form method="POST" action="/adhoc-jobs/sidekiq_adhoc_job_test_dummy_rest_args_worker/schedule">
HTML
))

expect(response_body).to include(compact_html(
<<~HTML
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="id">*id:</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="id" id="id" required/>
</div>
</div>
HTML
))

expect(response_body).to include(compact_html(
<<~HTML
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="rest_args">Rest arguments (please provide a json string representing the arguments):</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="rest_args" id="rest_args"/>
</div>
</div>
HTML
))
expect(response_body).to include(
compact_html(
<<~HTML
<form method="POST" action="/adhoc-jobs/sidekiq_adhoc_job_test_dummy_rest_args_worker/schedule" id="adhoc-jobs-submit-form">
HTML
)
)

expect(response_body).to include(
compact_html(
<<~HTML
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="id">*id:</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="id" id="id" required/>
</div>
</div>
HTML
)
)

expect(response_body).to include(
compact_html(
<<~HTML
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="rest_args">Rest arguments (please provide a json string representing the arguments):</label>
<div class="col-sm-4">
<input class="form-control" type="text" name="rest_args" id="rest_args"/>
</div>
</div>
HTML
)
)
end
end

Expand All @@ -115,11 +125,13 @@

response_body = compact_html(last_response.body)

expect(response_body).to include(compact_html(
<<~HTML
<form method="POST" action="/adhoc-jobs/sidekiq_adhoc_job_test_dummy_no_arg_worker/schedule">
HTML
))
expect(response_body).to include(
compact_html(
<<~HTML
<form method="POST" action="/adhoc-jobs/sidekiq_adhoc_job_test_dummy_no_arg_worker/schedule" id="adhoc-jobs-submit-form">
HTML
)
)

expect(response_body).to include('<p>No job arguments</p>')
end
Expand All @@ -133,5 +145,4 @@
expect(last_response.headers['Location']).to eq "#{last_request.base_url}/adhoc-jobs"
end
end

end