foreman-tasks 4.1.2 → 4.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 676dae1bc60b1633da496445b980e4b5fb491931bb227a70f2dcec4c44a9ae9e
4
- data.tar.gz: 98d4f9798338d20bf7885a9e11b40d492eeeca4d30e2a7f84c4734e4f83e30d7
3
+ metadata.gz: ba89e76b07357c27678169c5350b13a80ea346896e681e7061da8c9ff5c6d2ce
4
+ data.tar.gz: c0a597c5a7db439fcd6627460b0fa91ed9e5bf0ef2d5308f356d35582c141b9d
5
5
  SHA512:
6
- metadata.gz: 8482b8a8e5ce147f2bd81d1eea004ba9507c95ecf5d83d0ebd50b7c74cc467a561f035d0049f0d1b44c3d63a29c35f3e55792705d37dfc0b4431e02d2370732a
7
- data.tar.gz: c317248a7e396b2d556f397ba1fd91d162b5d38b75a593a7f8a28f555ef77ca15ec097f548162edd6c7a7198bfa7e84c6a902bbde6d7515c17b585f7632e9add
6
+ metadata.gz: 3f873f26387eb89860543bca5f888b017c2ac692c986873b97b48506f30429172d49e926450937262a9dcb06c26c45d7eefabdb7f3cce0b8c70ce6786ea7e4ad
7
+ data.tar.gz: b021241e11f9db347960eb55e2497112cf996f1e77e48d92f593fa47b735c0268532ec61e2779bd35fc01768178037eaedf8248b59dfc178031dd56fb1340b6f
@@ -192,7 +192,7 @@ module ForemanTasks
192
192
  params[:order] = "#{ordering_params[:sort_by]} #{ordering_params[:sort_order]}"
193
193
  end
194
194
  params[:order] ||= 'started_at DESC'
195
- @tasks = DashboardTableFilter.new(resource_scope_for_index, params).scope.order(params[:order].to_s)
195
+ @tasks = resource_scope_for_index.order(params[:order].to_s)
196
196
  end
197
197
 
198
198
  def search_options
@@ -127,8 +127,9 @@ module ForemanTasks
127
127
  end
128
128
 
129
129
  def filter(scope, paginate: true)
130
- scope = DashboardTableFilter.new(scope, params).scope
131
- scope = scope.search_for(search_query, order: params[:order])
130
+ search = current_taxonomy_search
131
+ search = [search, params[:search]].select(&:present?).join(' AND ')
132
+ scope = scope.search_for(search, order: params[:order])
132
133
  scope = scope.paginate(page: params[:page], per_page: params[:per_page]) if paginate
133
134
  scope.distinct
134
135
  end
@@ -20,9 +20,7 @@ module Actions
20
20
  private
21
21
 
22
22
  def set_clock
23
- action.world.clock.ping action.send(:suspended_action),
24
- POLL_INTERVAL,
25
- CheckOnProxyActions
23
+ action.plan_event(CheckOnProxyActions, POLL_INTERVAL, optional: true)
26
24
  end
27
25
 
28
26
  def check_triggered
@@ -44,9 +42,7 @@ module Actions
44
42
 
45
43
  def notify(event, tasks)
46
44
  tasks.each do |task|
47
- action.world.event task.execution_plan_id,
48
- task.step_id,
49
- event
45
+ action.plan_event(event, execution_plan_id: task.execution_plan_id, step_id: task.step_id)
50
46
  end
51
47
  end
52
48
 
@@ -140,12 +140,17 @@ module ForemanTasks
140
140
 
141
141
  def main_action
142
142
  return @main_action if defined?(@main_action)
143
+
144
+ @main_action = execution_plan && execution_plan.root_plan_step.try(:action, execution_plan)
143
145
  if active_job?
144
146
  job_data = active_job_data
145
- @main_action = active_job_action(job_data['job_class'], job_data['arguments'])
146
- else
147
- @main_action = execution_plan && execution_plan.root_plan_step.try(:action, execution_plan)
147
+ begin
148
+ @main_action = active_job_action(job_data['job_class'], job_data['arguments'])
149
+ rescue => e
150
+ Foreman::Logging.exception("Failed to load ActiveJob for task #{id}", e, :logger => 'foreman-tasks')
151
+ end
148
152
  end
