mirror of
https://github.com/plausible/analytics.git
synced 2024-09-11 18:07:33 +03:00
Filter out empty entries when listing stats for UTM props (#3339)
* Filter out empty entries when listing stats for UTM props * Update test fixtures removing noref entries in UTM CSV stat exports * Update external API tests to account for lack of noref records for UTM stats * Filter out entries with empty UTM props from imported GA stats * Remove unreachable GA utm_source dim clause in imported stats logic
This commit is contained in:
parent
9b029c1558
commit
27a11fc5b7
@ -443,9 +443,10 @@ defmodule Plausible.Stats.Breakdown do
|
||||
defp do_group_by(q, "visit:utm_medium") do
|
||||
from(
|
||||
s in q,
|
||||
where: fragment("not empty(?)", s.utm_medium),
|
||||
group_by: s.utm_medium,
|
||||
select_merge: %{
|
||||
utm_medium: fragment("if(empty(?), ?, ?)", s.utm_medium, @no_ref, s.utm_medium)
|
||||
utm_medium: s.utm_medium
|
||||
}
|
||||
)
|
||||
end
|
||||
@ -453,9 +454,10 @@ defmodule Plausible.Stats.Breakdown do
|
||||
defp do_group_by(q, "visit:utm_source") do
|
||||
from(
|
||||
s in q,
|
||||
where: fragment("not empty(?)", s.utm_source),
|
||||
group_by: s.utm_source,
|
||||
select_merge: %{
|
||||
utm_source: fragment("if(empty(?), ?, ?)", s.utm_source, @no_ref, s.utm_source)
|
||||
utm_source: s.utm_source
|
||||
}
|
||||
)
|
||||
end
|
||||
@ -463,9 +465,10 @@ defmodule Plausible.Stats.Breakdown do
|
||||
defp do_group_by(q, "visit:utm_campaign") do
|
||||
from(
|
||||
s in q,
|
||||
where: fragment("not empty(?)", s.utm_campaign),
|
||||
group_by: s.utm_campaign,
|
||||
select_merge: %{
|
||||
utm_campaign: fragment("if(empty(?), ?, ?)", s.utm_campaign, @no_ref, s.utm_campaign)
|
||||
utm_campaign: s.utm_campaign
|
||||
}
|
||||
)
|
||||
end
|
||||
@ -473,9 +476,10 @@ defmodule Plausible.Stats.Breakdown do
|
||||
defp do_group_by(q, "visit:utm_content") do
|
||||
from(
|
||||
s in q,
|
||||
where: fragment("not empty(?)", s.utm_content),
|
||||
group_by: s.utm_content,
|
||||
select_merge: %{
|
||||
utm_content: fragment("if(empty(?), ?, ?)", s.utm_content, @no_ref, s.utm_content)
|
||||
utm_content: s.utm_content
|
||||
}
|
||||
)
|
||||
end
|
||||
@ -483,9 +487,10 @@ defmodule Plausible.Stats.Breakdown do
|
||||
defp do_group_by(q, "visit:utm_term") do
|
||||
from(
|
||||
s in q,
|
||||
where: fragment("not empty(?)", s.utm_term),
|
||||
group_by: s.utm_term,
|
||||
select_merge: %{
|
||||
utm_term: fragment("if(empty(?), ?, ?)", s.utm_term, @no_ref, s.utm_term)
|
||||
utm_term: s.utm_term
|
||||
}
|
||||
)
|
||||
end
|
||||
|
@ -142,32 +142,30 @@ defmodule Plausible.Stats.Imported do
|
||||
|
||||
:utm_medium ->
|
||||
imported_q
|
||||
|> where([i], fragment("not empty(?)", i.utm_medium))
|
||||
|> select_merge([i], %{
|
||||
utm_medium: fragment("if(empty(?), ?, ?)", i.utm_medium, @no_ref, i.utm_medium)
|
||||
})
|
||||
|
||||
:utm_source ->
|
||||
imported_q
|
||||
|> select_merge([i], %{
|
||||
utm_source: fragment("if(empty(?), ?, ?)", i.utm_source, @no_ref, i.utm_source)
|
||||
utm_medium: i.utm_medium
|
||||
})
|
||||
|
||||
:utm_campaign ->
|
||||
imported_q
|
||||
|> where([i], fragment("not empty(?)", i.utm_campaign))
|
||||
|> select_merge([i], %{
|
||||
utm_campaign: fragment("if(empty(?), ?, ?)", i.utm_campaign, @no_ref, i.utm_campaign)
|
||||
utm_campaign: i.utm_campaign
|
||||
})
|
||||
|
||||
:utm_term ->
|
||||
imported_q
|
||||
|> where([i], fragment("not empty(?)", i.utm_term))
|
||||
|> select_merge([i], %{
|
||||
utm_term: fragment("if(empty(?), ?, ?)", i.utm_term, @no_ref, i.utm_term)
|
||||
utm_term: i.utm_term
|
||||
})
|
||||
|
||||
:utm_content ->
|
||||
imported_q
|
||||
|> where([i], fragment("not empty(?)", i.utm_content))
|
||||
|> select_merge([i], %{
|
||||
utm_content: fragment("if(empty(?), ?, ?)", i.utm_content, @no_ref, i.utm_content)
|
||||
utm_content: i.utm_content
|
||||
})
|
||||
|
||||
:page ->
|
||||
|
@ -306,12 +306,6 @@ defmodule Plausible.ImportedTest do
|
||||
"name" => "social",
|
||||
"visit_duration" => 20,
|
||||
"visitors" => 3
|
||||
},
|
||||
%{
|
||||
"bounce_rate" => 100.0,
|
||||
"name" => "Direct / None",
|
||||
"visit_duration" => 60.0,
|
||||
"visitors" => 1
|
||||
}
|
||||
]
|
||||
end
|
||||
@ -395,12 +389,6 @@ defmodule Plausible.ImportedTest do
|
||||
"visitors" => 2,
|
||||
"bounce_rate" => 100.0,
|
||||
"visit_duration" => 50.0
|
||||
},
|
||||
%{
|
||||
"bounce_rate" => 0.0,
|
||||
"name" => "Direct / None",
|
||||
"visit_duration" => 100.0,
|
||||
"visitors" => 1
|
||||
}
|
||||
]
|
||||
end
|
||||
@ -485,12 +473,6 @@ defmodule Plausible.ImportedTest do
|
||||
"visitors" => 2,
|
||||
"bounce_rate" => 100.0,
|
||||
"visit_duration" => 50.0
|
||||
},
|
||||
%{
|
||||
"bounce_rate" => 0.0,
|
||||
"name" => "Direct / None",
|
||||
"visit_duration" => 100.0,
|
||||
"visitors" => 1
|
||||
}
|
||||
]
|
||||
end
|
||||
@ -574,12 +556,6 @@ defmodule Plausible.ImportedTest do
|
||||
"visitors" => 2,
|
||||
"bounce_rate" => 100.0,
|
||||
"visit_duration" => 50.0
|
||||
},
|
||||
%{
|
||||
"bounce_rate" => 0.0,
|
||||
"name" => "Direct / None",
|
||||
"visit_duration" => 100.0,
|
||||
"visitors" => 1
|
||||
}
|
||||
]
|
||||
end
|
||||
|
@ -1,2 +1 @@
|
||||
name,conversions,conversion_rate
|
||||
Direct / None,1,33.3
|
||||
|
|
@ -1,2 +1 @@
|
||||
name,conversions,conversion_rate
|
||||
Direct / None,1,33.3
|
||||
|
|
@ -1,2 +1 @@
|
||||
name,conversions,conversion_rate
|
||||
Direct / None,1,33.3
|
||||
|
|
@ -1,2 +1 @@
|
||||
name,conversions,conversion_rate
|
||||
Direct / None,1,33.3
|
||||
|
|
@ -1,2 +1 @@
|
||||
name,conversions,conversion_rate
|
||||
Direct / None,1,33.3
|
||||
|
|
@ -1,2 +1 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
||||
Direct / None,1,0,60
|
||||
|
|
@ -1,2 +1 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
||||
Direct / None,1,0,60
|
||||
|
|
@ -1,2 +1 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
||||
Direct / None,1,0,60
|
||||
|
|
@ -1,2 +1 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
||||
Direct / None,1,0,60
|
||||
|
|
@ -1,2 +1 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
||||
Direct / None,1,0,60
|
||||
|
|
@ -1,3 +1,2 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
||||
Direct / None,3,67,20
|
||||
ads,1,100,0
|
||||
|
|
@ -1,3 +1,2 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
||||
Direct / None,3,67,20
|
||||
content,1,100,0
|
||||
|
|
@ -1,3 +1,2 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
||||
Direct / None,3,67,20
|
||||
search,1,100,0
|
||||
|
|
@ -1,3 +1,2 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
||||
Direct / None,3,67,20
|
||||
google,1,100,0
|
||||
|
|
@ -1,3 +1,2 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
||||
Direct / None,3,67,20
|
||||
term,1,100,0
|
||||
|
|
@ -1,3 +1,2 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
||||
Direct / None,3,67,20
|
||||
ads,2,100,0
|
||||
|
|
@ -1,3 +1,2 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
||||
Direct / None,4,75,15
|
||||
content,1,100,0
|
||||
|
|
@ -1,3 +1,2 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
||||
Direct / None,4,75,15
|
||||
search,1,100,0
|
||||
|
|
@ -1,3 +1,2 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
||||
Direct / None,4,75,15
|
||||
google,1,100,0
|
||||
|
|
@ -1,3 +1,2 @@
|
||||
name,visitors,bounce_rate,visit_duration
|
||||
Direct / None,4,75,15
|
||||
term,1,100,0
|
||||
|
|
@ -243,8 +243,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.BreakdownTest do
|
||||
|
||||
assert json_response(conn, 200) == %{
|
||||
"results" => [
|
||||
%{"utm_medium" => "Search", "visitors" => 2},
|
||||
%{"utm_medium" => "Direct / None", "visitors" => 1}
|
||||
%{"utm_medium" => "Search", "visitors" => 2}
|
||||
]
|
||||
}
|
||||
end
|
||||
@ -275,8 +274,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.BreakdownTest do
|
||||
|
||||
assert json_response(conn, 200) == %{
|
||||
"results" => [
|
||||
%{"utm_source" => "Google", "visitors" => 2},
|
||||
%{"utm_source" => "Direct / None", "visitors" => 1}
|
||||
%{"utm_source" => "Google", "visitors" => 2}
|
||||
]
|
||||
}
|
||||
end
|
||||
@ -307,8 +305,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.BreakdownTest do
|
||||
|
||||
assert json_response(conn, 200) == %{
|
||||
"results" => [
|
||||
%{"utm_campaign" => "ads", "visitors" => 2},
|
||||
%{"utm_campaign" => "Direct / None", "visitors" => 1}
|
||||
%{"utm_campaign" => "ads", "visitors" => 2}
|
||||
]
|
||||
}
|
||||
end
|
||||
@ -339,8 +336,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.BreakdownTest do
|
||||
|
||||
assert json_response(conn, 200) == %{
|
||||
"results" => [
|
||||
%{"utm_content" => "Content1", "visitors" => 2},
|
||||
%{"utm_content" => "Direct / None", "visitors" => 1}
|
||||
%{"utm_content" => "Content1", "visitors" => 2}
|
||||
]
|
||||
}
|
||||
end
|
||||
@ -371,8 +367,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.BreakdownTest do
|
||||
|
||||
assert json_response(conn, 200) == %{
|
||||
"results" => [
|
||||
%{"utm_term" => "Term1", "visitors" => 2},
|
||||
%{"utm_term" => "Direct / None", "visitors" => 1}
|
||||
%{"utm_term" => "Term1", "visitors" => 2}
|
||||
]
|
||||
}
|
||||
end
|
||||
|
@ -568,6 +568,74 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
test "filters out entries without utm_medium present", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:pageview,
|
||||
utm_medium: "social",
|
||||
user_id: @user_id,
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_medium: "social",
|
||||
user_id: @user_id,
|
||||
timestamp: ~N[2021-01-01 00:15:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_medium: "",
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
)
|
||||
])
|
||||
|
||||
populate_stats(site, [
|
||||
build(:imported_sources,
|
||||
utm_medium: "social",
|
||||
date: ~D[2021-01-01],
|
||||
visit_duration: 700,
|
||||
bounces: 1,
|
||||
visits: 1,
|
||||
visitors: 1
|
||||
),
|
||||
build(:imported_sources,
|
||||
utm_medium: "",
|
||||
date: ~D[2021-01-01],
|
||||
bounces: 0,
|
||||
visits: 1,
|
||||
visitors: 1,
|
||||
visit_duration: 100
|
||||
)
|
||||
])
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/utm_mediums?period=day&date=2021-01-01"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "social",
|
||||
"visitors" => 1,
|
||||
"bounce_rate" => 0,
|
||||
"visit_duration" => 900
|
||||
}
|
||||
]
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/utm_mediums?period=day&date=2021-01-01&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "social",
|
||||
"visitors" => 2,
|
||||
"bounce_rate" => 50,
|
||||
"visit_duration" => 800.0
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/stats/:domain/utm_campaigns" do
|
||||
@ -656,10 +724,82 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
test "filters out entries without utm_campaign present", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:pageview,
|
||||
utm_campaign: "profile",
|
||||
user_id: @user_id,
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_campaign: "profile",
|
||||
user_id: @user_id,
|
||||
timestamp: ~N[2021-01-01 00:15:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_campaign: "",
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_campaign: "",
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
)
|
||||
])
|
||||
|
||||
populate_stats(site, [
|
||||
build(:imported_sources,
|
||||
utm_campaign: "profile",
|
||||
date: ~D[2021-01-01],
|
||||
visit_duration: 700,
|
||||
bounces: 1,
|
||||
visits: 1,
|
||||
visitors: 1
|
||||
),
|
||||
build(:imported_sources,
|
||||
utm_campaign: "",
|
||||
date: ~D[2021-01-01],
|
||||
bounces: 0,
|
||||
visits: 1,
|
||||
visitors: 1,
|
||||
visit_duration: 900
|
||||
)
|
||||
])
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/utm_campaigns?period=day&date=2021-01-01"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "profile",
|
||||
"visitors" => 1,
|
||||
"bounce_rate" => 0,
|
||||
"visit_duration" => 900
|
||||
}
|
||||
]
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/utm_campaigns?period=day&date=2021-01-01&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "profile",
|
||||
"visitors" => 2,
|
||||
"bounce_rate" => 50,
|
||||
"visit_duration" => 800.0
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/stats/:domain/utm_sources" do
|
||||
setup [:create_user, :log_in, :create_new_site]
|
||||
setup [:create_user, :log_in, :create_new_site, :add_imported_data]
|
||||
|
||||
test "returns top utm_sources by unique user ids", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
@ -706,6 +846,326 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/stats/:domain/utm_terms" do
|
||||
setup [:create_user, :log_in, :create_new_site, :add_imported_data]
|
||||
|
||||
test "returns top utm_terms by unique user ids", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:pageview,
|
||||
utm_term: "oat milk",
|
||||
user_id: @user_id,
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_term: "oat milk",
|
||||
user_id: @user_id,
|
||||
timestamp: ~N[2021-01-01 00:15:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_term: "Sweden",
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_term: "Sweden",
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
)
|
||||
])
|
||||
|
||||
populate_stats(site, [
|
||||
build(:imported_sources,
|
||||
utm_term: "oat milk",
|
||||
date: ~D[2021-01-01],
|
||||
visit_duration: 700,
|
||||
bounces: 1,
|
||||
visits: 1,
|
||||
visitors: 1
|
||||
),
|
||||
build(:imported_sources,
|
||||
utm_term: "Sweden",
|
||||
date: ~D[2021-01-01],
|
||||
bounces: 0,
|
||||
visits: 1,
|
||||
visitors: 1,
|
||||
visit_duration: 900
|
||||
)
|
||||
])
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/utm_terms?period=day&date=2021-01-01"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Sweden",
|
||||
"visitors" => 2,
|
||||
"bounce_rate" => 100,
|
||||
"visit_duration" => 0
|
||||
},
|
||||
%{
|
||||
"name" => "oat milk",
|
||||
"visitors" => 1,
|
||||
"bounce_rate" => 0,
|
||||
"visit_duration" => 900
|
||||
}
|
||||
]
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/utm_terms?period=day&date=2021-01-01&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Sweden",
|
||||
"visitors" => 3,
|
||||
"bounce_rate" => 67,
|
||||
"visit_duration" => 300
|
||||
},
|
||||
%{
|
||||
"name" => "oat milk",
|
||||
"visitors" => 2,
|
||||
"bounce_rate" => 50,
|
||||
"visit_duration" => 800.0
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
test "filters out entries without utm_term present", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:pageview,
|
||||
utm_term: "oat milk",
|
||||
user_id: @user_id,
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_term: "oat milk",
|
||||
user_id: @user_id,
|
||||
timestamp: ~N[2021-01-01 00:15:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_term: "",
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_term: "",
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
)
|
||||
])
|
||||
|
||||
populate_stats(site, [
|
||||
build(:imported_sources,
|
||||
utm_term: "oat milk",
|
||||
date: ~D[2021-01-01],
|
||||
visit_duration: 700,
|
||||
bounces: 1,
|
||||
visits: 1,
|
||||
visitors: 1
|
||||
),
|
||||
build(:imported_sources,
|
||||
utm_term: "",
|
||||
date: ~D[2021-01-01],
|
||||
bounces: 0,
|
||||
visits: 1,
|
||||
visitors: 1,
|
||||
visit_duration: 900
|
||||
)
|
||||
])
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/utm_terms?period=day&date=2021-01-01"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "oat milk",
|
||||
"visitors" => 1,
|
||||
"bounce_rate" => 0,
|
||||
"visit_duration" => 900
|
||||
}
|
||||
]
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/utm_terms?period=day&date=2021-01-01&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "oat milk",
|
||||
"visitors" => 2,
|
||||
"bounce_rate" => 50,
|
||||
"visit_duration" => 800.0
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/stats/:domain/utm_contents" do
|
||||
setup [:create_user, :log_in, :create_new_site, :add_imported_data]
|
||||
|
||||
test "returns top utm_contents by unique user ids", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:pageview,
|
||||
utm_content: "ad",
|
||||
user_id: @user_id,
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_content: "ad",
|
||||
user_id: @user_id,
|
||||
timestamp: ~N[2021-01-01 00:15:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_content: "blog",
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_content: "blog",
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
)
|
||||
])
|
||||
|
||||
populate_stats(site, [
|
||||
build(:imported_sources,
|
||||
utm_content: "ad",
|
||||
date: ~D[2021-01-01],
|
||||
visit_duration: 700,
|
||||
bounces: 1,
|
||||
visits: 1,
|
||||
visitors: 1
|
||||
),
|
||||
build(:imported_sources,
|
||||
utm_content: "blog",
|
||||
date: ~D[2021-01-01],
|
||||
bounces: 0,
|
||||
visits: 1,
|
||||
visitors: 1,
|
||||
visit_duration: 900
|
||||
)
|
||||
])
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/utm_contents?period=day&date=2021-01-01"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "blog",
|
||||
"visitors" => 2,
|
||||
"bounce_rate" => 100,
|
||||
"visit_duration" => 0
|
||||
},
|
||||
%{
|
||||
"name" => "ad",
|
||||
"visitors" => 1,
|
||||
"bounce_rate" => 0,
|
||||
"visit_duration" => 900
|
||||
}
|
||||
]
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/utm_contents?period=day&date=2021-01-01&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "blog",
|
||||
"visitors" => 3,
|
||||
"bounce_rate" => 67,
|
||||
"visit_duration" => 300
|
||||
},
|
||||
%{
|
||||
"name" => "ad",
|
||||
"visitors" => 2,
|
||||
"bounce_rate" => 50,
|
||||
"visit_duration" => 800.0
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
test "filters out entries without utm_content present", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:pageview,
|
||||
utm_content: "ad",
|
||||
user_id: @user_id,
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_content: "ad",
|
||||
user_id: @user_id,
|
||||
timestamp: ~N[2021-01-01 00:15:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_content: "",
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_content: "",
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
)
|
||||
])
|
||||
|
||||
populate_stats(site, [
|
||||
build(:imported_sources,
|
||||
utm_content: "ad",
|
||||
date: ~D[2021-01-01],
|
||||
visit_duration: 700,
|
||||
bounces: 1,
|
||||
visits: 1,
|
||||
visitors: 1
|
||||
),
|
||||
build(:imported_sources,
|
||||
utm_content: "",
|
||||
date: ~D[2021-01-01],
|
||||
bounces: 0,
|
||||
visits: 1,
|
||||
visitors: 1,
|
||||
visit_duration: 900
|
||||
)
|
||||
])
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/utm_contents?period=day&date=2021-01-01"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "ad",
|
||||
"visitors" => 1,
|
||||
"bounce_rate" => 0,
|
||||
"visit_duration" => 900
|
||||
}
|
||||
]
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/utm_contents?period=day&date=2021-01-01&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "ad",
|
||||
"visitors" => 2,
|
||||
"bounce_rate" => 50,
|
||||
"visit_duration" => 800.0
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/stats/:domain/sources - with goal filter" do
|
||||
setup [:create_user, :log_in, :create_new_site]
|
||||
|
||||
@ -1074,180 +1534,4 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/stats/:domain/utm_terms" do
|
||||
setup [:create_user, :log_in, :create_new_site, :add_imported_data]
|
||||
|
||||
test "returns top utm_terms by unique user ids", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:pageview,
|
||||
utm_term: "oat milk",
|
||||
user_id: @user_id,
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_term: "oat milk",
|
||||
user_id: @user_id,
|
||||
timestamp: ~N[2021-01-01 00:15:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_term: "Sweden",
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_term: "Sweden",
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
)
|
||||
])
|
||||
|
||||
populate_stats(site, [
|
||||
build(:imported_sources,
|
||||
utm_term: "oat milk",
|
||||
date: ~D[2021-01-01],
|
||||
visit_duration: 700,
|
||||
bounces: 1,
|
||||
visits: 1,
|
||||
visitors: 1
|
||||
),
|
||||
build(:imported_sources,
|
||||
utm_term: "Sweden",
|
||||
date: ~D[2021-01-01],
|
||||
bounces: 0,
|
||||
visits: 1,
|
||||
visitors: 1,
|
||||
visit_duration: 900
|
||||
)
|
||||
])
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/utm_terms?period=day&date=2021-01-01"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Sweden",
|
||||
"visitors" => 2,
|
||||
"bounce_rate" => 100,
|
||||
"visit_duration" => 0
|
||||
},
|
||||
%{
|
||||
"name" => "oat milk",
|
||||
"visitors" => 1,
|
||||
"bounce_rate" => 0,
|
||||
"visit_duration" => 900
|
||||
}
|
||||
]
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/utm_terms?period=day&date=2021-01-01&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "Sweden",
|
||||
"visitors" => 3,
|
||||
"bounce_rate" => 67,
|
||||
"visit_duration" => 300
|
||||
},
|
||||
%{
|
||||
"name" => "oat milk",
|
||||
"visitors" => 2,
|
||||
"bounce_rate" => 50,
|
||||
"visit_duration" => 800.0
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/stats/:domain/utm_contents" do
|
||||
setup [:create_user, :log_in, :create_new_site, :add_imported_data]
|
||||
|
||||
test "returns top utm_contents by unique user ids", %{conn: conn, site: site} do
|
||||
populate_stats(site, [
|
||||
build(:pageview,
|
||||
utm_content: "ad",
|
||||
user_id: @user_id,
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_content: "ad",
|
||||
user_id: @user_id,
|
||||
timestamp: ~N[2021-01-01 00:15:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_content: "blog",
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
),
|
||||
build(:pageview,
|
||||
utm_content: "blog",
|
||||
timestamp: ~N[2021-01-01 00:00:00]
|
||||
)
|
||||
])
|
||||
|
||||
populate_stats(site, [
|
||||
build(:imported_sources,
|
||||
utm_content: "ad",
|
||||
date: ~D[2021-01-01],
|
||||
visit_duration: 700,
|
||||
bounces: 1,
|
||||
visits: 1,
|
||||
visitors: 1
|
||||
),
|
||||
build(:imported_sources,
|
||||
utm_content: "blog",
|
||||
date: ~D[2021-01-01],
|
||||
bounces: 0,
|
||||
visits: 1,
|
||||
visitors: 1,
|
||||
visit_duration: 900
|
||||
)
|
||||
])
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/utm_contents?period=day&date=2021-01-01"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "blog",
|
||||
"visitors" => 2,
|
||||
"bounce_rate" => 100,
|
||||
"visit_duration" => 0
|
||||
},
|
||||
%{
|
||||
"name" => "ad",
|
||||
"visitors" => 1,
|
||||
"bounce_rate" => 0,
|
||||
"visit_duration" => 900
|
||||
}
|
||||
]
|
||||
|
||||
conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/stats/#{site.domain}/utm_contents?period=day&date=2021-01-01&with_imported=true"
|
||||
)
|
||||
|
||||
assert json_response(conn, 200) == [
|
||||
%{
|
||||
"name" => "blog",
|
||||
"visitors" => 3,
|
||||
"bounce_rate" => 67,
|
||||
"visit_duration" => 300
|
||||
},
|
||||
%{
|
||||
"name" => "ad",
|
||||
"visitors" => 2,
|
||||
"bounce_rate" => 50,
|
||||
"visit_duration" => 800.0
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user