defmodule AprsmeWeb.ThemeManagerTest do use ExUnit.Case, async: true alias AprsmeWeb.ThemeManager alias Phoenix.LiveView.Socket describe "resolve_theme/2" do test "returns system_preference for 'auto'" do assert ThemeManager.resolve_theme("auto", "dark") == "dark" assert ThemeManager.resolve_theme("auto", "light") == "light" end test "returns the explicit theme for 'light' or 'dark'" do assert ThemeManager.resolve_theme("light", "dark") == "light" assert ThemeManager.resolve_theme("dark", "light") == "dark" end test "falls back to system_preference for unknown themes" do assert ThemeManager.resolve_theme("neon", "light") == "light" assert ThemeManager.resolve_theme(nil, "dark") == "dark" end end describe "get_theme_colors/1" do test "returns dark-themed colors for 'dark'" do colors = ThemeManager.get_theme_colors("dark") assert is_map(colors) assert colors.text == "#e5e7eb" assert colors.grid == "#374151" assert colors.primary == "#3b82f6" end test "returns light-themed colors for 'light'" do colors = ThemeManager.get_theme_colors("light") assert colors.text == "#111827" assert colors.primary == "#2563eb" end test "any non-dark value returns light colors" do assert ThemeManager.get_theme_colors("auto").text == "#111827" assert ThemeManager.get_theme_colors(nil).text == "#111827" assert ThemeManager.get_theme_colors("whatever").text == "#111827" end test "dark and light colors are distinct" do dark = ThemeManager.get_theme_colors("dark") light = ThemeManager.get_theme_colors("light") refute dark.text == light.text refute dark.grid == light.grid end test "all expected keys are present" do for theme <- ["dark", "light"] do colors = ThemeManager.get_theme_colors(theme) assert Map.has_key?(colors, :text) assert Map.has_key?(colors, :grid) assert Map.has_key?(colors, :background) assert Map.has_key?(colors, :primary) assert Map.has_key?(colors, :secondary) assert Map.has_key?(colors, :accent) end end end describe "init_theme/2" do test "initializes with stored theme from session" do socket = %Socket{assigns: %{__changed__: %{}}} result = ThemeManager.init_theme(socket, %{"theme" => "dark"}) assert result.assigns.theme == "dark" assert result.assigns.resolved_theme == "dark" assert is_map(result.assigns.theme_colors) end test "defaults to 'auto' when no session theme" do socket = %Socket{assigns: %{__changed__: %{}}} result = ThemeManager.init_theme(socket, %{}) assert result.assigns.theme == "auto" # system_preference is "light" in this module assert result.assigns.resolved_theme == "light" end test "ignores unknown stored themes, defaulting to auto" do socket = %Socket{assigns: %{__changed__: %{}}} result = ThemeManager.init_theme(socket, %{"theme" => "neon"}) assert result.assigns.theme == "auto" end test "defaults to auto when session arg is omitted" do socket = %Socket{assigns: %{__changed__: %{}}} result = ThemeManager.init_theme(socket) assert result.assigns.theme == "auto" end end describe "handle_theme_change/2" do test "returns unchanged socket for invalid themes" do socket = %Socket{assigns: %{__changed__: %{}}} assert ThemeManager.handle_theme_change(socket, "invalid") == socket end test "updates assigns for valid themes" do socket = %Socket{assigns: %{__changed__: %{}}} result = ThemeManager.handle_theme_change(socket, "dark") assert result.assigns.theme == "dark" assert result.assigns.resolved_theme == "dark" end end end