defmodule BDS.UI.TaskGroupingTest do use ExUnit.Case, async: true alias BDS.UI.TaskGrouping defp task(id, status, opts \\ %{}) do %{ id: id, name: Map.get(opts, :name, "Task #{id}"), status: status, progress: Map.get(opts, :progress), message: nil, group_id: Map.get(opts, :group_id), group_name: Map.get(opts, :group_name) } end describe "build_task_entries/1" do test "tasks without a group stay single entries in order" do entries = TaskGrouping.build_task_entries([task("a", :running), task("b", :completed)]) assert [{:single, %{id: "a"}}, {:single, %{id: "b"}}] = entries end test "tasks with a group_id are grouped by first-seen order" do entries = TaskGrouping.build_task_entries([ task("a", :running, %{group_id: "g1", group_name: "Import"}), task("b", :running), task("c", :pending, %{group_id: "g1", group_name: "Import"}), task("d", :completed, %{group_id: "g2", group_name: "Upload"}) ]) assert [ {:group, "g1", "Import", [%{id: "a"}, %{id: "c"}]}, {:single, %{id: "b"}}, {:group, "g2", "Upload", [%{id: "d"}]} ] = entries end test "group label falls back to the group_id when no group_name is set" do assert [{:group, "g1", "g1", [_]}] = TaskGrouping.build_task_entries([task("a", :running, %{group_id: "g1"})]) end end describe "summarize_task_group/1" do test "counts statuses and averages progress contributions" do summary = TaskGrouping.summarize_task_group([ task("a", :running, %{progress: 0.5}), task("b", :pending), task("c", :completed) ]) assert summary.total == 3 assert summary.running == 1 assert summary.pending == 1 assert summary.completed == 1 assert summary.failed == 0 assert summary.cancelled == 0 # contributions: 0.5 (running) + 0 (pending) + 1.0 (completed) assert_in_delta summary.progress, 0.5, 0.001 end test "finished failures and cancellations count as full progress" do summary = TaskGrouping.summarize_task_group([task("a", :failed), task("b", :cancelled)]) assert summary.progress == 1.0 assert summary.failed == 1 assert summary.cancelled == 1 end test "empty group summarizes to zero" do assert %{total: 0, progress: +0.0} = TaskGrouping.summarize_task_group([]) end end end