defmodule ToweropsWeb.AgentLive.HelpersTest do use ExUnit.Case, async: true alias ToweropsWeb.AgentLive.Helpers describe "agent_status/1" do test "returns :never when last_seen_at is nil" do agent_token = %{last_seen_at: nil} assert {:never, "Never connected"} = Helpers.agent_status(agent_token) end test "returns :online when last seen less than 120 seconds ago" do last_seen = DateTime.add(DateTime.utc_now(), -60, :second) agent_token = %{last_seen_at: last_seen} assert {:online, "Online"} = Helpers.agent_status(agent_token) end test "returns :online at the boundary just under 120 seconds" do last_seen = DateTime.add(DateTime.utc_now(), -118, :second) agent_token = %{last_seen_at: last_seen} assert {:online, "Online"} = Helpers.agent_status(agent_token) end test "returns :warning when last seen between 120 and 300 seconds ago" do last_seen = DateTime.add(DateTime.utc_now(), -200, :second) agent_token = %{last_seen_at: last_seen} assert {:warning, "Warning"} = Helpers.agent_status(agent_token) end test "returns :warning at the boundary of exactly 120 seconds" do last_seen = DateTime.add(DateTime.utc_now(), -120, :second) agent_token = %{last_seen_at: last_seen} assert {:warning, "Warning"} = Helpers.agent_status(agent_token) end test "returns :warning just under 300 seconds" do last_seen = DateTime.add(DateTime.utc_now(), -299, :second) agent_token = %{last_seen_at: last_seen} assert {:warning, "Warning"} = Helpers.agent_status(agent_token) end test "returns :offline when last seen 300 or more seconds ago" do last_seen = DateTime.add(DateTime.utc_now(), -300, :second) agent_token = %{last_seen_at: last_seen} assert {:offline, "Offline"} = Helpers.agent_status(agent_token) end test "returns :offline when last seen far in the past" do last_seen = DateTime.add(DateTime.utc_now(), -86_400, :second) agent_token = %{last_seen_at: last_seen} assert {:offline, "Offline"} = Helpers.agent_status(agent_token) end end describe "status_badge_class/1" do test "returns green classes for :online" do result = Helpers.status_badge_class(:online) assert result =~ "bg-green-100" assert result =~ "text-green-800" end test "returns yellow classes for :warning" do result = Helpers.status_badge_class(:warning) assert result =~ "bg-yellow-100" assert result =~ "text-yellow-800" end test "returns red classes for :offline" do result = Helpers.status_badge_class(:offline) assert result =~ "bg-red-100" assert result =~ "text-red-800" end test "returns gray classes for :never" do result = Helpers.status_badge_class(:never) assert result =~ "bg-gray-100" assert result =~ "text-gray-800" end end describe "status_dot_class/1" do test "returns green with animation for :online" do result = Helpers.status_dot_class(:online) assert result =~ "bg-green-600" assert result =~ "animate-pulse" end test "returns yellow without animation for :warning" do result = Helpers.status_dot_class(:warning) assert result =~ "bg-yellow-600" refute result =~ "animate-pulse" end test "returns red without animation for :offline" do result = Helpers.status_dot_class(:offline) assert result =~ "bg-red-600" refute result =~ "animate-pulse" end test "returns gray without animation for :never" do result = Helpers.status_dot_class(:never) assert result =~ "bg-gray-400" refute result =~ "animate-pulse" end end describe "format_uptime/1" do test "formats days and hours when days > 0" do # 2 days and 3 hours = 2*86400 + 3*3600 = 183600 assert "2d 3h" = Helpers.format_uptime(183_600) end test "formats days and zero hours" do assert "1d 0h" = Helpers.format_uptime(86_400) end test "formats hours and minutes when hours > 0 and days == 0" do # 2 hours and 34 minutes = 2*3600 + 34*60 = 9240 assert "2h 34m" = Helpers.format_uptime(9240) end test "formats only minutes when less than one hour" do # 45 minutes = 45 * 60 = 2700 assert "45m" = Helpers.format_uptime(2700) end test "formats zero minutes" do assert "0m" = Helpers.format_uptime(0) end test "formats small number of seconds as 0m" do assert "0m" = Helpers.format_uptime(59) end test "returns Unknown for non-integer input" do assert "Unknown" = Helpers.format_uptime(nil) end test "returns Unknown for string input" do assert "Unknown" = Helpers.format_uptime("not a number") end test "returns Unknown for float input" do assert "Unknown" = Helpers.format_uptime(123.45) end end describe "format_agent_version/1" do test "prepends v to semver string" do assert "v1.2.3" = Helpers.format_agent_version("1.2.3") end test "prepends v to simple version" do assert "v0.1.0" = Helpers.format_agent_version("0.1.0") end test "returns timestamp as-is when it starts with date prefix" do timestamp = "2026-02-09T14:30:00Z" assert ^timestamp = Helpers.format_agent_version(timestamp) end test "returns timestamp as-is for other RFC 3339 formats" do timestamp = "2026-01-15T08:00:00+00:00" assert ^timestamp = Helpers.format_agent_version(timestamp) end test "returns nil for nil input" do assert nil == Helpers.format_agent_version(nil) end test "returns nil for non-binary input" do assert nil == Helpers.format_agent_version(123) end end describe "format_last_seen_with_date/2" do test "returns Never for nil datetime" do assert "Never" = Helpers.format_last_seen_with_date(nil) end test "returns Never for nil datetime with timezone" do assert "Never" = Helpers.format_last_seen_with_date(nil, "America/New_York") end test "formats relative time and full datetime for recent time" do dt = DateTime.add(DateTime.utc_now(), -30, :second) result = Helpers.format_last_seen_with_date(dt, "Etc/UTC") assert result =~ "s ago" assert result =~ "(" assert result =~ ")" end end end