foreman-tasks 4.1.2 → 4.1.3

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 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