153
+ @main_action
149
154
  end
150
155
 
151
156
  # The class for ActiveJob jobs in Dynflow, JobWrapper is not expected to
@@ -12,7 +12,7 @@ namespace :foreman_tasks do
12
12
 
13
13
  * TASK_SEARCH : scoped search filter (example: 'label = "Actions::Foreman::Host::ImportFacts"')
14
14
  * TASK_FILE : file to export to
15
- * TASK_FORMAT : format to use for the export (either html or csv)
15
+ * TASK_FORMAT : format to use for the export (either html, html-dir or csv)
16
16
  * TASK_DAYS : number of days to go back
17
17
 
18
18
  If TASK_SEARCH is not defined, it defaults to all tasks in the past 7 days and
@@ -185,23 +185,27 @@ namespace :foreman_tasks do
185
185
  end
186
186
 
187
187
  class PageHelper
188
- def self.pagify(template)
189
- pre = <<-HTML
190
- <html>
191
- <head>
192
- <title>Dynflow Console</title>
193
- <script src="jquery.js"></script>
194
- <link rel="stylesheet" type="text/css" href="bootstrap.css">
195
- <link rel="stylesheet" type="text/css" href="application.css">
196
- <script src="bootstrap.js"></script>
197
- <script src="run_prettify.js"></script>
198
- <script src="application.js"></script>
199
- </head>
200
- <body>
201
- #{template}
202
- <body>
203
- </html>
188
+ def self.pagify(io, template = nil)
189
+ io.write <<~HTML
190
+ <html>
191
+ <head>
192
+ <title>Dynflow Console</title>
193
+ <script src="jquery.js"></script>
194
+ <link rel="stylesheet" type="text/css" href="bootstrap.css">
195
+ <link rel="stylesheet" type="text/css" href="application.css">
196
+ <script src="bootstrap.js"></script>
197
+ <script src="run_prettify.js"></script>
198
+ <script src="application.js"></script>
199
+ </head>
200
+ <body>
204
201
  HTML
202
+ if block_given?
203
+ yield io
204
+ else
205
+ io.write template
206
+ end
207
+ ensure
208
+ io.write '</body></html>'
205
209
  end
206
210
 
207
211
  def self.copy_assets(tmp_dir)
@@ -216,13 +220,64 @@ namespace :foreman_tasks do
216
220
  end
217
221
  end
218
222
 
219
- def self.generate_index(tasks)
220
- html = '<div><table class="table">'
221
- tasks.order('started_at desc').all.each do |task|
222
- html << "<tr><td><a href=\"#{task.id}.html\">#{task.label}</a></td><td>#{task.started_at}</td>\
223
- <td>#{task.state}</td><td>#{task.result}</td></tr>"
223
+ def self.generate_with_index(io)
224
+ io.write '<div><table class="table">'
225
+ yield io
226
+ ensure
227
+ io.write '</table></div>'
228
+ end
229
+
230
+ def self.generate_index_entry(io, task)
231
+ io << <<~HTML
232
+ <tr>
233
+ <td><a href=\"#{task.id}.html\">#{task.label}</a></td>
234
+ <td>#{task.started_at}</td>
235
+ <td>#{task.state}</td>
236
+ <td>#{task.result}</td>
237
+ </tr>
238
+ HTML
239
+ end
240
+ end
241
+
242
+ def csv_export(export_filename, tasks)
243
+ CSV.open(export_filename, 'wb') do |csv|
244
+ csv << %w[id state type label result parent_task_id started_at ended_at]
245
+ tasks.find_each do |task|
246
+ csv << [task.id, task.state, task.type, task.label, task.result,
247
+ task.parent_task_id, task.started_at, task.ended_at]
224
248
  end
