analytics/test/plausible_web/controllers/api/stats_controller/countries_test.exs
Vini Brasil 4503895d0a
Fix breakdown API pagination when using event metrics (#2562)
* Fix breakdown API pagination when using event metrics

This commit fixes a bug where the subsequent breakdown API pages had
the same items as the first page. The fix sorts the underlying
ClickHouse query by timestamp, keeping the same order between requests,
as we use OFFSET/LIMIT pagination.

* Fix repeated results assertion

* Add different ORDER BY to each breakdown property
2023-01-04 22:14:40 -03:00

304 lines
8.6 KiB
Elixir

defmodule PlausibleWeb.Api.StatsController.CountriesTest do
use PlausibleWeb.ConnCase
describe "GET /api/stats/:domain/countries" do
setup [:create_user, :log_in, :create_new_site, :add_imported_data]
test "returns top countries by new visitors", %{conn: conn, site: site} do
populate_stats(site, [
build(:pageview,
country_code: "EE"
),
build(:pageview,
country_code: "EE"
),
build(:pageview,
country_code: "GB"
),
build(:imported_locations,
country: "EE"
),
build(:imported_locations,
country: "GB"
)
])
conn = get(conn, "/api/stats/#{site.domain}/countries?period=day")
assert json_response(conn, 200) == [
%{
"code" => "EE",
"alpha_3" => "EST",
"name" => "Estonia",
"flag" => "🇪🇪",
"visitors" => 2,
"percentage" => 67
},
%{
"code" => "GB",
"alpha_3" => "GBR",
"name" => "United Kingdom",
"flag" => "🇬🇧",
"visitors" => 1,
"percentage" => 33
}
]
conn = get(conn, "/api/stats/#{site.domain}/countries?period=day&with_imported=true")
assert json_response(conn, 200) == [
%{
"code" => "EE",
"alpha_3" => "EST",
"name" => "Estonia",
"flag" => "🇪🇪",
"visitors" => 3,
"percentage" => 60
},
%{
"code" => "GB",
"alpha_3" => "GBR",
"name" => "United Kingdom",
"flag" => "🇬🇧",
"visitors" => 2,
"percentage" => 40
}
]
end
test "ignores unknown country code ZZ", %{conn: conn, site: site} do
populate_stats(site, [
build(:pageview, country_code: "ZZ"),
build(:imported_locations, country: "ZZ")
])
conn = get(conn, "/api/stats/#{site.domain}/countries?period=day&with_imported=true")
assert json_response(conn, 200) == []
end
test "calculates conversion_rate when filtering for goal", %{conn: conn, site: site} do
populate_stats(site, [
build(:pageview,
user_id: 1,
country_code: "EE"
),
build(:event, user_id: 1, name: "Signup"),
build(:pageview,
user_id: 2,
country_code: "EE"
),
build(:pageview,
user_id: 3,
country_code: "GB"
),
build(:event, user_id: 3, name: "Signup")
])
filters = Jason.encode!(%{"goal" => "Signup"})
conn = get(conn, "/api/stats/#{site.domain}/countries?period=day&filters=#{filters}")
assert json_response(conn, 200) == [
%{
"code" => "EE",
"alpha_3" => "EST",
"name" => "Estonia",
"flag" => "🇪🇪",
"total_visitors" => 2,
"visitors" => 1,
"conversion_rate" => 50.0
},
%{
"code" => "GB",
"alpha_3" => "GBR",
"name" => "United Kingdom",
"flag" => "🇬🇧",
"total_visitors" => 1,
"visitors" => 1,
"conversion_rate" => 100.0
}
]
end
test "returns top countries with :is filter on custom pageview props", %{
conn: conn,
site: site
} do
populate_stats(site, [
build(:pageview,
user_id: 123,
country_code: "EE"
),
build(:pageview,
user_id: 123,
country_code: "EE",
"meta.key": ["author"],
"meta.value": ["John Doe"]
),
build(:pageview,
country_code: "GB",
"meta.key": ["author"],
"meta.value": ["other"]
),
build(:pageview,
country_code: "US"
)
])
filters = Jason.encode!(%{props: %{"author" => "John Doe"}})
conn = get(conn, "/api/stats/#{site.domain}/countries?period=day&filters=#{filters}")
assert json_response(conn, 200) == [
%{
"code" => "EE",
"alpha_3" => "EST",
"name" => "Estonia",
"flag" => "🇪🇪",
"visitors" => 1,
"percentage" => 100
}
]
end
test "returns top countries with :is_not filter on custom pageview props", %{
conn: conn,
site: site
} do
populate_stats(site, [
build(:pageview,
user_id: 123,
country_code: "EE",
"meta.key": ["author"],
"meta.value": ["John Doe"]
),
build(:pageview,
user_id: 123,
country_code: "EE",
"meta.key": ["author"],
"meta.value": ["John Doe"]
),
build(:pageview,
country_code: "GB",
"meta.key": ["author"],
"meta.value": ["other"]
),
build(:pageview,
country_code: "GB"
)
])
filters = Jason.encode!(%{props: %{"author" => "!John Doe"}})
conn = get(conn, "/api/stats/#{site.domain}/countries?period=day&filters=#{filters}")
assert json_response(conn, 200) == [
%{
"code" => "GB",
"alpha_3" => "GBR",
"name" => "United Kingdom",
"flag" => "🇬🇧",
"visitors" => 2,
"percentage" => 100
}
]
end
test "returns top countries with :is (none) filter on custom pageview props", %{
conn: conn,
site: site
} do
populate_stats(site, [
build(:pageview,
country_code: "EE",
"meta.key": ["author"],
"meta.value": ["John Doe"]
),
build(:pageview,
country_code: "GB",
"meta.key": ["logged_in"],
"meta.value": ["true"]
),
build(:pageview,
country_code: "GB"
)
])
filters = Jason.encode!(%{props: %{"author" => "(none)"}})
conn = get(conn, "/api/stats/#{site.domain}/countries?period=day&filters=#{filters}")
assert json_response(conn, 200) == [
%{
"code" => "GB",
"alpha_3" => "GBR",
"name" => "United Kingdom",
"flag" => "🇬🇧",
"visitors" => 2,
"percentage" => 100
}
]
end
test "returns top countries with :is_not (none) filter on custom pageview props", %{
conn: conn,
site: site
} do
populate_stats(site, [
build(:pageview,
country_code: "EE",
"meta.key": ["author"],
"meta.value": ["John Doe"]
),
build(:pageview,
country_code: "EE",
"meta.key": ["author"],
"meta.value": [""]
),
build(:pageview,
country_code: "GB",
"meta.key": ["logged_in"],
"meta.value": ["true"]
),
build(:pageview,
country_code: "GB"
)
])
filters = Jason.encode!(%{props: %{"author" => "!(none)"}})
conn = get(conn, "/api/stats/#{site.domain}/countries?period=day&filters=#{filters}")
assert json_response(conn, 200) == [
%{
"code" => "EE",
"alpha_3" => "EST",
"name" => "Estonia",
"flag" => "🇪🇪",
"visitors" => 2,
"percentage" => 100
}
]
end
test "when list is filtered by country returns one country only", %{conn: conn, site: site} do
populate_stats(site, [
build(:pageview, country_code: "EE"),
build(:pageview, country_code: "EE"),
build(:pageview, country_code: "GB")
])
filters = Jason.encode!(%{country: "GB"})
conn = get(conn, "/api/stats/#{site.domain}/countries?period=day&filters=#{filters}")
assert json_response(conn, 200) == [
%{
"code" => "GB",
"alpha_3" => "GBR",
"name" => "United Kingdom",
"flag" => "🇬🇧",
"visitors" => 1,
"percentage" => 100
}
]
end
end
end