mirror of
https://github.com/plausible/analytics.git
synced 2024-12-27 19:47:26 +03:00
0fa6b688af
* Make TestUtils module available in all tests * Add macros patching the application env in tests Unfortunately a lot of existing functionality relies on certain application env setup. This isn't ideal because the app config is a shared state that prevents us from running the tests in parallel. Those macros encapsulate setting up new env for test purposes and make sure the changes are reverted when the test finishes. * Allow passing request opts to HTTPClient.post/4 We need this to swap custom request building in Google Analytics import. * Unify errors when listing sites * React: propagate backend error messages if available * React: catch API errors in Search Terms component * Propagate google API errors on referrer drilldown * Handle verified properties errors in SC settings * Add missing tests for SC settings controller * Unify errors for fetching search analytics queries (list stats) * Unify errors refreshing Google Auth Token * Test fetch_stats/3 errors and replace Double with Mox * Fixup makrup * s/class/className * Simplify Search Terms display in case of errors * Fix warnings
304 lines
8.6 KiB
Elixir
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" => "GB",
|
|
"alpha_3" => "GBR",
|
|
"name" => "United Kingdom",
|
|
"flag" => "🇬🇧",
|
|
"total_visitors" => 1,
|
|
"visitors" => 1,
|
|
"conversion_rate" => 100.0
|
|
},
|
|
%{
|
|
"code" => "EE",
|
|
"alpha_3" => "EST",
|
|
"name" => "Estonia",
|
|
"flag" => "🇪🇪",
|
|
"total_visitors" => 2,
|
|
"visitors" => 1,
|
|
"conversion_rate" => 50.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
|