225
- html << '</table></div>'
249
+ end
250
+ end
251
+
252
+ def html_export(workdir, tasks)
253
+ PageHelper.copy_assets(workdir)
254
+
255
+ renderer = TaskRender.new
256
+ total = tasks.count
257
+ index = File.open(File.join(workdir, 'index.html'), 'w')
258
+
259
+ File.open(File.join(workdir, 'index.html'), 'w') do |index|
260
+ PageHelper.pagify(index) do |io|
261
+ PageHelper.generate_with_index(io) do |index|
262
+ tasks.find_each.each_with_index do |task, count|
263
+ File.open(File.join(workdir, "#{task.id}.html"), 'w') { |file| PageHelper.pagify(file, renderer.render_task(task)) }
264
+ PageHelper.generate_index_entry(index, task)
265
+ puts "#{count + 1}/#{total}"
266
+ end
267
+ end
268
+ end
269
+ end
270
+ end
271
+
272
+ def generate_filename(format)
273
+ base = "/tmp/task-export-#{Time.now.to_i}"
274
+ case format
275
+ when 'html'
276
+ base + '.tar.gz'
277
+ when 'csv'
278
+ base + '.csv'
279
+ when 'html-dir'
280
+ base
226
281
  end
227
282
  end
228
283
 
@@ -239,36 +294,25 @@ namespace :foreman_tasks do
239
294
  end
240
295
 
241
296
  format = ENV['TASK_FORMAT'] || 'html'
242
- export_filename = ENV['TASK_FILE'] || "/tmp/task-export-#{Time.now.to_i}.#{format == 'csv' ? 'csv' : 'tar.gz'}"
297
+ export_filename = ENV['TASK_FILE'] || generate_filename(format)
243
298
 
244
- tasks = ForemanTasks::Task.search_for(filter)
299
+ tasks = ForemanTasks::Task.search_for(filter).order(:started_at => :desc)
245
300
 
246
301
  puts _("Exporting all tasks matching filter #{filter}")
247
302
  puts _("Gathering #{tasks.count} tasks.")
248
- if format == 'html'
303
+ case format
304
+ when 'html'
249
305
  Dir.mktmpdir('task-export') do |tmp_dir|
250
- PageHelper.copy_assets(tmp_dir)
251
-
252
- renderer = TaskRender.new
253
- total = tasks.count
254
-
255
- tasks.find_each.with_index do |task, count|
256
- File.open(File.join(tmp_dir, "#{task.id}.html"), 'w') { |file| file.write(PageHelper.pagify(renderer.render_task(task))) }
257
- puts "#{count + 1}/#{total}"
258
- end
259
-
260
- File.open(File.join(tmp_dir, 'index.html'), 'w') { |file| file.write(PageHelper.pagify(PageHelper.generate_index(tasks))) }
261
-
306
+ html_export(tmp_dir, tasks)
262
307
  system("tar", "czf", export_filename, tmp_dir)
263
308
  end
264
- elsif format == 'csv'
265
- CSV.open(export_filename, 'wb') do |csv|
266
- csv << %w[id state type label result parent_task_id started_at ended_at]
267
- tasks.find_each do |task|
268
- csv << [task.id, task.state, task.type, task.label, task.result,
269
- task.parent_task_id, task.started_at, task.ended_at]
270
- end
271
- end
309
+ when 'html-dir'
310
+ FileUtils.mkdir_p(export_filename)
311
+ html_export(export_filename, tasks)
312
+ when 'csv'
313
+ csv_export(export_filename, tasks)
314
+ else
315
+ raise "Unkonwn export format '#{format}'"
272
316
  end
273
317
 
274
318
  puts "Created #{export_filename}"
@@ -1,3 +1,3 @@
1
1
  module ForemanTasks
2
- VERSION = '4.1.2'.freeze
2
+ VERSION = '4.1.3'.freeze
3
3
  end
@@ -15,22 +15,29 @@ export const convertDashboardQuery = query => {
15
15
  state,
16
16
  result,
17
17
  search,
18
+ ...rest
18
19
  } = query;
19
20
 
20
21
  const hours = timeToHoursNumber(timeHorizon);
21
22
  const timestamp = new Date(new Date() - hours * 60 * 60 * 1000);
22
23
  let dashboardTime = '';
23
24
  const stateQuery = state ? `state=${state}` : '';
