Test goal_conversions function

This commit is contained in:
Uku Taht 2019-10-31 14:14:06 +08:00
parent c7ed0d54ce
commit bf8443d028
3 changed files with 91 additions and 7 deletions

View File

@ -181,11 +181,11 @@ defmodule Plausible.Stats do
) )
end end
def goal_conversions(site, query, limit \\ 5) do def goal_conversions(site, query, _limit \\ 5) do
goals = Repo.all(from g in Plausible.Goal, where: g.domain == ^site.domain) goals = Repo.all(from g in Plausible.Goal, where: g.domain == ^site.domain)
conversions = fetch_pageview_goals(goals, site, query) fetch_pageview_goals(goals, site, query)
++ fetch_event_goals(goals, site, query) ++ fetch_event_goals(goals, site, query)
|> sort_conversions |> sort_conversions()
end end
defp fetch_event_goals(goals, site, query) do defp fetch_event_goals(goals, site, query) do
@ -195,7 +195,7 @@ defmodule Plausible.Stats do
{:ok, last} = NaiveDateTime.new(query.date_range.last |> Timex.shift(days: 1), ~T[00:00:00]) {:ok, last} = NaiveDateTime.new(query.date_range.last |> Timex.shift(days: 1), ~T[00:00:00])
last_datetime = Timex.to_datetime(last, site.timezone) last_datetime = Timex.to_datetime(last, site.timezone)
events = Enum.map(goals, fn goal -> goal.name end) events = Enum.map(goals, fn goal -> goal.event_name end)
|> Enum.filter(&(&1)) |> Enum.filter(&(&1))
if Enum.count(events) > 0 do if Enum.count(events) > 0 do
@ -212,9 +212,34 @@ defmodule Plausible.Stats do
end end
end end
defp fetch_pageview_goals(goals, site, query), do: [] defp fetch_pageview_goals(goals, site, query) do
{:ok, first} = NaiveDateTime.new(query.date_range.first, ~T[00:00:00])
first_datetime = Timex.to_datetime(first, site.timezone)
defp sort_conversions(conversions), do: conversions {:ok, last} = NaiveDateTime.new(query.date_range.last |> Timex.shift(days: 1), ~T[00:00:00])
last_datetime = Timex.to_datetime(last, site.timezone)
pages = Enum.map(goals, fn goal -> goal.page_path end)
|> Enum.filter(&(&1))
if Enum.count(pages) > 0 do
Repo.all(
from e in Plausible.Event,
where: e.hostname == ^site.domain,
where: e.timestamp >= ^first_datetime and e.timestamp < ^last_datetime,
where: e.name == "pageview",
where: e.pathname in ^pages,
group_by: e.pathname,
select: {fragment("concat('Visit ', ?)", e.pathname), count(e.user_id, :distinct)}
)
else
[]
end
end
defp sort_conversions(conversions) do
Enum.sort_by(conversions, fn {_, count} -> -count end)
end
defp base_query(site, query) do defp base_query(site, query) do
{:ok, first} = NaiveDateTime.new(query.date_range.first, ~T[00:00:00]) {:ok, first} = NaiveDateTime.new(query.date_range.first, ~T[00:00:00])

View File

@ -319,6 +319,61 @@ defmodule Plausible.StatsTest do
end end
end end
describe "goal_conversions" do
test "shows custom event conversions" do
site = insert(:site)
insert(:goal, %{domain: site.domain, event_name: "Register", name: "Register"})
insert(:goal, %{domain: site.domain, event_name: "Newsletter signup", name: "Newsletter signup"})
insert(:event, name: "Register", hostname: site.domain, user_id: @user_id, timestamp: ~N[2019-01-01 01:00:00])
insert(:event, name: "Register", hostname: site.domain, user_id: UUID.uuid4(), timestamp: ~N[2019-01-01 01:00:00])
insert(:event, name: "Newsletter signup", hostname: site.domain, user_id: UUID.uuid4(), timestamp: ~N[2019-01-01 01:00:00])
insert(:event, name: "Irrelevant", hostname: site.domain, user_id: UUID.uuid4(), timestamp: ~N[2019-01-01 01:00:00])
query = Stats.Query.from(site.timezone, %{"period" => "day", "date" => "2019-01-01"})
conversions = Stats.goal_conversions(site, query)
assert conversions == [
{"Register", 2},
{"Newsletter signup", 1}
]
end
test "shows pageview conversions" do
site = insert(:site)
insert(:goal, %{domain: site.domain, page_path: "/success", name: "Visit /success"})
insert(:goal, %{domain: site.domain, page_path: "/register", name: "Visit /register"})
insert(:event, name: "pageview", pathname: "/success", hostname: site.domain, user_id: @user_id, timestamp: ~N[2019-01-01 01:00:00])
insert(:event, name: "pageview", pathname: "/success", hostname: site.domain, user_id: UUID.uuid4(), timestamp: ~N[2019-01-01 01:00:00])
insert(:event, name: "pageview", pathname: "/register", hostname: site.domain, user_id: UUID.uuid4(), timestamp: ~N[2019-01-01 01:00:00])
insert(:event, name: "pageview", pathname: "/irrelevant", hostname: site.domain, user_id: UUID.uuid4(), timestamp: ~N[2019-01-01 01:00:00])
query = Stats.Query.from(site.timezone, %{"period" => "day", "date" => "2019-01-01"})
conversions = Stats.goal_conversions(site, query)
assert conversions == [
{"Visit /success", 2},
{"Visit /register", 1}
]
end
test "shows mixed conversions in order of occurence" do
site = insert(:site)
insert(:goal, %{domain: site.domain, page_path: "/success", name: "Visit /success"})
insert(:goal, %{domain: site.domain, event_name: "Signup", name: "Signup"})
insert(:event, name: "Signup", hostname: site.domain, user_id: @user_id, timestamp: ~N[2019-01-01 01:00:00])
insert(:event, name: "pageview", pathname: "/success", hostname: site.domain, user_id: UUID.uuid4(), timestamp: ~N[2019-01-01 01:00:00])
insert(:event, name: "pageview", pathname: "/success", hostname: site.domain, user_id: UUID.uuid4(), timestamp: ~N[2019-01-01 01:00:00])
query = Stats.Query.from(site.timezone, %{"period" => "day", "date" => "2019-01-01"})
conversions = Stats.goal_conversions(site, query)
assert conversions == [
{"Visit /success", 2},
{"Signup", 1}
]
end
end
defp months_ago(months) do defp months_ago(months) do
Timex.now() |> Timex.shift(months: -months) Timex.now() |> Timex.shift(months: -months)
end end

View File

@ -42,6 +42,10 @@ defmodule Plausible.Factory do
} }
end end
def goal_factory do
%Plausible.Goal{}
end
def subscription_factory do def subscription_factory do
%Plausible.Billing.Subscription{ %Plausible.Billing.Subscription{
paddle_subscription_id: sequence(:paddle_subscription_id, &"subscription-#{&1}"), paddle_subscription_id: sequence(:paddle_subscription_id, &"subscription-#{&1}"),