All checks were successful
deploy / deploy (push) Successful in 1m37s
Event call sites (product_view, add_to_cart, checkout_start, purchase) were only passing visitor_hash and pathname, leaving browser, OS, screen size and country nil. Add AnalyticsHook.attrs/1 helper to extract common analytics fields from socket assigns, and use it in all LiveView event call sites. Checkout controller reads the same fields from the session. Also fix plug analytics test to clear stale events before assertions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
117 lines
3.0 KiB
Elixir
117 lines
3.0 KiB
Elixir
defmodule BerrypodWeb.Plugs.AnalyticsTest do
|
|
use BerrypodWeb.ConnCase, async: false
|
|
|
|
import Ecto.Query
|
|
|
|
alias Berrypod.Analytics.{Buffer, Event}
|
|
alias Berrypod.Repo
|
|
|
|
setup do
|
|
send(Buffer, :flush)
|
|
:timer.sleep(50)
|
|
Repo.delete_all(Event)
|
|
:ok
|
|
end
|
|
|
|
describe "analytics plug" do
|
|
test "records a pageview on GET request", %{conn: conn} do
|
|
conn
|
|
|> put_req_header("user-agent", "Mozilla/5.0 Chrome/120.0")
|
|
|> get(~p"/")
|
|
|
|
send(Buffer, :flush)
|
|
:timer.sleep(50)
|
|
|
|
events =
|
|
from(e in Event, where: e.pathname == "/" and e.name == "pageview")
|
|
|> Repo.all()
|
|
|
|
assert length(events) >= 1
|
|
event = hd(events)
|
|
assert event.browser == "Chrome"
|
|
end
|
|
|
|
test "does not record on POST request", %{conn: conn} do
|
|
count_before = Repo.aggregate(Event, :count)
|
|
|
|
conn
|
|
|> put_req_header("user-agent", "Mozilla/5.0 Chrome/120.0")
|
|
|> post(~p"/checkout", %{})
|
|
|
|
send(Buffer, :flush)
|
|
:timer.sleep(50)
|
|
|
|
count_after = Repo.aggregate(Event, :count)
|
|
# POST to /checkout shouldn't create a pageview event via the plug
|
|
# (it may fail with a redirect, but the plug should have skipped)
|
|
assert count_after == count_before
|
|
end
|
|
|
|
test "skips bots", %{conn: conn} do
|
|
count_before = Repo.aggregate(Event, :count)
|
|
|
|
conn
|
|
|> put_req_header("user-agent", "Googlebot/2.1 (+http://www.google.com/bot.html)")
|
|
|> get(~p"/")
|
|
|
|
send(Buffer, :flush)
|
|
:timer.sleep(50)
|
|
|
|
count_after = Repo.aggregate(Event, :count)
|
|
assert count_after == count_before
|
|
end
|
|
|
|
test "stores analytics data in session", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> put_req_header("user-agent", "Mozilla/5.0 Firefox/121.0")
|
|
|> get(~p"/")
|
|
|
|
assert get_session(conn, "analytics_visitor_hash") |> is_binary()
|
|
assert get_session(conn, "analytics_browser") == "Firefox"
|
|
end
|
|
|
|
test "extracts referrer", %{conn: conn} do
|
|
conn
|
|
|> put_req_header("user-agent", "Mozilla/5.0 Chrome/120.0")
|
|
|> put_req_header("referer", "https://www.google.com/search?q=test")
|
|
|> get(~p"/")
|
|
|
|
send(Buffer, :flush)
|
|
:timer.sleep(50)
|
|
|
|
event =
|
|
from(e in Event,
|
|
where: e.referrer == "google.com",
|
|
order_by: [desc: e.inserted_at],
|
|
limit: 1
|
|
)
|
|
|> Repo.one()
|
|
|
|
assert event
|
|
assert event.referrer_source == "Google"
|
|
end
|
|
|
|
test "extracts UTM params", %{conn: conn} do
|
|
conn
|
|
|> put_req_header("user-agent", "Mozilla/5.0 Chrome/120.0")
|
|
|> get(~p"/?utm_source=newsletter&utm_medium=email&utm_campaign=spring")
|
|
|
|
send(Buffer, :flush)
|
|
:timer.sleep(50)
|
|
|
|
event =
|
|
from(e in Event,
|
|
where: e.utm_source == "newsletter",
|
|
order_by: [desc: e.inserted_at],
|
|
limit: 1
|
|
)
|
|
|> Repo.one()
|
|
|
|
assert event
|
|
assert event.utm_medium == "email"
|
|
assert event.utm_campaign == "spring"
|
|
end
|
|
end
|
|
end
|