24
- const resultQuery = result ? `result=${result}` : '';
25
+ let resultQuery = '';
26
+ if (result === 'other') {
27
+ resultQuery = 'result ^ (pending, cancelled)';
28
+ } else {
29
+ resultQuery = result ? `result=${result}` : '';
30
+ }
25
31
  if (timeMode === TASKS_DASHBOARD_JS_QUERY_MODES.RECENT) {
26
- dashboardTime = `(state_updated_at>${timestamp.toISOString()} or state_updated_at = NULL)`;
32
+ dashboardTime = `state_updated_at>${timestamp.toISOString()} or null? state_updated_at`;
27
33
  } else if (timeMode === TASKS_DASHBOARD_JS_QUERY_MODES.OLDER) {
28
- dashboardTime = `(state_updated_at>${timestamp.toISOString()})`;
34
+ dashboardTime = `state_updated_at<=${timestamp.toISOString()}`;
29
35
  }
30
36
  const newQuery = [stateQuery, resultQuery, search, dashboardTime]
31
37
  .filter(Boolean)
38
+ .map(q => `(${q})`)
32
39
  .join(' and ');
33
- return newQuery;
40
+ return newQuery ? { search: newQuery, ...rest } : rest;
34
41
  };
35
42
 
36
43
  export const resumeToastInfo = {
@@ -27,9 +27,18 @@ describe('convertDashboardQuery', () => {
27
27
  result: 'error',
28
28
  search: 'action~job',
29
29
  };
30
- expect(convertDashboardQuery(query)).toEqual(
31
- 'state=stopped and result=error and action~job and (state_updated_at>2020-05-01T11:01:58.135Z or state_updated_at = NULL)'
32
- );
30
+ const expected =
31
+ '(state=stopped) and (result=error) and (action~job) and (state_updated_at>2020-05-01T11:01:58.135Z or null? state_updated_at)';
32
+
33
+ expect(convertDashboardQuery(query)).toEqual({ search: expected });
34
+
35
+ const query2 = {
36
+ ...query,
37
+ time_mode: TASKS_DASHBOARD_JS_QUERY_MODES.OLDER,
38
+ };
39
+ const expected2 =
40
+ '(state=stopped) and (result=error) and (action~job) and (state_updated_at<=2020-05-01T11:01:58.135Z)';
41
+ expect(convertDashboardQuery(query2)).toEqual({ search: expected2 });
33
42
  // Cleanup
34
43
  global.Date = realDate;
35
44
  });
@@ -37,10 +46,23 @@ describe('convertDashboardQuery', () => {
37
46
  const query = {
38
47
  search: 'action~job',
39
48
  };
40
- expect(convertDashboardQuery(query)).toEqual('action~job');
49
+ expect(convertDashboardQuery(query)).toEqual({ search: '(action~job)' });
41
50
  });
42
51
  it('convertDashboardQuery should work with no query', () => {
43
52
  const query = {};
44
- expect(convertDashboardQuery(query)).toEqual('');
53
+ expect(convertDashboardQuery(query)).toEqual({});
54
+ });
55
+ it('convertDashboardQuery should not override unknown keys', () => {
56
+ const query = { weather: 'nice', search: 'okay', number: 7 };
57
+ expect(convertDashboardQuery(query)).toEqual({
58
+ ...query,
59
+ search: '(okay)',
60
+ });
61
+ });
62
+ it('convertDashboardQuery should expand other result', () => {
63
+ const query = { result: 'other' };
64
+ expect(convertDashboardQuery(query)).toEqual({
65
+ search: '(result ^ (pending, cancelled))',
66
+ });
45
67
  });
46
68
  });
@@ -18,9 +18,14 @@ import {
18
18
  resumeTaskRequest,
19
19
  forceCancelTaskRequest,
20
20
  } from '../TaskActions';
21
+ import { convertDashboardQuery } from '../TaskActions/TaskActionHelpers';
21
22
 
22
23
  export const getTableItems = url =>
23
- getTableItemsAction(TASKS_TABLE_ID, getURIQuery(url), getApiPathname(url));
24
+ getTableItemsAction(
25
+ TASKS_TABLE_ID,
26
+ convertDashboardQuery(getURIQuery(url)),
27
+ getApiPathname(url)
28
+ );
24
29
 
