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

feat: adds ability to archive tasks #837

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions app/helpers/maintenance_tasks/tasks_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module TasksHelper
"cancelling" => ["is-light"],
"cancelled" => ["is-dark"],
"errored" => ["is-danger"],
"archived" => ["is-black"],
}

# Formats a run backtrace.
Expand Down Expand Up @@ -59,8 +60,10 @@ def progress(run)
# @param status [String] the status for the Run.
# @return [String] the span element containing the status, with the
# appropriate tag class attached.
def status_tag(status)
tag.span(status.capitalize, class: ["tag"] + STATUS_COLOURS.fetch(status))
def status_tag(status, size = :normal)
classes = ["tag"] + STATUS_COLOURS.fetch(status)
classes << "is-large" if size == :large
tag.span(status.capitalize, class: classes)
end

# Reports the approximate elapsed time a Run has been processed so far based
Expand Down
2 changes: 2 additions & 0 deletions app/models/maintenance_tasks/task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class NotFoundError < NameError; end
# @api private
class_attribute :collection_builder_strategy, default: NullCollectionBuilder.new

class_attribute :archived, default: false

define_callbacks :start, :complete, :error, :cancel, :pause, :interrupt

class << self
Expand Down
19 changes: 13 additions & 6 deletions app/models/maintenance_tasks/task_data_index.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,22 @@ class << self
def available_tasks
tasks = []

task_names = Task.available_tasks.map(&:name)
available_tasks = Task.available_tasks
task_names = available_tasks.map(&:name)

active_runs = Run.with_attached_csv.active.where(task_name: task_names)
active_runs.each do |run|
tasks << TaskDataIndex.new(run.task_name, run)
task = available_tasks.find { |task| task.name == run.task_name }
tasks << TaskDataIndex.new(run.task_name, task.archived?, run)
task_names.delete(run.task_name)
end

completed_runs = Run.completed.where(task_name: task_names)
last_runs = Run.with_attached_csv.where(id: completed_runs.select("MAX(id) as id").group(:task_name))
task_names.map do |task_name|
last_run = last_runs.find { |run| run.task_name == task_name }
tasks << TaskDataIndex.new(task_name, last_run)
task = available_tasks.find { |task| task.name == task_name }
tasks << TaskDataIndex.new(task_name, task.archived?, last_run)
end

# We add an additional sorting key (status) to avoid possible
Expand All @@ -52,14 +55,16 @@ def available_tasks
# @param name [String] the name of the Task subclass.
# @param related_run [MaintenanceTasks::Run] optionally, a Run record to
# set for the Task.
def initialize(name, related_run = nil)
def initialize(name, archived, related_run = nil)
@name = name
@archived = archived
@related_run = related_run
end

# @return [String] the name of the Task.
attr_reader :name
attr_reader :related_run
attr_reader :archived

alias_method :to_s, :name

Expand All @@ -68,14 +73,16 @@ def initialize(name, related_run = nil)
#
# @return [String] the Task status.
def status
related_run&.status || "new"
archived ? "archived" : related_run&.status || "new"
end

# Retrieves the Task's category, which is one of active, new, or completed.
#
# @return [Symbol] the category of the Task.
def category
if related_run.present? && related_run.active?
if archived
:archived
elsif related_run.present? && related_run.active?
:active
elsif related_run.nil?
:new
Expand Down
5 changes: 5 additions & 0 deletions app/models/maintenance_tasks/task_data_show.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ def deleted?
true
end

# @return [Boolean] whether the Task has been archived.
def archived?
!deleted? && Task.named(name).archived?
end

# @return [Boolean] whether the Task inherits from CsvTask.
def csv_task?
!deleted? && Task.named(name).has_csv_content?
Expand Down
2 changes: 1 addition & 1 deletion app/views/maintenance_tasks/tasks/_task.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<%= status_tag(task.status) %>
</h3>

<% if (run = task.related_run) %>
<% if !task.archived && (run = task.related_run) %>
<h5 class="title is-5">
<%= time_tag run.created_at, title: run.created_at %>
</h5>
Expand Down
4 changes: 4 additions & 0 deletions app/views/maintenance_tasks/tasks/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,9 @@
<h3 class="title is-3">Completed Tasks</h3>
<%= render partial: 'task', collection: completed_tasks %>
<% end %>
<% if archived_tasks = @available_tasks[:archived] %>
<h3 class="title is-3">Archived Tasks</h3>
<%= render partial: 'task', collection: archived_tasks %>
<% end %>
<% end %>
<% end %>
3 changes: 2 additions & 1 deletion app/views/maintenance_tasks/tasks/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<h1 class="title is-1">
<%= @task %>
<%= @task.archived? && status_tag("archived", :large) %>
</h1>

<div class="buttons">
Expand Down Expand Up @@ -29,7 +30,7 @@
<% end %>
<%= render "maintenance_tasks/tasks/custom", form: form %>
<div class="block">
<%= form.submit 'Run', class: "button is-success", disabled: @task.deleted? %>
<%= form.submit 'Run', class: "button is-success", disabled: @task.deleted? || @task.archived? %>
</div>
<% end %>
</div>
Expand Down
13 changes: 13 additions & 0 deletions test/dummy/app/tasks/maintenance/archived_task.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

