berrypod/test/berrypod_web/live/admin/analytics_test.exs
jamey 7ceee9c814
All checks were successful
deploy / deploy (push) Successful in 1m19s
add dashboard filtering to analytics
Click any row in pages, sources, countries, or devices tables to
filter the entire dashboard by that dimension. Active filters show
as dismissible chips. Filters thread through all queries including
previous-period deltas. 1050 tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 13:46:34 +00:00

165 lines
5.0 KiB
Elixir

defmodule BerrypodWeb.Admin.AnalyticsTest do
use BerrypodWeb.ConnCase, async: false
import Phoenix.LiveViewTest
import Berrypod.AccountsFixtures
alias Berrypod.Analytics.{Buffer, Event}
alias Berrypod.Repo
setup do
send(Buffer, :flush)
:timer.sleep(50)
user = user_fixture()
%{user: user}
end
describe "unauthenticated" do
test "redirects to login", %{conn: conn} do
{:error, redirect} = live(conn, ~p"/admin/analytics")
assert {:redirect, %{to: path}} = redirect
assert path == ~p"/users/log-in"
end
end
describe "analytics dashboard" do
setup %{conn: conn, user: user} do
%{conn: log_in_user(conn, user)}
end
test "renders the analytics page", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/admin/analytics")
assert html =~ "Analytics"
assert html =~ "Unique visitors"
assert html =~ "Total pageviews"
assert html =~ "Bounce rate"
assert html =~ "Visit duration"
end
test "shows zero state with no data", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/admin/analytics")
assert html =~ "No data for this period"
end
test "shows data when events exist", %{conn: conn} do
now = DateTime.utc_now() |> DateTime.truncate(:second)
Repo.insert_all(Event, [
[
id: Ecto.UUID.generate(),
name: "pageview",
pathname: "/",
visitor_hash: :crypto.strong_rand_bytes(8),
session_hash: :crypto.strong_rand_bytes(8),
browser: "Chrome",
os: "macOS",
inserted_at: now
]
])
{:ok, view, _html} = live(conn, ~p"/admin/analytics")
assert has_element?(view, "[data-bars]")
end
test "changes period", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/analytics")
html = render_click(view, "change_period", %{"period" => "7d"})
assert html =~ "Analytics"
end
test "changes tab to sources", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/analytics")
html = render_click(view, "change_tab", %{"tab" => "sources"})
assert html =~ "Top sources"
assert html =~ "Top referrers"
end
test "changes tab to countries", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/analytics")
html = render_click(view, "change_tab", %{"tab" => "countries"})
assert html =~ "Countries"
end
test "changes tab to devices", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/analytics")
html = render_click(view, "change_tab", %{"tab" => "devices"})
assert html =~ "Browsers"
assert html =~ "Operating systems"
assert html =~ "Screen sizes"
end
test "changes tab to funnel", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/analytics")
html = render_click(view, "change_tab", %{"tab" => "funnel"})
assert html =~ "Conversion funnel"
end
test "clicking a source adds a filter chip", %{conn: conn} do
now = DateTime.utc_now() |> DateTime.truncate(:second)
Repo.insert_all(Event, [
[
id: Ecto.UUID.generate(),
name: "pageview",
pathname: "/",
visitor_hash: :crypto.strong_rand_bytes(8),
session_hash: :crypto.strong_rand_bytes(8),
referrer_source: "Google",
inserted_at: now
]
])
{:ok, view, _html} = live(conn, ~p"/admin/analytics")
# Switch to sources tab and click the source
render_click(view, "change_tab", %{"tab" => "sources"})
html =
render_click(view, "add_filter", %{"dimension" => "referrer_source", "value" => "Google"})
assert html =~ "Source: Google"
assert has_element?(view, "#analytics-filters")
end
test "removing a filter chip clears it", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/analytics")
render_click(view, "add_filter", %{"dimension" => "country_code", "value" => "GB"})
assert render(view) =~ "Country: United Kingdom"
html = render_click(view, "remove_filter", %{"dimension" => "country_code"})
refute html =~ "Country: United Kingdom"
end
test "clear all removes all filters", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/analytics")
render_click(view, "add_filter", %{"dimension" => "country_code", "value" => "GB"})
render_click(view, "add_filter", %{"dimension" => "browser", "value" => "Chrome"})
assert render(view) =~ "Clear all"
html = render_click(view, "clear_filters", %{})
refute html =~ "Country: United Kingdom"
refute html =~ "Browser: Chrome"
end
test "changing period preserves filters", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/analytics")
render_click(view, "add_filter", %{"dimension" => "country_code", "value" => "GB"})
html = render_click(view, "change_period", %{"period" => "7d"})
assert html =~ "Country: United Kingdom"
end
end
end