mirror of
https://github.com/plausible/analytics.git
synced 2025-01-08 19:17:06 +03:00
Refactor: Standardize API metrics used internally (#3208)
* extract add_exit_rate function * Change internal API metric names for /entry-pages & /exit-pages * `unique_entrances` -> `visitors`, * `total_entrances` -> `visits`, * `unique_exits` -> `visitors`, * `total_exits` -> `visits`, This is just a consistency improvement - the `visitors` metric always means one thing and there's no need to call it different for entry pages internally. This commit does not change any noticable behavior. The UI labels are kept the same and the column headers in the CSV export will also remain the same. * Change internal API metric names for /conversions * `unique_conversions` -> `visitors`, * `total_conversions` -> `events`,
This commit is contained in:
parent
7b39328d6c
commit
17b9e36a19
@ -52,17 +52,17 @@ export default class Conversions extends React.Component {
|
||||
<div className="flex items-center justify-between my-2">
|
||||
<span className="flex-1">
|
||||
<Bar
|
||||
count={goal.unique_conversions}
|
||||
count={goal.visitors}
|
||||
all={this.state.goals}
|
||||
bg="bg-red-50 dark:bg-gray-500 dark:bg-opacity-15"
|
||||
plot="unique_conversions"
|
||||
plot="visitors"
|
||||
>
|
||||
<Link to={url.setQuery('goal', escapeFilterValue(goal.name))} className="block px-2 py-1.5 hover:underline relative z-9 break-all lg:truncate dark:text-gray-200">{goal.name}</Link>
|
||||
</Bar>
|
||||
</span>
|
||||
<div className="dark:text-gray-200">
|
||||
<span className="inline-block w-20 font-medium text-right">{numberFormatter(goal.unique_conversions)}</span>
|
||||
<span className="hidden md:inline-block md:w-20 font-medium text-right">{numberFormatter(goal.total_conversions)}</span>
|
||||
<span className="inline-block w-20 font-medium text-right">{numberFormatter(goal.visitors)}</span>
|
||||
<span className="hidden md:inline-block md:w-20 font-medium text-right">{numberFormatter(goal.events)}</span>
|
||||
<span className="inline-block w-20 font-medium text-right">{goal.conversion_rate}%</span>
|
||||
{renderRevenueColumn && <span className="hidden md:inline-block md:w-20 font-medium text-right"><Money formatted={goal.total_revenue} /></span>}
|
||||
{renderRevenueColumn && <span className="hidden md:inline-block md:w-20 font-medium text-right"><Money formatted={goal.average_revenue} /></span>}
|
||||
|
@ -90,8 +90,8 @@ class EntryPagesModal extends React.Component {
|
||||
</Link>
|
||||
</td>
|
||||
{this.showConversionRate() && <td className="p-2 w-32 font-medium" align="right">{numberFormatter(page.total_visitors)}</td>}
|
||||
<td className="p-2 w-32 font-medium" align="right">{numberFormatter(page.unique_entrances)}</td>
|
||||
{this.showExtra() && <td className="p-2 w-32 font-medium" align="right">{numberFormatter(page.total_entrances)}</td>}
|
||||
<td className="p-2 w-32 font-medium" align="right">{numberFormatter(page.visitors)}</td>
|
||||
{this.showExtra() && <td className="p-2 w-32 font-medium" align="right">{numberFormatter(page.visits)}</td>}
|
||||
{this.showExtra() && <td className="p-2 w-32 font-medium" align="right">{durationFormatter(page.visit_duration)}</td>}
|
||||
{this.showConversionRate() && <td className="p-2 w-32 font-medium" align="right">{numberFormatter(page.conversion_rate)}%</td>}
|
||||
</tr>
|
||||
|
@ -72,8 +72,8 @@ class ExitPagesModal extends React.Component {
|
||||
<Link to={{pathname: `/${encodeURIComponent(this.props.site.domain)}`, search: query.toString()}} className="hover:underline">{page.name}</Link>
|
||||
</td>
|
||||
{this.showConversionRate() && <td className="p-2 w-32 font-medium" align="right">{numberFormatter(page.total_visitors)}</td>}
|
||||
<td className="p-2 w-32 font-medium" align="right">{numberFormatter(page.unique_exits)}</td>
|
||||
{this.showExtra() && <td className="p-2 w-32 font-medium" align="right">{numberFormatter(page.total_exits)}</td>}
|
||||
<td className="p-2 w-32 font-medium" align="right">{numberFormatter(page.visitors)}</td>
|
||||
{this.showExtra() && <td className="p-2 w-32 font-medium" align="right">{numberFormatter(page.visits)}</td>}
|
||||
{this.showExtra() && <td className="p-2 w-32 font-medium" align="right">{this.formatPercentage(page.exit_rate)}</td>}
|
||||
{this.showConversionRate() && <td className="p-2 w-32 font-medium" align="right">{numberFormatter(page.conversion_rate)}%</td>}
|
||||
</tr>
|
||||
|
@ -4,7 +4,7 @@ import * as storage from '../../util/storage'
|
||||
import * as url from '../../util/url'
|
||||
import * as api from '../../api'
|
||||
import ListReport from './../reports/list'
|
||||
import { VISITORS_METRIC, UNIQUE_ENTRANCES_METRIC, UNIQUE_EXITS_METRIC, maybeWithCR } from './../reports/metrics';
|
||||
import { VISITORS_METRIC, maybeWithCR } from './../reports/metrics';
|
||||
|
||||
function EntryPages({query, site}) {
|
||||
function fetchData() {
|
||||
@ -24,7 +24,7 @@ function EntryPages({query, site}) {
|
||||
fetchData={fetchData}
|
||||
getFilterFor={getFilterFor}
|
||||
keyLabel="Entry page"
|
||||
metrics={maybeWithCR([UNIQUE_ENTRANCES_METRIC], query)}
|
||||
metrics={maybeWithCR([{...VISITORS_METRIC, label: 'Unique Entrances'}], query)}
|
||||
detailsLink={url.sitePath(site, '/entry-pages')}
|
||||
query={query}
|
||||
externalLinkDest={externalLinkDest}
|
||||
@ -51,7 +51,7 @@ function ExitPages({query, site}) {
|
||||
fetchData={fetchData}
|
||||
getFilterFor={getFilterFor}
|
||||
keyLabel="Exit page"
|
||||
metrics={maybeWithCR([UNIQUE_EXITS_METRIC], query)}
|
||||
metrics={maybeWithCR([{...VISITORS_METRIC, label: "Unique Exits"}], query)}
|
||||
detailsLink={url.sitePath(site, '/exit-pages')}
|
||||
query={query}
|
||||
externalLinkDest={externalLinkDest}
|
||||
|
@ -7,16 +7,6 @@ export const VISITORS_METRIC = {
|
||||
realtimeLabel: 'Current visitors',
|
||||
goalFilterLabel: 'Conversions'
|
||||
}
|
||||
export const UNIQUE_ENTRANCES_METRIC = {
|
||||
...VISITORS_METRIC,
|
||||
name: 'unique_entrances',
|
||||
label: 'Unique Entrances'
|
||||
}
|
||||
export const UNIQUE_EXITS_METRIC = {
|
||||
...VISITORS_METRIC,
|
||||
name: 'unique_exits',
|
||||
label: 'Unique Exits'
|
||||
}
|
||||
export const PERCENTAGE_METRIC = { name: 'percentage', label: '%' }
|
||||
export const CR_METRIC = { name: 'conversion_rate', label: 'CR' }
|
||||
|
||||
|
@ -796,19 +796,22 @@ defmodule PlausibleWeb.Api.StatsController do
|
||||
entry_pages =
|
||||
Stats.breakdown(site, query, "visit:entry_page", metrics, pagination)
|
||||
|> add_cr(site, query, pagination, :entry_page, "visit:entry_page")
|
||||
|> transform_keys(%{
|
||||
entry_page: :name,
|
||||
visitors: :unique_entrances,
|
||||
visits: :total_entrances
|
||||
})
|
||||
|> transform_keys(%{entry_page: :name})
|
||||
|
||||
if params["csv"] do
|
||||
if Map.has_key?(query.filters, "event:goal") do
|
||||
entry_pages
|
||||
|> transform_keys(%{unique_entrances: :conversions})
|
||||
|> to_csv([:name, :conversions, :conversion_rate])
|
||||
to_csv(entry_pages, [:name, :visitors, :conversion_rate], [
|
||||
:name,
|
||||
:conversions,
|
||||
:conversion_rate
|
||||
])
|
||||
else
|
||||
entry_pages |> to_csv([:name, :unique_entrances, :total_entrances, :visit_duration])
|
||||
to_csv(entry_pages, [:name, :visitors, :visits, :visit_duration], [
|
||||
:name,
|
||||
:unique_entrances,
|
||||
:total_entrances,
|
||||
:visit_duration
|
||||
])
|
||||
end
|
||||
else
|
||||
json(conn, entry_pages)
|
||||
@ -824,52 +827,57 @@ defmodule PlausibleWeb.Api.StatsController do
|
||||
exit_pages =
|
||||
Stats.breakdown(site, query, "visit:exit_page", metrics, {limit, page})
|
||||
|> add_cr(site, query, {limit, page}, :exit_page, "visit:exit_page")
|
||||
|> transform_keys(%{
|
||||
exit_page: :name,
|
||||
visitors: :unique_exits,
|
||||
visits: :total_exits
|
||||
})
|
||||
|
||||
pages = Enum.map(exit_pages, & &1[:name])
|
||||
|
||||
total_visits_query =
|
||||
Query.put_filter(query, "event:page", {:member, pages})
|
||||
|> Query.put_filter("event:name", {:is, "pageview"})
|
||||
|
||||
exit_pages =
|
||||
if !Query.has_event_filters?(query) do
|
||||
total_pageviews =
|
||||
Stats.breakdown(site, total_visits_query, "event:page", [:pageviews], {limit, 1})
|
||||
|
||||
Enum.map(exit_pages, fn exit_page ->
|
||||
exit_rate =
|
||||
case Enum.find(total_pageviews, &(&1[:page] == exit_page[:name])) do
|
||||
%{pageviews: pageviews} ->
|
||||
Float.floor(exit_page[:total_exits] / pageviews * 100)
|
||||
|
||||
nil ->
|
||||
nil
|
||||
end
|
||||
|
||||
Map.put(exit_page, :exit_rate, exit_rate)
|
||||
end)
|
||||
else
|
||||
exit_pages
|
||||
end
|
||||
|> add_exit_rate(site, query, limit)
|
||||
|> transform_keys(%{exit_page: :name})
|
||||
|
||||
if params["csv"] do
|
||||
if Map.has_key?(query.filters, "event:goal") do
|
||||
exit_pages
|
||||
|> transform_keys(%{unique_exits: :conversions})
|
||||
|> to_csv([:name, :conversions, :conversion_rate])
|
||||
to_csv(exit_pages, [:name, :visitors, :conversion_rate], [
|
||||
:name,
|
||||
:conversions,
|
||||
:conversion_rate
|
||||
])
|
||||
else
|
||||
exit_pages |> to_csv([:name, :unique_exits, :total_exits, :exit_rate])
|
||||
to_csv(exit_pages, [:name, :visitors, :visits, :exit_rate], [
|
||||
:name,
|
||||
:unique_exits,
|
||||
:total_exits,
|
||||
:exit_rate
|
||||
])
|
||||
end
|
||||
else
|
||||
json(conn, exit_pages)
|
||||
end
|
||||
end
|
||||
|
||||
defp add_exit_rate(breakdown_results, site, query, limit) do
|
||||
if Query.has_event_filters?(query) do
|
||||
breakdown_results
|
||||
else
|
||||
pages = Enum.map(breakdown_results, & &1[:exit_page])
|
||||
|
||||
total_visits_query =
|
||||
Query.put_filter(query, "event:page", {:member, pages})
|
||||
|> Query.put_filter("event:name", {:is, "pageview"})
|
||||
|
||||
total_pageviews =
|
||||
Stats.breakdown(site, total_visits_query, "event:page", [:pageviews], {limit, 1})
|
||||
|
||||
Enum.map(breakdown_results, fn result ->
|
||||
exit_rate =
|
||||
case Enum.find(total_pageviews, &(&1[:page] == result[:exit_page])) do
|
||||
%{pageviews: pageviews} ->
|
||||
Float.floor(result[:visits] / pageviews * 100)
|
||||
|
||||
nil ->
|
||||
nil
|
||||
end
|
||||
|
||||
Map.put(result, :exit_rate, exit_rate)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
def countries(conn, params) do
|
||||
site = conn.assigns[:site]
|
||||
query = site |> Query.from(params) |> Filters.add_prefix()
|
||||
@ -1126,17 +1134,21 @@ defmodule PlausibleWeb.Api.StatsController do
|
||||
conversions =
|
||||
site
|
||||
|> Stats.breakdown(query, "event:goal", metrics, {100, 1})
|
||||
|> transform_keys(%{goal: :name, visitors: :unique_conversions, events: :total_conversions})
|
||||
|> transform_keys(%{goal: :name})
|
||||
|> Enum.map(fn goal ->
|
||||
goal
|
||||
|> Map.put(:prop_names, CustomProps.props_for_goal(site, query))
|
||||
|> Map.put(:conversion_rate, calculate_cr(total_visitors, goal[:unique_conversions]))
|
||||
|> Map.put(:conversion_rate, calculate_cr(total_visitors, goal[:visitors]))
|
||||
|> Enum.map(&format_revenue_metric/1)
|
||||
|> Map.new()
|
||||
end)
|
||||
|
||||
if params["csv"] do
|
||||
to_csv(conversions, [:name, :unique_conversions, :total_conversions])
|
||||
to_csv(conversions, [:name, :visitors, :events], [
|
||||
:name,
|
||||
:unique_conversions,
|
||||
:total_conversions
|
||||
])
|
||||
else
|
||||
json(conn, conversions)
|
||||
end
|
||||
@ -1364,10 +1376,12 @@ defmodule PlausibleWeb.Api.StatsController do
|
||||
|
||||
defp add_cr(breakdown_results, _, _, _, _, _), do: breakdown_results
|
||||
|
||||
defp to_csv(list, headers) do
|
||||
defp to_csv(list, columns), do: to_csv(list, columns, columns)
|
||||
|
||||
defp to_csv(list, columns, column_names) do
|
||||
list
|
||||
|> Enum.map(fn row -> Enum.map(headers, &row[&1]) end)
|
||||
|> (fn res -> [headers | res] end).()
|
||||
|> Enum.map(fn row -> Enum.map(columns, &row[&1]) end)
|
||||
|> (fn res -> [column_names | res] end).()
|
||||
|> CSV.encode()
|
||||
|> Enum.join()
|
||||
end
|
||||
|
@ -748,11 +748,11 @@ defmodule Plausible.ImportedTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "/page2",
|
||||
"unique_exits" => 3,
|
||||
"total_exits" => 4,
|
||||
"visitors" => 3,
|
||||
"visits" => 4,
|
||||
"exit_rate" => 80.0
|
||||
},
|
||||
%{"name" => "/page1", "unique_exits" => 2, "total_exits" => 2, "exit_rate" => 66}
|
||||
%{"name" => "/page1", "visitors" => 2, "visits" => 2, "exit_rate" => 66}
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -35,15 +35,15 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Signup",
|
||||
"unique_conversions" => 2,
|
||||
"total_conversions" => 3,
|
||||
"visitors" => 2,
|
||||
"events" => 3,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 33.3
|
||||
},
|
||||
%{
|
||||
"name" => "Visit /register",
|
||||
"unique_conversions" => 2,
|
||||
"total_conversions" => 2,
|
||||
"visitors" => 2,
|
||||
"events" => 2,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 33.3
|
||||
}
|
||||
@ -84,8 +84,8 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Payment",
|
||||
"unique_conversions" => 1,
|
||||
"total_conversions" => 2,
|
||||
"visitors" => 1,
|
||||
"events" => 2,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 33.3
|
||||
}
|
||||
@ -125,8 +125,8 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Payment",
|
||||
"unique_conversions" => 2,
|
||||
"total_conversions" => 2,
|
||||
"visitors" => 2,
|
||||
"events" => 2,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 66.7
|
||||
}
|
||||
@ -164,8 +164,8 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Payment",
|
||||
"unique_conversions" => 2,
|
||||
"total_conversions" => 3,
|
||||
"visitors" => 2,
|
||||
"events" => 3,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 66.7
|
||||
}
|
||||
@ -205,8 +205,8 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Payment",
|
||||
"unique_conversions" => 2,
|
||||
"total_conversions" => 3,
|
||||
"visitors" => 2,
|
||||
"events" => 3,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 66.7
|
||||
}
|
||||
@ -256,8 +256,8 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Payment",
|
||||
"unique_conversions" => 5,
|
||||
"total_conversions" => 5,
|
||||
"visitors" => 5,
|
||||
"events" => 5,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 100.0,
|
||||
"average_revenue" => %{"short" => "€166.7M", "long" => "€166,733,566.75"},
|
||||
@ -294,27 +294,27 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
"conversion_rate" => 33.3,
|
||||
"name" => "Payment",
|
||||
"prop_names" => [],
|
||||
"total_conversions" => 1,
|
||||
"events" => 1,
|
||||
"total_revenue" => %{"long" => "€10.00", "short" => "€10.0"},
|
||||
"unique_conversions" => 1
|
||||
"visitors" => 1
|
||||
},
|
||||
%{
|
||||
"average_revenue" => nil,
|
||||
"conversion_rate" => 66.7,
|
||||
"name" => "Signup",
|
||||
"prop_names" => [],
|
||||
"total_conversions" => 2,
|
||||
"events" => 2,
|
||||
"total_revenue" => nil,
|
||||
"unique_conversions" => 2
|
||||
"visitors" => 2
|
||||
},
|
||||
%{
|
||||
"average_revenue" => nil,
|
||||
"conversion_rate" => 33.3,
|
||||
"name" => "Visit /checkout",
|
||||
"prop_names" => [],
|
||||
"total_conversions" => 1,
|
||||
"events" => 1,
|
||||
"total_revenue" => nil,
|
||||
"unique_conversions" => 1
|
||||
"visitors" => 1
|
||||
}
|
||||
] == Enum.sort_by(response, & &1["name"])
|
||||
end
|
||||
@ -334,8 +334,8 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Signup",
|
||||
"unique_conversions" => 1,
|
||||
"total_conversions" => 1,
|
||||
"visitors" => 1,
|
||||
"events" => 1,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 100.0
|
||||
}
|
||||
@ -370,8 +370,8 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Signup",
|
||||
"unique_conversions" => 2,
|
||||
"total_conversions" => 2,
|
||||
"visitors" => 2,
|
||||
"events" => 2,
|
||||
"prop_names" => ["variant"],
|
||||
"conversion_rate" => 33.3
|
||||
}
|
||||
@ -408,8 +408,8 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Payment",
|
||||
"unique_conversions" => 2,
|
||||
"total_conversions" => 2,
|
||||
"visitors" => 2,
|
||||
"events" => 2,
|
||||
"prop_names" => ["logged_in"],
|
||||
"conversion_rate" => 66.7
|
||||
}
|
||||
@ -573,15 +573,15 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Signup",
|
||||
"unique_conversions" => 2,
|
||||
"total_conversions" => 2,
|
||||
"visitors" => 2,
|
||||
"events" => 2,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 33.3
|
||||
},
|
||||
%{
|
||||
"name" => "Visit /register",
|
||||
"unique_conversions" => 1,
|
||||
"total_conversions" => 1,
|
||||
"visitors" => 1,
|
||||
"events" => 1,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 16.7
|
||||
}
|
||||
@ -614,15 +614,15 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "CTA",
|
||||
"unique_conversions" => 1,
|
||||
"total_conversions" => 1,
|
||||
"visitors" => 1,
|
||||
"events" => 1,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 16.7
|
||||
},
|
||||
%{
|
||||
"name" => "Visit /register",
|
||||
"unique_conversions" => 1,
|
||||
"total_conversions" => 1,
|
||||
"visitors" => 1,
|
||||
"events" => 1,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 16.7
|
||||
}
|
||||
@ -650,15 +650,15 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Visit /blog/**",
|
||||
"unique_conversions" => 2,
|
||||
"total_conversions" => 2,
|
||||
"visitors" => 2,
|
||||
"events" => 2,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 66.7
|
||||
},
|
||||
%{
|
||||
"name" => "Visit /billing/upgrade",
|
||||
"unique_conversions" => 1,
|
||||
"total_conversions" => 1,
|
||||
"visitors" => 1,
|
||||
"events" => 1,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 33.3
|
||||
}
|
||||
@ -690,15 +690,15 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Visit /blog**",
|
||||
"unique_conversions" => 2,
|
||||
"total_conversions" => 2,
|
||||
"visitors" => 2,
|
||||
"events" => 2,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 33.3
|
||||
},
|
||||
%{
|
||||
"name" => "Signup",
|
||||
"unique_conversions" => 1,
|
||||
"total_conversions" => 1,
|
||||
"visitors" => 1,
|
||||
"events" => 1,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 16.7
|
||||
}
|
||||
@ -731,15 +731,15 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Visit /ano**",
|
||||
"unique_conversions" => 2,
|
||||
"total_conversions" => 2,
|
||||
"visitors" => 2,
|
||||
"events" => 2,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 33.3
|
||||
},
|
||||
%{
|
||||
"name" => "CTA",
|
||||
"unique_conversions" => 1,
|
||||
"total_conversions" => 1,
|
||||
"visitors" => 1,
|
||||
"events" => 1,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 16.7
|
||||
}
|
||||
@ -769,8 +769,8 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Visit /register",
|
||||
"unique_conversions" => 1,
|
||||
"total_conversions" => 1,
|
||||
"visitors" => 1,
|
||||
"events" => 1,
|
||||
"prop_names" => [],
|
||||
"conversion_rate" => 25
|
||||
}
|
||||
@ -802,8 +802,8 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Signup",
|
||||
"unique_conversions" => 1,
|
||||
"total_conversions" => 1,
|
||||
"visitors" => 1,
|
||||
"events" => 1,
|
||||
"prop_names" => ["variant"],
|
||||
"conversion_rate" => 50
|
||||
}
|
||||
@ -870,58 +870,58 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"conversion_rate" => 100.0,
|
||||
"unique_conversions" => 8,
|
||||
"visitors" => 8,
|
||||
"name" => "Visit /**",
|
||||
"total_conversions" => 8,
|
||||
"events" => 8,
|
||||
"prop_names" => []
|
||||
},
|
||||
%{
|
||||
"conversion_rate" => 37.5,
|
||||
"unique_conversions" => 3,
|
||||
"visitors" => 3,
|
||||
"name" => "Visit /signup/**",
|
||||
"total_conversions" => 3,
|
||||
"events" => 3,
|
||||
"prop_names" => []
|
||||
},
|
||||
%{
|
||||
"conversion_rate" => 37.5,
|
||||
"unique_conversions" => 3,
|
||||
"visitors" => 3,
|
||||
"name" => "Visit /*",
|
||||
"total_conversions" => 3,
|
||||
"events" => 3,
|
||||
"prop_names" => []
|
||||
},
|
||||
%{
|
||||
"conversion_rate" => 25.0,
|
||||
"unique_conversions" => 2,
|
||||
"visitors" => 2,
|
||||
"name" => "Visit /billing**/success",
|
||||
"total_conversions" => 2,
|
||||
"events" => 2,
|
||||
"prop_names" => []
|
||||
},
|
||||
%{
|
||||
"conversion_rate" => 25.0,
|
||||
"unique_conversions" => 2,
|
||||
"visitors" => 2,
|
||||
"name" => "Visit /reg*",
|
||||
"total_conversions" => 2,
|
||||
"events" => 2,
|
||||
"prop_names" => []
|
||||
},
|
||||
%{
|
||||
"conversion_rate" => 12.5,
|
||||
"unique_conversions" => 1,
|
||||
"visitors" => 1,
|
||||
"name" => "Visit /signup/*",
|
||||
"total_conversions" => 1,
|
||||
"events" => 1,
|
||||
"prop_names" => []
|
||||
},
|
||||
%{
|
||||
"conversion_rate" => 12.5,
|
||||
"unique_conversions" => 1,
|
||||
"visitors" => 1,
|
||||
"name" => "Visit /billing*/success",
|
||||
"total_conversions" => 1,
|
||||
"events" => 1,
|
||||
"prop_names" => []
|
||||
},
|
||||
%{
|
||||
"conversion_rate" => 12.5,
|
||||
"unique_conversions" => 1,
|
||||
"visitors" => 1,
|
||||
"name" => "Visit /register",
|
||||
"total_conversions" => 1,
|
||||
"events" => 1,
|
||||
"prop_names" => []
|
||||
}
|
||||
]
|
||||
@ -956,9 +956,9 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"conversion_rate" => 100.0,
|
||||
"unique_conversions" => 2,
|
||||
"visitors" => 2,
|
||||
"name" => "Visit /register**",
|
||||
"total_conversions" => 2,
|
||||
"events" => 2,
|
||||
"prop_names" => ["logged_in", "author"]
|
||||
}
|
||||
]
|
||||
|
@ -903,14 +903,14 @@ defmodule PlausibleWeb.Api.StatsController.PagesTest do
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"unique_entrances" => 2,
|
||||
"total_entrances" => 2,
|
||||
"visitors" => 2,
|
||||
"visits" => 2,
|
||||
"name" => "/page1",
|
||||
"visit_duration" => 0
|
||||
},
|
||||
%{
|
||||
"unique_entrances" => 1,
|
||||
"total_entrances" => 2,
|
||||
"visitors" => 1,
|
||||
"visits" => 2,
|
||||
"name" => "/page2",
|
||||
"visit_duration" => 450
|
||||
}
|
||||
@ -959,14 +959,14 @@ defmodule PlausibleWeb.Api.StatsController.PagesTest do
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"unique_entrances" => 1,
|
||||
"total_entrances" => 1,
|
||||
"visitors" => 1,
|
||||
"visits" => 1,
|
||||
"name" => "/blog",
|
||||
"visit_duration" => 60
|
||||
},
|
||||
%{
|
||||
"unique_entrances" => 1,
|
||||
"total_entrances" => 1,
|
||||
"visitors" => 1,
|
||||
"visits" => 1,
|
||||
"name" => "/blog/john-2",
|
||||
"visit_duration" => 0
|
||||
}
|
||||
@ -1014,14 +1014,14 @@ defmodule PlausibleWeb.Api.StatsController.PagesTest do
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"unique_entrances" => 2,
|
||||
"total_entrances" => 2,
|
||||
"visitors" => 2,
|
||||
"visits" => 2,
|
||||
"name" => "/page1",
|
||||
"visit_duration" => 0
|
||||
},
|
||||
%{
|
||||
"unique_entrances" => 1,
|
||||
"total_entrances" => 2,
|
||||
"visitors" => 1,
|
||||
"visits" => 2,
|
||||
"name" => "/page2",
|
||||
"visit_duration" => 450
|
||||
}
|
||||
@ -1035,14 +1035,14 @@ defmodule PlausibleWeb.Api.StatsController.PagesTest do
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"unique_entrances" => 3,
|
||||
"total_entrances" => 5,
|
||||
"visitors" => 3,
|
||||
"visits" => 5,
|
||||
"name" => "/page2",
|
||||
"visit_duration" => 240.0
|
||||
},
|
||||
%{
|
||||
"unique_entrances" => 2,
|
||||
"total_entrances" => 2,
|
||||
"visitors" => 2,
|
||||
"visits" => 2,
|
||||
"name" => "/page1",
|
||||
"visit_duration" => 0
|
||||
}
|
||||
@ -1094,16 +1094,16 @@ defmodule PlausibleWeb.Api.StatsController.PagesTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"total_visitors" => 2,
|
||||
"unique_entrances" => 1,
|
||||
"total_entrances" => 1,
|
||||
"visitors" => 1,
|
||||
"visits" => 1,
|
||||
"name" => "/page1",
|
||||
"visit_duration" => 0,
|
||||
"conversion_rate" => 50.0
|
||||
},
|
||||
%{
|
||||
"total_visitors" => 1,
|
||||
"unique_entrances" => 1,
|
||||
"total_entrances" => 1,
|
||||
"visitors" => 1,
|
||||
"visits" => 1,
|
||||
"name" => "/page2",
|
||||
"visit_duration" => 900,
|
||||
"conversion_rate" => 100.0
|
||||
@ -1140,8 +1140,8 @@ defmodule PlausibleWeb.Api.StatsController.PagesTest do
|
||||
conn = get(conn, "/api/stats/#{site.domain}/exit-pages?period=day&date=2021-01-01")
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{"name" => "/page1", "unique_exits" => 2, "total_exits" => 2, "exit_rate" => 66},
|
||||
%{"name" => "/page2", "unique_exits" => 1, "total_exits" => 1, "exit_rate" => 100}
|
||||
%{"name" => "/page1", "visitors" => 2, "visits" => 2, "exit_rate" => 66},
|
||||
%{"name" => "/page2", "visitors" => 1, "visits" => 1, "exit_rate" => 100}
|
||||
]
|
||||
end
|
||||
|
||||
@ -1180,7 +1180,7 @@ defmodule PlausibleWeb.Api.StatsController.PagesTest do
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{"name" => "/", "unique_exits" => 1, "total_exits" => 1}
|
||||
%{"name" => "/", "visitors" => 1, "visits" => 1}
|
||||
]
|
||||
end
|
||||
|
||||
@ -1224,8 +1224,8 @@ defmodule PlausibleWeb.Api.StatsController.PagesTest do
|
||||
conn = get(conn, "/api/stats/#{site.domain}/exit-pages?period=day&date=2021-01-01")
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{"name" => "/page1", "unique_exits" => 2, "total_exits" => 2, "exit_rate" => 66},
|
||||
%{"name" => "/page2", "unique_exits" => 1, "total_exits" => 1, "exit_rate" => 100}
|
||||
%{"name" => "/page1", "visitors" => 2, "visits" => 2, "exit_rate" => 66},
|
||||
%{"name" => "/page2", "visitors" => 1, "visits" => 1, "exit_rate" => 100}
|
||||
]
|
||||
|
||||
conn =
|
||||
@ -1237,11 +1237,11 @@ defmodule PlausibleWeb.Api.StatsController.PagesTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "/page2",
|
||||
"unique_exits" => 3,
|
||||
"total_exits" => 4,
|
||||
"visitors" => 3,
|
||||
"visits" => 4,
|
||||
"exit_rate" => 80.0
|
||||
},
|
||||
%{"name" => "/page1", "unique_exits" => 2, "total_exits" => 2, "exit_rate" => 66}
|
||||
%{"name" => "/page1", "visitors" => 2, "visits" => 2, "exit_rate" => 66}
|
||||
]
|
||||
end
|
||||
|
||||
@ -1288,16 +1288,16 @@ defmodule PlausibleWeb.Api.StatsController.PagesTest do
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "/exit1",
|
||||
"unique_exits" => 1,
|
||||
"visitors" => 1,
|
||||
"total_visitors" => 1,
|
||||
"total_exits" => 1,
|
||||
"visits" => 1,
|
||||
"conversion_rate" => 100.0
|
||||
},
|
||||
%{
|
||||
"name" => "/exit2",
|
||||
"unique_exits" => 1,
|
||||
"visitors" => 1,
|
||||
"total_visitors" => 1,
|
||||
"total_exits" => 1,
|
||||
"visits" => 1,
|
||||
"conversion_rate" => 100.0
|
||||
}
|
||||
]
|
||||
@ -1341,8 +1341,8 @@ defmodule PlausibleWeb.Api.StatsController.PagesTest do
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{"name" => "/exit1", "unique_exits" => 1, "total_exits" => 1},
|
||||
%{"name" => "/exit2", "unique_exits" => 1, "total_exits" => 1}
|
||||
%{"name" => "/exit1", "visitors" => 1, "visits" => 1},
|
||||
%{"name" => "/exit2", "visitors" => 1, "visits" => 1}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user