25
30
  export const reloadPage = (url, parentTaskID) => dispatch => {
26
31
  dispatch(getTableItems(url));
@@ -2,6 +2,7 @@ import URI from 'urijs';
2
2
  import { translate as __, documentLocale } from 'foremanReact/common/I18n';
3
3
  import humanizeDuration from 'humanize-duration';
4
4
  import { isoCompatibleDate } from 'foremanReact/common/helpers';
5
+ import { convertDashboardQuery } from '../TaskActions/TaskActionHelpers';
5
6
 
6
7
  export const updateURlQuery = (query, history) => {
7
8
  const uri = new URI(history.location.pathname + history.location.search);
@@ -17,7 +18,7 @@ export const getApiPathname = url => {
17
18
  export const getCSVurl = (path, query) => {
18
19
  let url = new URI(path);
19
20
  url = url.pathname(`${url.pathname()}.csv`);
20
- url.addSearch(query);
21
+ url.addSearch(convertDashboardQuery(query));
21
22
  return url.toString();
22
23
  };
23
24
 
@@ -77,7 +77,7 @@ const TasksTablePage = ({
77
77
  </Button>
78
78
  {props.status === STATUS.PENDING && <Spinner size="md" loading />}
79
79
  <ExportButton
80
- url={getCSVurl(url, uriQuery)}
80
+ url={getCSVurl(history.location.pathname, uriQuery)}
81
81
  title={__('Export All')}
82
82
  />
83
83
  <ActionSelectButton
@@ -32,7 +32,7 @@ describe('getCSVurl', () => {
32
32
  const url = '/foreman_tasks/tasks';
33
33
  const query = { state: 'stopped' };
34
34
  expect(getCSVurl(url, query)).toEqual(
35
- '/foreman_tasks/tasks.csv?state=stopped'
35
+ '/foreman_tasks/tasks.csv?search=%28state%3Dstopped%29'
36
36
  );
37
37
  });
38
38
  it('should return currect url for subtasks', () => {
@@ -92,7 +92,7 @@ exports[`TasksTablePage rendering render with Breadcrubs and edit permissions 1`
92
92
  />
93
93
  <ExportButton
94
94
  title="Export All"
95
- url="/foreman_tasks/tasks.csv?action=%22some-name%22&state=stopped"
95
+ url="/foreman_tasks/tasks.csv?search=%28state%3Dstopped%29"
96
96
  />
97
97
  <ActionSelectButton
98
98
  disabled={true}
@@ -227,7 +227,7 @@ exports[`TasksTablePage rendering render with minimal props 1`] = `
227
227
  />
228
228
  <ExportButton
229
229
  title="Export All"
230
- url="/foreman_tasks/tasks.csv?action=%22some-name%22&state=stopped"
230
+ url="/foreman_tasks/tasks.csv?search=%28state%3Dstopped%29"
231
231
  />
232
232
  <ActionSelectButton
233
233
  disabled={true}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman-tasks
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.2
4
+ version: 4.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Nečas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-15 00:00:00.000000000 Z
11
+ date: 2021-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dynflow
@@ -198,7 +198,6 @@ files:
198
198
  - app/models/foreman_tasks/task_groups/recurring_logic_task_group.rb
199
199
  - app/models/foreman_tasks/triggering.rb
200
200
  - app/models/setting/foreman_tasks.rb
201
- - app/services/foreman_tasks/dashboard_table_filter.rb
202
201
  - app/services/foreman_tasks/proxy_selector.rb
203
202
  - app/services/foreman_tasks/troubleshooting_help_generator.rb
204
203
  - app/services/ui_notifications/tasks.rb
@@ -335,7 +334,6 @@ files:
335
334
  - test/unit/actions/recurring_action_test.rb
336
335
  - test/unit/cleaner_test.rb
337
336
  - test/unit/config/environment.rb
338
- - test/unit/dashboard_table_filter_test.rb
339
337
  - test/unit/dynflow_console_authorizer_test.rb
340
338
  - test/unit/locking_test.rb
341
339
  - test/unit/otp_manager_test.rb
@@ -650,7 +648,6 @@ test_files:
650
648
  - test/unit/actions/recurring_action_test.rb
651
649
  - test/unit/cleaner_test.rb
652
650
  - test/unit/config/environment.rb
653
- - test/unit/dashboard_table_filter_test.rb
654
651
  - test/unit/dynflow_console_authorizer_test.rb
655
652
  - test/unit/locking_test.rb
656
653
  - test/unit/otp_manager_test.rb
@@ -1,56 +0,0 @@
1
- module ForemanTasks
2
- # narrows the scope for the tasks table based on params coming from tasks dashboard
3
- #
4
- # Supported filters:
5
- #
6
- # * :result
7
- # * :state
8
- # * :time_horizon - expected format of Hxy, where the xy is the time horizon in hours we're interested in
9
- # :time_mode can be set to 'recent' to filter the recent tasks, or 'older' (default) to filter earlier ones
10
- class DashboardTableFilter
11
- def initialize(scope, params)
12
- @scope = scope
13
- @params = params
14
- end
15
-
16
- def scope
17
- @new_scope = @scope
18
- scope_by(:result)
19
- scope_by(:state)
20
- scope_by_time
21
- @new_scope
22
- end
23
-
24
- private
25
-
26
- def scope_by(field)
27
- if (field == :result) && (@params[field] == 'other')
28
- @new_scope = @new_scope.where(:result => ['cancelled', 'pending'])
29
- elsif @params[field].present?
30
- @new_scope = @new_scope.where(field => @params[field])
31
- end
32
- end
33
-
34
- def scope_by_time
35
- return if @params[:time_horizon].blank?
36
- hours = if @params[:time_horizon].casecmp('week') == 0
37
- 24 * 7
38
- else
39
- @params[:time_horizon][/\AH(\d{1,2})$/i, 1]
40
- end
41
-
42
- unless hours
43
- raise Foreman::Exception, 'Unexpected format of time: should be in form of "H24" or equal to "week"'
44
- end
45
- timestamp = Time.now.utc - hours.to_i.hours
46
- case @params[:time_mode]
47
- when 'recent'
48
- operator = '>'
49
- else
50
- operator = '<'
51
- search_suffix = 'OR state_updated_at IS NULL'
52
- end
53
- @new_scope = @new_scope.where("state_updated_at #{operator} ? #{search_suffix}", timestamp)
54
- end
55
- end
56
- end
@@ -1,77 +0,0 @@
1
- require 'foreman_tasks_test_helper'
2
-
3
- class DashboardTableFilterTest < ActiveSupport::TestCase
4
- before do
5
- ::ForemanTasks::Task.delete_all
6
- end
7
-
8
- describe ForemanTasks::DashboardTableFilter do
9
- before do
10
- @tasks_builder = HistoryTasksBuilder.new
11
- @scope = ForemanTasks::Task.all
12
- @tasks_builder.build
13
- end
14
-
15
- let :subject do
16
- ForemanTasks::DashboardTableFilter.new(@scope, params)
17
- end
18
-
19
- let :filtered_scope do
20
- subject.scope
21
- end
22
-
23
- describe 'by result' do
24
- let(:params) { { result: 'warning' } }
25
-
26
- it 'filters' do
27
- _(filtered_scope.count).must_equal @tasks_builder.distribution['stopped'][:by_result]['warning'][:total]
28
- end
29
- end
30
-
31
- describe 'by state' do
32
- let(:params) { { state: 'running' } }
33
-
34
- it 'filters' do
35
- _(filtered_scope.count).must_equal @tasks_builder.distribution['running'][:total]
36
- end
37
- end
38
-
39
- describe 'recent' do
40
- let(:params) do
41
- { state: 'running',
42
- time_horizon: 'H24',
43
- time_mode: 'recent' }
44
- end
45
-
46
- it 'filters' do
47
- _(filtered_scope.count).must_equal @tasks_builder.distribution['running'][:recent]
48
- end
49
- end
50
-
51
- describe 'recent week time horizon' do
52
- let(:params) do
53
- { state: 'running',
54
- time_horizon: 'week',
55
- time_mode: 'recent' }
56
- end
57
-
58
- it 'filters' do
59
- _(filtered_scope.count).must_equal @tasks_builder.distribution['running'][:recent]
60
- end
61
- end
62
-
63
- describe 'older' do
64
- let(:params) do
65
- { state: 'running',
66
- time_horizon: 'H24',
67
- time_mode: 'older' }
68
- end
69
-
70
- it 'filters' do
71
- old_tasks_count = @tasks_builder.distribution['running'][:total] -
72
- @tasks_builder.distribution['running'][:recent]
73
- _(filtered_scope.count).must_equal old_tasks_count
74
- end
75
- end
76
- end
77
- end