# vim:fileencoding=utf-8
require_relative 'test_helper'
require 'resque/server/test_helper'
context 'on GET to /schedule' do
setup { get '/schedule' }
test('is 200') { assert last_response.ok? }
end
context 'on GET to /schedule with scheduled jobs' do
setup do
Resque::Scheduler.env = 'production'
Resque.schedule = {
'some_ivar_job' => {
'cron' => '* * * * *',
'class' => 'SomeIvarJob',
'args' => '/tmp',
'rails_env' => 'production'
},
'some_other_job' => {
'every' => ['1m', ['1h']],
'queue' => 'high',
'custom_job_class' => 'SomeOtherJob',
'args' => {
'b' => 'blah'
}
},
'some_fancy_job' => {
'every' => ['1m'],
'queue' => 'fancy',
'class' => 'SomeFancyJob',
'args' => 'sparkles',
'rails_env' => 'fancy'
},
'shared_env_job' => {
'cron' => '* * * * *',
'class' => 'SomeSharedEnvJob',
'args' => '/tmp',
'rails_env' => 'fancy, production'
}
}
Resque::Scheduler.load_schedule!
get '/schedule'
end
test('is 200') { assert last_response.ok? }
test 'see the scheduled job' do
assert last_response.body.include?('SomeIvarJob')
end
test 'excludes jobs for other envs' do
assert !last_response.body.include?('SomeFancyJob')
end
test 'includes job used in multiple environments' do
assert last_response.body.include?('SomeSharedEnvJob')
end
test 'allows delete when dynamic' do
Resque::Scheduler.stubs(:dynamic).returns(true)
get '/schedule'
assert last_response.body.include?('Delete')
end
test "doesn't allow delete when static" do
Resque::Scheduler.stubs(:dynamic).returns(false)
get '/schedule'
assert !last_response.body.include?('Delete')
end
end
context 'on GET to /delayed' do
setup { get '/delayed' }
test('is 200') { assert last_response.ok? }
end
context 'on GET to /delayed/jobs/:klass'do
setup do
@t = Time.now + 3600
Resque.enqueue_at(@t, SomeIvarJob, 'foo', 'bar')
get(
URI('/delayed/jobs/SomeIvarJob?args=' <<
URI.encode(%w(foo bar).to_json)).to_s
)
end
test('is 200') { assert last_response.ok? }
test 'see the scheduled job' do
assert last_response.body.include?(@t.to_s)
end
context 'with a namespaced class' do
setup do
@t = Time.now + 3600
module Foo
class Bar
def self.queue
'bar'
end
end
end
Resque.enqueue_at(@t, Foo::Bar, 'foo', 'bar')
get(
URI('/delayed/jobs/Foo::Bar?args=' <<
URI.encode(%w(foo bar).to_json)).to_s
)
end
test('is 200') { assert last_response.ok? }
test 'see the scheduled job' do
assert last_response.body.include?(@t.to_s)
end
end
end
module Test
RESQUE_SCHEDULE = {
'job_without_params' => {
'cron' => '* * * * *',
'class' => 'JobWithoutParams',
'args' => {
'host' => 'localhost'
},
'rails_env' => 'production'
},
'job_with_params' => {
'every' => '1m',
'class' => 'JobWithParams',
'args' => {
'host' => 'localhost'
},
'parameters' => {
'log_level' => {
'description' => 'The level of logging',
'default' => 'warn'
}
}
}
}
end
context 'POST /schedule/requeue' do
setup do
Resque.schedule = Test::RESQUE_SCHEDULE
Resque::Scheduler.load_schedule!
end
test 'job without params' do
# Regular jobs without params should redirect to /overview
job_name = 'job_without_params'
Resque::Scheduler.stubs(:enqueue_from_config)
.once.with(Resque.schedule[job_name])
post '/schedule/requeue', 'job_name' => job_name
follow_redirect!
assert_equal 'http://example.org/overview', last_request.url
assert last_response.ok?
end
test 'job with params' do
# If a job has params defined,
# it should render the template with a form for the job params
job_name = 'job_with_params'
post '/schedule/requeue', 'job_name' => job_name
assert last_response.ok?, last_response.errors
assert last_response.body.include?('This job requires parameters')
assert last_response.body.include?(
%()
)
Resque.schedule[job_name]['parameters'].each do |_param_name, param_config|
assert last_response.body.include?(
'(?)]
)
assert last_response.body.include?(
')
)
end
end
end
context 'POST /schedule/requeue_with_params' do
setup do
Resque.schedule = Test::RESQUE_SCHEDULE
Resque::Scheduler.load_schedule!
end
test 'job with params' do
job_name = 'job_with_params'
log_level = 'error'
job_config = Resque.schedule[job_name]
args = job_config['args'].merge('log_level' => log_level)
job_config = job_config.merge('args' => args)
Resque::Scheduler.stubs(:enqueue_from_config).once.with(job_config)
post '/schedule/requeue_with_params',
'job_name' => job_name,
'log_level' => log_level
follow_redirect!
assert_equal 'http://example.org/overview', last_request.url
assert last_response.ok?, last_response.errors
end
end
context 'on POST to /delayed/search' do
setup do
t = Time.now + 60
Resque.enqueue_at(t, SomeIvarJob)
Resque.enqueue(SomeQuickJob)
end
test 'should find matching scheduled job' do
post '/delayed/search', 'search' => 'ivar'
assert last_response.status == 200
assert last_response.body.include?('SomeIvarJob')
end
test 'should find matching queued job' do
post '/delayed/search', 'search' => 'quick'
assert last_response.status == 200
assert last_response.body.include?('SomeQuickJob')
end
end
context 'on POST to /delayed/cancel_now' do
setup { post '/delayed/cancel_now' }
test 'redirects to overview' do
assert last_response.status == 302
assert last_response.header['Location'].include? '/delayed'
end
end
context 'on POST to /delayed/clear' do
setup { post '/delayed/clear' }
test 'redirects to delayed' do
assert last_response.status == 302
assert last_response.header['Location'].include? '/delayed'
end
end
context 'on POST to /delayed/queue_now' do
setup { post '/delayed/queue_now' }
test 'redirects to overview' do
assert last_response.status == 302
assert last_response.header['Location'].include? '/overview'
end
end
context 'on GET to /delayed/:timestamp' do
setup { get '/delayed/1234567890' }
test 'shows delayed_timestamp view' do
assert last_response.status == 200
end
end
context 'DELETE /schedule when dynamic' do
setup do
Resque.schedule = Test::RESQUE_SCHEDULE
Resque::Scheduler.load_schedule!
Resque::Scheduler.stubs(:dynamic).returns(true)
end
test 'redirects to schedule page' do
delete '/schedule'
status = last_response.status
redirect_location = last_response.original_headers['Location']
response_status_msg = "Expected response to be a 302, but was a #{status}."
redirect_msg = "Redirect to #{redirect_location} instead of /schedule."
assert status == 302, response_status_msg
assert_match %r{/schedule/?$}, redirect_location, redirect_msg
end
test 'does not show the deleted job' do
delete '/schedule', job_name: 'job_with_params'
follow_redirect!
msg = 'The job should not have been shown on the /schedule page.'
assert !last_response.body.include?('job_with_params'), msg
end
test 'removes job from redis' do
delete '/schedule', job_name: 'job_with_params'
msg = 'The job was not deleted from redis.'
assert_nil Resque.fetch_schedule('job_with_params'), msg
end
end
context 'DELETE /schedule when static' do
setup do
Resque.schedule = Test::RESQUE_SCHEDULE
Resque::Scheduler.load_schedule!
Resque::Scheduler.stubs(:dynamic).returns(false)
end
test 'does not remove the job from the UI' do
delete '/schedule', job_name: 'job_with_params'
follow_redirect!
msg = 'The job should not have been removed from the /schedule page.'
assert last_response.body.include?('job_with_params'), msg
end
test 'does not remove job from redis' do
delete '/schedule', job_name: 'job_with_params'
msg = 'The job should not have been deleted from redis.'
assert Resque.fetch_schedule('job_with_params'), msg
end
end