diff --git a/test/towerops_web/components/cookie_consent_test.exs b/test/towerops_web/components/cookie_consent_test.exs
new file mode 100644
index 00000000..e5e980f5
--- /dev/null
+++ b/test/towerops_web/components/cookie_consent_test.exs
@@ -0,0 +1,61 @@
+defmodule ToweropsWeb.Components.CookieConsentTest do
+ use ExUnit.Case, async: true
+
+ import Phoenix.Component
+ import Phoenix.LiveViewTest
+
+ alias ToweropsWeb.Components.CookieConsent
+
+ describe "banner/1" do
+ test "renders consent banner when requires_consent is true" do
+ assigns = %{requires_consent: true}
+
+ html =
+ rendered_to_string(~H"""
+
+ """)
+
+ assert html =~ ~s(id="cookie-consent-banner")
+ assert html =~ "We respect your privacy"
+ assert html =~ "essential cookies"
+ assert html =~ ~s(href="/privacy")
+ assert html =~ "Accept"
+ end
+
+ test "renders nothing when requires_consent is false" do
+ assigns = %{requires_consent: false}
+
+ html =
+ rendered_to_string(~H"""
+
+ """)
+
+ assert html == ""
+ end
+
+ test "has proper accessibility attributes" do
+ assigns = %{requires_consent: true}
+
+ html =
+ rendered_to_string(~H"""
+
+ """)
+
+ assert html =~ ~s(role="dialog")
+ assert html =~ ~s(aria-label="Cookie consent")
+ assert html =~ ~s(aria-live="polite")
+ end
+
+ test "has functioning accept button with data attribute" do
+ assigns = %{requires_consent: true}
+
+ html =
+ rendered_to_string(~H"""
+
+ """)
+
+ assert html =~ ~s(data-cookie-consent="accept")
+ assert html =~ ~s(type="button")
+ end
+ end
+end
diff --git a/test/towerops_web/controllers/api/param_filter_test.exs b/test/towerops_web/controllers/api/param_filter_test.exs
new file mode 100644
index 00000000..45e6da62
--- /dev/null
+++ b/test/towerops_web/controllers/api/param_filter_test.exs
@@ -0,0 +1,53 @@
+defmodule ToweropsWeb.Api.ParamFilterTest do
+ use ExUnit.Case, async: true
+
+ alias ToweropsWeb.Api.ParamFilter
+
+ describe "strip_sensitive/1" do
+ test "removes sensitive identity fields from params" do
+ params = %{
+ "name" => "Test Device",
+ "ip_address" => "10.0.0.1",
+ "organization_id" => "org-123",
+ "id" => "device-456",
+ "inserted_at" => "2024-01-01T00:00:00Z"
+ }
+
+ result = ParamFilter.strip_sensitive(params)
+
+ assert result == %{"name" => "Test Device", "ip_address" => "10.0.0.1"}
+ end
+
+ test "preserves non-sensitive fields" do
+ params = %{"name" => "Keep", "description" => "Also keep", "tags" => ["a", "b"]}
+ assert params == ParamFilter.strip_sensitive(params)
+ end
+
+ test "handles empty map" do
+ assert %{} == ParamFilter.strip_sensitive(%{})
+ end
+
+ test "returns non-map input unchanged" do
+ assert "string" == ParamFilter.strip_sensitive("string")
+ assert nil == ParamFilter.strip_sensitive(nil)
+ assert 42 == ParamFilter.strip_sensitive(42)
+ assert [] == ParamFilter.strip_sensitive([])
+ end
+
+ test "removes all sensitive fields defined in @sensitive_fields" do
+ sensitive = ~w(id organization_id user_id created_by_id inserted_at updated_at)
+ params = Map.new(sensitive, &{&1, "value"})
+ params = Map.put(params, "safe_field", "keep")
+
+ result = ParamFilter.strip_sensitive(params)
+ assert result == %{"safe_field" => "keep"}
+ end
+
+ test "does not strip atom keys (sensitive_fields are strings)" do
+ # @sensitive_fields uses string keys, so atom keys pass through
+ params = %{name: "Test", organization_id: "org-123", id: "dev-1"}
+ result = ParamFilter.strip_sensitive(params)
+ assert result == params
+ end
+ end
+end
diff --git a/test/towerops_web/live/components/status_title_component_test.exs b/test/towerops_web/live/components/status_title_component_test.exs
new file mode 100644
index 00000000..810129a2
--- /dev/null
+++ b/test/towerops_web/live/components/status_title_component_test.exs
@@ -0,0 +1,28 @@
+defmodule ToweropsWeb.Live.Components.StatusTitleComponentTest do
+ use ExUnit.Case, async: true
+
+ import Phoenix.Component
+ import Phoenix.LiveViewTest
+
+ alias ToweropsWeb.Live.Components.StatusTitleComponent
+
+ describe "render/1" do
+ test "renders the status title watcher div" do
+ assigns = %{id: "status-title-watcher"}
+
+ html =
+ render_component(
+ fn inner_assigns ->
+ ~H"""
+ <.live_component module={StatusTitleComponent} id={@id} />
+ """
+ end,
+ assigns
+ )
+
+ assert html =~ ~s(id="status-title-watcher")
+ assert html =~ ~s(phx-hook="StatusTitle")
+ assert html =~ ~s(style="display: none;")
+ end
+ end
+end