resque-scheduler-web 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +48 -0
- data/Rakefile +2 -0
- data/app/controllers/resque_web/plugins/resque_scheduler/delayed_controller.rb +55 -0
- data/app/controllers/resque_web/plugins/resque_scheduler/schedules_controller.rb +62 -0
- data/app/helpers/resque_web/plugins/resque_scheduler/delayed_helper.rb +11 -0
- data/app/helpers/resque_web/plugins/resque_scheduler/schedules_helper.rb +53 -0
- data/app/models/resque_web/plugins/resque_scheduler/job_finder/working_job_finder.rb +40 -0
- data/app/models/resque_web/plugins/resque_scheduler/job_finder.rb +81 -0
- data/app/views/resque_web/plugins/resque_scheduler/delayed/_next_more.erb +23 -0
- data/app/views/resque_web/plugins/resque_scheduler/delayed/_search_form.erb +8 -0
- data/app/views/resque_web/plugins/resque_scheduler/delayed/index.erb +61 -0
- data/app/views/resque_web/plugins/resque_scheduler/delayed/jobs_klass.erb +20 -0
- data/app/views/resque_web/plugins/resque_scheduler/delayed/search.erb +72 -0
- data/app/views/resque_web/plugins/resque_scheduler/delayed/timestamp.erb +25 -0
- data/app/views/resque_web/plugins/resque_scheduler/schedules/index.html.erb +51 -0
- data/app/views/resque_web/plugins/resque_scheduler/schedules/requeue-params.erb +23 -0
- data/lib/resque/scheduler/web/version.rb +7 -0
- data/lib/resque/scheduler/web.rb +6 -0
- data/lib/resque_web/plugins/resque_scheduler/engine.rb +49 -0
- data/resque-scheduler-web.gemspec +35 -0
- data/spec/controllers/delayed_controller_spec.rb +117 -0
- data/spec/controllers/schedules_controller_spec.rb +152 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config/application.rb +31 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +42 -0
- data/spec/dummy/config/environments/production.rb +83 -0
- data/spec/dummy/config/environments/test.rb +43 -0
- data/spec/dummy/config/initializers/assets.rb +12 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +9 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +15 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +18 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/log/development.log +4 -0
- data/spec/dummy/log/test.log +56454 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/features/navigation_spec.rb +16 -0
- data/spec/features/schedules/requeuing_a_job_with_parameters_spec.rb +36 -0
- data/spec/features/schedules/scheduled_jobs_page_spec.rb +80 -0
- data/spec/models/job_finder/working_job_finder_spec.rb +38 -0
- data/spec/models/job_finder_spec.rb +68 -0
- data/spec/rails_helper.rb +25 -0
- data/spec/routing/delayed_routing_spec.rb +9 -0
- data/spec/spec_helper.rb +96 -0
- data/spec/support/redis_instance.rb +133 -0
- data/spec/support/test_jobs.rb +77 -0
- metadata +312 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/404.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
62
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
63
|
+
</div>
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/422.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>The change you wanted was rejected.</h1>
|
62
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
63
|
+
</div>
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,66 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/500.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>We're sorry, but something went wrong.</h1>
|
62
|
+
</div>
|
63
|
+
<p>If you are the application owner check the logs for more information.</p>
|
64
|
+
</div>
|
65
|
+
</body>
|
66
|
+
</html>
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
feature 'the tabs added to the resque web interface work correctly' do
|
4
|
+
|
5
|
+
scenario 'the Schedule tab works' do
|
6
|
+
visit ResqueWeb::Engine.app.url_helpers.overview_path
|
7
|
+
click_link 'Schedule'
|
8
|
+
expect(current_path).to eq resque_scheduler_engine_routes.schedules_path
|
9
|
+
end
|
10
|
+
|
11
|
+
scenario 'the Delayed tab works' do
|
12
|
+
visit ResqueWeb::Engine.app.url_helpers.overview_path
|
13
|
+
click_link 'Delayed'
|
14
|
+
expect(current_path).to eq resque_scheduler_engine_routes.delayed_path
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
feature 'requeuing a job that has defined params' do
|
4
|
+
|
5
|
+
before do
|
6
|
+
Resque.schedule = Test::RESQUE_SCHEDULE
|
7
|
+
Resque::Scheduler.load_schedule!
|
8
|
+
end
|
9
|
+
|
10
|
+
# Given I have a job which requires params in the schedule
|
11
|
+
# When I press the requeue button
|
12
|
+
# Then I should be presented with a form that prompts me for the params
|
13
|
+
# When I enter the params and submit the form
|
14
|
+
# Then I should be on the overview page
|
15
|
+
# And I should see the job in the queue
|
16
|
+
# When I visit the queue page
|
17
|
+
# Then I should see the job on the page with the new params
|
18
|
+
scenario 'I am prompted to enter the params required for the requeued job' do
|
19
|
+
|
20
|
+
job_name = 'job_with_params'
|
21
|
+
queue_name = 'quick'
|
22
|
+
job_class = 'JobWithParams'
|
23
|
+
|
24
|
+
visit resque_scheduler_engine_routes.schedules_path
|
25
|
+
click_button "requeue_job_#{job_name}"
|
26
|
+
|
27
|
+
fill_in 'log_level', with: 'info'
|
28
|
+
click_button 'Queue now'
|
29
|
+
|
30
|
+
expect(current_path).to eq ResqueWeb::Engine.app.url_helpers.overview_path
|
31
|
+
click_link queue_name
|
32
|
+
|
33
|
+
expect(page).to have_content job_class
|
34
|
+
expect(page).to have_css 'td.args', text: /"log_level"=>"info"/
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
feature 'Viewing the schedule page and interacting with it' do
|
4
|
+
|
5
|
+
def visit_scheduler_page
|
6
|
+
visit resque_scheduler_engine_routes.schedules_path
|
7
|
+
end
|
8
|
+
|
9
|
+
before do
|
10
|
+
Resque::Scheduler.env = 'production'
|
11
|
+
|
12
|
+
Resque.schedule = {
|
13
|
+
'some_ivar_job' => {
|
14
|
+
'cron' => '* * * * *',
|
15
|
+
'class' => 'SomeIvarJob',
|
16
|
+
'args' => '/tmp',
|
17
|
+
'rails_env' => 'production'
|
18
|
+
},
|
19
|
+
'some_other_job' => {
|
20
|
+
'every' => ['1m', ['1h']],
|
21
|
+
'queue' => 'high',
|
22
|
+
'custom_job_class' => 'SomeOtherJob',
|
23
|
+
'args' => {
|
24
|
+
'b' => 'blah'
|
25
|
+
}
|
26
|
+
},
|
27
|
+
'some_fancy_job' => {
|
28
|
+
'every' => ['1m'],
|
29
|
+
'queue' => 'fancy',
|
30
|
+
'class' => 'SomeFancyJob',
|
31
|
+
'args' => 'sparkles',
|
32
|
+
'rails_env' => 'fancy'
|
33
|
+
},
|
34
|
+
'shared_env_job' => {
|
35
|
+
'cron' => '* * * * *',
|
36
|
+
'class' => 'SomeSharedEnvJob',
|
37
|
+
'args' => '/tmp',
|
38
|
+
'rails_env' => 'fancy, production'
|
39
|
+
}
|
40
|
+
}
|
41
|
+
Resque::Scheduler.load_schedule!
|
42
|
+
visit_scheduler_page
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'Link to Schedule page in navigation works' do
|
46
|
+
visit '/resque_web'
|
47
|
+
click_link 'Schedule'
|
48
|
+
assert page.has_css? 'h1', 'Schedule'
|
49
|
+
end
|
50
|
+
|
51
|
+
it '200' do
|
52
|
+
assert page.has_css?('h1', 'Schedule')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'see the scheduled job' do
|
56
|
+
assert page.body.include?('SomeIvarJob')
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'excludes jobs for other envs' do
|
60
|
+
assert !page.body.include?('SomeFancyJob')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'includes job used in multiple environments' do
|
64
|
+
assert page.body.include?('SomeSharedEnvJob')
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'allows delete when dynamic' do
|
68
|
+
allow(Resque::Scheduler).to receive(:dynamic).and_return(true)
|
69
|
+
visit_scheduler_page
|
70
|
+
|
71
|
+
assert page.body.include?('Delete')
|
72
|
+
end
|
73
|
+
|
74
|
+
it "doesn't allow delete when static" do
|
75
|
+
allow(Resque::Scheduler).to receive(:dynamic).and_return(false)
|
76
|
+
visit_scheduler_page
|
77
|
+
|
78
|
+
assert !page.body.include?('Delete')
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative '../../../app/models/resque_web/plugins/resque_scheduler/job_finder/working_job_finder'
|
2
|
+
|
3
|
+
describe ResqueWeb::Plugins::ResqueScheduler::JobFinder::WorkingJobFinder do
|
4
|
+
|
5
|
+
before do
|
6
|
+
Resque.enqueue(OngoingJob)
|
7
|
+
@worker_thread = Thread.new do
|
8
|
+
worker = Resque::Worker.new '*'
|
9
|
+
worker.term_child = 1
|
10
|
+
worker.work 0.1
|
11
|
+
end
|
12
|
+
sleep 0.2
|
13
|
+
end
|
14
|
+
|
15
|
+
after do
|
16
|
+
@worker_thread.kill
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'finds a working job when the search term matches' do
|
20
|
+
finder = ResqueWeb::Plugins::ResqueScheduler::JobFinder::WorkingJobFinder.new('going')
|
21
|
+
expect(finder.find_jobs.first['class']).to eq 'OngoingJob'
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'does not find a working job when the search term does not match' do
|
25
|
+
finder = ResqueWeb::Plugins::ResqueScheduler::JobFinder::WorkingJobFinder.new('donkey')
|
26
|
+
expect(finder.find_jobs).to be_empty
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'adds the queue name to the returned jobs' do
|
30
|
+
finder = ResqueWeb::Plugins::ResqueScheduler::JobFinder::WorkingJobFinder.new('going')
|
31
|
+
expect(finder.find_jobs.first['queue']).to eq 'quick'
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'sets the where_at value to "working" for the returned jobs' do
|
35
|
+
finder = ResqueWeb::Plugins::ResqueScheduler::JobFinder::WorkingJobFinder.new('going')
|
36
|
+
expect(finder.find_jobs.first['where_at']).to eq 'working'
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require_relative '../../app/models/resque_web/plugins/resque_scheduler/job_finder'
|
2
|
+
|
3
|
+
describe ResqueWeb::Plugins::ResqueScheduler::JobFinder do
|
4
|
+
|
5
|
+
let(:non_matching_finder) { ResqueWeb::Plugins::ResqueScheduler::JobFinder.new('donkey') }
|
6
|
+
|
7
|
+
after do
|
8
|
+
Resque.reset_delayed_queue
|
9
|
+
Resque.queues.each { |q| Resque.remove_queue q }
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'with a scheduled job queued in the future' do
|
13
|
+
|
14
|
+
let(:time_in_future) { Time.now + 60 }
|
15
|
+
let(:matching_finder) { ResqueWeb::Plugins::ResqueScheduler::JobFinder.new('ivar') }
|
16
|
+
|
17
|
+
before do
|
18
|
+
Resque.enqueue_at(time_in_future, SomeIvarJob)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'does not find a scheduled job that does not match' do
|
22
|
+
expect(non_matching_finder.find_jobs).to be_empty
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'finds a matching scheduled job' do
|
26
|
+
expect(matching_finder.find_jobs.first['class']).to eq 'SomeIvarJob'
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'sets "where_at" to "delayed" for the delayed scheduled jobs' do
|
30
|
+
expect(matching_finder.find_jobs.first['where_at']).to eq 'delayed'
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'sets the timestamp for the delayed scheduled jobs' do
|
34
|
+
expect(matching_finder.find_jobs.first['timestamp']).to eq time_in_future.to_i
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'with a job currently in the queue' do
|
39
|
+
|
40
|
+
let(:matching_finder) { ResqueWeb::Plugins::ResqueScheduler::JobFinder.new('quick') }
|
41
|
+
|
42
|
+
before do
|
43
|
+
Resque.enqueue(SomeQuickJob)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'returns an empty result set with a nil search term' do
|
47
|
+
finder = ResqueWeb::Plugins::ResqueScheduler::JobFinder.new(nil)
|
48
|
+
expect(finder.find_jobs).to be_empty
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should find matching queued job' do
|
52
|
+
expect(matching_finder.find_jobs.first['class']).to eq 'SomeQuickJob'
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'adds the queue name to the returned queued jobs' do
|
56
|
+
expect(matching_finder.find_jobs.first['queue']).to eq 'quick'
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'sets "where_at" to "queued" for the returned queued jobs' do
|
60
|
+
expect(matching_finder.find_jobs.first['where_at']).to eq 'queued'
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'does not find a queued job that does not match' do
|
64
|
+
expect(non_matching_finder.find_jobs).to be_empty
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
4
|
+
ActiveRecord::Migrator.migrations_paths = [File.expand_path(
|
5
|
+
'../../test/dummy/db/migrate',
|
6
|
+
__FILE__
|
7
|
+
)]
|
8
|
+
ActiveRecord::Migrator.migrations_paths << File.expand_path(
|
9
|
+
'../../db/migrate',
|
10
|
+
__FILE__
|
11
|
+
)
|
12
|
+
|
13
|
+
require 'rspec/rails'
|
14
|
+
|
15
|
+
|
16
|
+
# So we can access the Engine class and its path helpers
|
17
|
+
$LOAD_PATH.unshift File.dirname(File.expand_path(__FILE__)) + '/../lib'
|
18
|
+
|
19
|
+
RSpec.configure do |config|
|
20
|
+
config.infer_spec_type_from_file_location!
|
21
|
+
end
|
22
|
+
|
23
|
+
RedisInstance.run!
|
24
|
+
|
25
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe ResqueWeb::Plugins::ResqueScheduler::DelayedController, type: :routing do
|
4
|
+
routes { ResqueWeb::Plugins::ResqueScheduler::Engine.routes }
|
5
|
+
|
6
|
+
it 'routes to POST cancel_now' do
|
7
|
+
expect(post 'delayed/cancel_now').to route_to('resque_web/plugins/resque_scheduler/delayed#cancel_now')
|
8
|
+
end
|
9
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
ENV['RAILS_ENV'] = 'test'
|
2
|
+
|
3
|
+
require 'resque'
|
4
|
+
|
5
|
+
require 'resque-scheduler'
|
6
|
+
|
7
|
+
Resque::Scheduler.configure do |c|
|
8
|
+
c.quiet = true
|
9
|
+
end
|
10
|
+
|
11
|
+
unless ENV['RESQUE_SCHEDULER_DISABLE_TEST_REDIS_SERVER']
|
12
|
+
# Start our own Redis when the tests start. RedisInstance will take care of
|
13
|
+
# starting and stopping.
|
14
|
+
require File.expand_path('../support/redis_instance', __FILE__)
|
15
|
+
RedisInstance.run!
|
16
|
+
end
|
17
|
+
|
18
|
+
require File.expand_path('../support/test_jobs', __FILE__)
|
19
|
+
|
20
|
+
RSpec.configure do |config|
|
21
|
+
# rspec-expectations config goes here. You can use an alternate
|
22
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
23
|
+
# assertions if you prefer.
|
24
|
+
config.expect_with :rspec do |expectations|
|
25
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
26
|
+
# and `failure_message` of custom matchers include text for helper methods
|
27
|
+
# defined using `chain`, e.g.:
|
28
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
29
|
+
# # => "be bigger than 2 and smaller than 4"
|
30
|
+
# ...rather than:
|
31
|
+
# # => "be bigger than 2"
|
32
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
33
|
+
end
|
34
|
+
|
35
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
36
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
37
|
+
config.mock_with :rspec do |mocks|
|
38
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
39
|
+
# a real object. This is generally recommended, and will default to
|
40
|
+
# `true` in RSpec 4.
|
41
|
+
mocks.verify_partial_doubles = true
|
42
|
+
end
|
43
|
+
|
44
|
+
# The settings below are suggested to provide a good initial experience
|
45
|
+
# with RSpec, but feel free to customize to your heart's content.
|
46
|
+
=begin
|
47
|
+
# These two settings work together to allow you to limit a spec run
|
48
|
+
# to individual examples or groups you care about by tagging them with
|
49
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
50
|
+
# get run.
|
51
|
+
config.filter_run :focus
|
52
|
+
config.run_all_when_everything_filtered = true
|
53
|
+
|
54
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
55
|
+
# recommended. For more details, see:
|
56
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
57
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
58
|
+
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
59
|
+
config.disable_monkey_patching!
|
60
|
+
|
61
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
62
|
+
# be too noisy due to issues in dependencies.
|
63
|
+
config.warnings = true
|
64
|
+
|
65
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
66
|
+
# file, and it's useful to allow more verbose output when running an
|
67
|
+
# individual spec file.
|
68
|
+
if config.files_to_run.one?
|
69
|
+
# Use the documentation formatter for detailed output,
|
70
|
+
# unless a formatter has already been configured
|
71
|
+
# (e.g. via a command-line flag).
|
72
|
+
config.default_formatter = 'doc'
|
73
|
+
end
|
74
|
+
|
75
|
+
# Print the 10 slowest examples and example groups at the
|
76
|
+
# end of the spec run, to help surface which specs are running
|
77
|
+
# particularly slow.
|
78
|
+
config.profile_examples = 10
|
79
|
+
|
80
|
+
# Run specs in random order to surface order dependencies. If you find an
|
81
|
+
# order dependency and want to debug it, you can fix the order by providing
|
82
|
+
# the seed, which is printed after each run.
|
83
|
+
# --seed 1234
|
84
|
+
config.order = :random
|
85
|
+
|
86
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
87
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
88
|
+
# test failures related to randomization by passing the same `--seed` value
|
89
|
+
# as the one that triggered the failure.
|
90
|
+
Kernel.srand config.seed
|
91
|
+
=end
|
92
|
+
end
|
93
|
+
|
94
|
+
def resque_scheduler_engine_routes
|
95
|
+
ResqueWeb::Plugins::ResqueScheduler::Engine.app.url_helpers
|
96
|
+
end
|