module Maintenance
class ArchivedTask < MaintenanceTasks::Task
self.archived = true

no_collection

def process
Rails.logger.debug("I am archived and cannot be run")
end
end
end
28 changes: 19 additions & 9 deletions test/models/maintenance_tasks/task_data_index_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module MaintenanceTasks
class TaskDataIndexTest < ActiveSupport::TestCase
test ".available_tasks returns a list of Tasks as TaskDataShow, ordered alphabetically by name" do
expected = [
"Maintenance::ArchivedTask",
"Maintenance::BatchImportPostsTask",
"Maintenance::CallbackTestTask",
"Maintenance::CancelledEnqueueTask",
Expand All @@ -29,48 +30,57 @@ class TaskDataIndexTest < ActiveSupport::TestCase

test "#new sets last_run if one is passed as an argument" do
run = Run.create!(task_name: "Maintenance::UpdatePostsTask")
task_data = TaskDataIndex.new("Maintenance::UpdatePostsTask", run)
task_data = TaskDataIndex.new("Maintenance::UpdatePostsTask", false, run)

assert_equal "Maintenance::UpdatePostsTask", task_data.to_s
end

test "#to_s returns the name of the Task" do
task_data = TaskDataIndex.new("Maintenance::UpdatePostsTask")
task_data = TaskDataIndex.new("Maintenance::UpdatePostsTask", false)

assert_equal "Maintenance::UpdatePostsTask", task_data.to_s
end

test "#status is new when Task does not have any Runs" do
task_data = TaskDataIndex.new("Maintenance::UpdatePostsTask")
test "#status is archived when Task is archived" do
task_data = TaskDataIndex.new("Maintenance::UpdatePostsTask", true)
assert_equal "archived", task_data.status
end

test "#status is new when Task does not have any Runs and is not archived" do
task_data = TaskDataIndex.new("Maintenance::UpdatePostsTask", false)
assert_equal "new", task_data.status
end

test "#status is the latest Run status" do
test "#status is the latest Run status if the Task is not archived" do
run = Run.create!(
task_name: "Maintenance::UpdatePostsTask",
status: :paused,
)
task_data = TaskDataIndex.new("Maintenance::UpdatePostsTask", run)
task_data = TaskDataIndex.new("Maintenance::UpdatePostsTask", false, run)
assert_equal "paused", task_data.status
end

test "#category returns :active if the task is active" do
run = Run.create!(task_name: "Maintenance::UpdatePostsTask")
task_data = TaskDataIndex.new("Maintenance::UpdatePostsTask", run)
task_data = TaskDataIndex.new("Maintenance::UpdatePostsTask", false, run)
assert_equal :active, task_data.category
end

test "#category returns :new if the task is new" do
assert_equal :new, TaskDataIndex.new("Maintenance::SomeNewTask").category
assert_equal :new, TaskDataIndex.new("Maintenance::SomeNewTask", false).category
end

test "#category returns :completed if the task is completed" do
run = Run.create!(
task_name: "Maintenance::UpdatePostsTask",
status: :succeeded,
)
task_data = TaskDataIndex.new("Maintenance::UpdatePostsTask", run)
task_data = TaskDataIndex.new("Maintenance::UpdatePostsTask", false, run)
assert_equal :completed, task_data.category
end

test "#category returns :archived if the task is archived" do
assert_equal :archived, TaskDataIndex.new("Maintenance::SomeNewTask", true).category
end
end
end
12 changes: 12 additions & 0 deletions test/models/maintenance_tasks/task_data_show_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@ class TaskDataShowTest < ActiveSupport::TestCase
refute_predicate TaskDataShow.new("Maintenance::UpdatePostsTask"), :deleted?
end

test "#archived? returns true if the Task is archived" do
assert_predicate TaskDataShow.new("Maintenance::ArchivedTask"), :archived?
end

test "#archived? returns false if the Task is not archived" do
refute_predicate TaskDataShow.new("Maintenance::TestTask"), :archived?
end

test "#archived? returns false if the Task is deleted" do
refute_predicate TaskDataShow.new("Maintenance::DoesNotExist"), :archived?
end

test "#csv_task? returns true if the Task includes the CsvTask module" do
assert_predicate TaskDataShow.new("Maintenance::ImportPostsTask"), :csv_task?
end
Expand Down
5 changes: 5 additions & 0 deletions test/models/maintenance_tasks/task_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module MaintenanceTasks
class TaskTest < ActiveSupport::TestCase
test ".available_tasks returns list of tasks that inherit from the Task superclass" do
expected = [
"Maintenance::ArchivedTask",
"Maintenance::BatchImportPostsTask",
"Maintenance::CallbackTestTask",
"Maintenance::CancelledEnqueueTask",
Expand Down Expand Up @@ -97,5 +98,9 @@ class TaskTest < ActiveSupport::TestCase
ensure
Maintenance::TestTask.throttle_conditions = []
end

test ".archived inherits conditions from superclass" do
assert_equal false, Maintenance::TestTask.archived
end
end
end
Loading