Make feature toggle work with teams schema and adjust affected tests

This commit is contained in:
Adrian Gruntkowski 2024-11-14 15:24:11 +01:00
parent 07a3436fa2
commit 9aa4049e8d
64 changed files with 391 additions and 360 deletions

View File

@ -48,7 +48,8 @@ defmodule Plausible.Billing.Feature do
`{:error, :upgrade_required}` when toggling a feature the site owner does not
have access to.
"""
@callback toggle(Plausible.Site.t(), Keyword.t()) :: :ok | {:error, :upgrade_required}
@callback toggle(Plausible.Site.t(), Plausible.Auth.User.t(), Keyword.t()) ::
:ok | {:error, :upgrade_required}
@doc """
Checks whether a feature is enabled or not. Returns false when the feature is
@ -130,31 +131,20 @@ defmodule Plausible.Billing.Feature do
@impl true
def check_availability(%Plausible.Auth.User{} = user) do
cond do
free?() -> :ok
__MODULE__ in Quota.Limits.allowed_features_for(user) -> :ok
true -> {:error, :upgrade_required}
end
end
def check_availability(team_or_nil) do
cond do
free?() -> :ok
__MODULE__ in Plausible.Teams.Billing.allowed_features_for(team_or_nil) -> :ok
true -> {:error, :upgrade_required}
end
Plausible.Teams.Adapter.Read.Billing.check_feature_availability(__MODULE__, user)
end
@impl true
def toggle(%Plausible.Site{} = site, opts \\ []) do
if toggle_field(), do: do_toggle(site, opts), else: :ok
def toggle(%Plausible.Site{} = site, %Plausible.Auth.User{} = user, opts \\ []) do
if toggle_field(), do: do_toggle(site, user, opts), else: :ok
end
defp do_toggle(%Plausible.Site{} = site, opts) do
site = Plausible.Repo.preload(site, :owner)
defp do_toggle(%Plausible.Site{} = site, user, opts) do
owner = Plausible.Teams.Adapter.Read.Ownership.get_owner(site, user)
override = Keyword.get(opts, :override)
toggle = if is_boolean(override), do: override, else: !Map.fetch!(site, toggle_field())
availability = if toggle, do: check_availability(site.owner), else: :ok
availability = if toggle, do: check_availability(owner), else: :ok
case availability do
:ok ->
@ -210,38 +200,17 @@ defmodule Plausible.Billing.Feature.StatsAPI do
name: :stats_api,
display_name: "Stats API"
if Plausible.ee?() do
@impl true
@doc """
Checks whether the user has access to Stats API or not.
@impl true
@doc """
Checks whether the user has access to Stats API or not.
Before the business tier, users who had not yet started their trial had
access to Stats API. With the business tier work, access is blocked and they
must either start their trial or subscribe to a plan. This is common when a
site owner invites a new user. In such cases, using the owner's API key is
recommended.
"""
def check_availability(%Plausible.Auth.User{} = user) do
user = Plausible.Users.with_subscription(user)
unlimited_trial? = is_nil(user.trial_expiry_date)
subscription? = Plausible.Billing.Subscriptions.active?(user.subscription)
pre_business_tier_account? =
NaiveDateTime.before?(user.inserted_at, Plausible.Billing.Plans.business_tier_launch())
cond do
!subscription? && unlimited_trial? && pre_business_tier_account? ->
:ok
!subscription? && unlimited_trial? && !pre_business_tier_account? ->
{:error, :upgrade_required}
true ->
super(user)
end
end
else
@impl true
def check_availability(_user), do: :ok
Before the business tier, users who had not yet started their trial had
access to Stats API. With the business tier work, access is blocked and they
must either start their trial or subscribe to a plan. This is common when a
site owner invites a new user. In such cases, using the owner's API key is
recommended.
"""
def check_availability(%Plausible.Auth.User{} = user) do
Plausible.Teams.Adapter.Read.Billing.check_feature_availability_for_stats_api(user)
end
end

View File

@ -11,14 +11,6 @@ defmodule Plausible.Teams.Adapter do
end
end
def team_or_user(user) do
switch(
user,
team_fn: &Function.identity/1,
user_fn: &Function.identity/1
)
end
def switch(user, opts \\ []) do
team_fn = Keyword.fetch!(opts, :team_fn)
user_fn = Keyword.fetch!(opts, :user_fn)

View File

@ -1,6 +1,6 @@
defmodule Plausible.Teams.Adapter.Read.Billing do
@moduledoc """
Transition adapter for new schema reads
Transition adapter for new schema reads
"""
use Plausible.Teams.Adapter
@ -34,4 +34,65 @@ defmodule Plausible.Teams.Adapter.Read.Billing do
user_fn: &Plausible.Billing.Quota.Usage.site_usage/1
)
end
use Plausible
on_ee do
def check_feature_availability_for_stats_api(user) do
{unlimited_trial?, subscription?} =
switch(user,
team_fn: fn team ->
team = Plausible.Teams.with_subscription(team)
unlimited_trial? = is_nil(team) or is_nil(team.trial_expiry_date)
subscription? =
not is_nil(team) and Plausible.Billing.Subscriptions.active?(team.subscription)
{unlimited_trial?, subscription?}
end,
user_fn: fn user ->
user = Plausible.Users.with_subscription(user)
unlimited_trial? = is_nil(user.trial_expiry_date)
subscription? = Plausible.Billing.Subscriptions.active?(user.subscription)
{unlimited_trial?, subscription?}
end
)
pre_business_tier_account? =
NaiveDateTime.before?(user.inserted_at, Plausible.Billing.Plans.business_tier_launch())
cond do
!subscription? && unlimited_trial? && pre_business_tier_account? ->
:ok
!subscription? && unlimited_trial? && !pre_business_tier_account? ->
{:error, :upgrade_required}
true ->
check_feature_availability(Plausible.Billing.Feature.StatsAPI, user)
end
end
else
def check_feature_availability_for_stats_api(_user), do: :ok
end
def check_feature_availability(feature, user) do
switch(user,
team_fn: fn team_or_nil ->
cond do
feature.free?() -> :ok
feature in Teams.Billing.allowed_features_for(team_or_nil) -> :ok
true -> {:error, :upgrade_required}
end
end,
user_fn: fn user ->
cond do
feature.free?() -> :ok
feature in Plausible.Billing.Quota.Limits.allowed_features_for(user) -> :ok
true -> {:error, :upgrade_required}
end
end
)
end
end

View File

@ -1,6 +1,6 @@
defmodule Plausible.Teams.Adapter.Read.Ownership do
@moduledoc """
Transition adapter for new schema reads
Transition adapter for new schema reads
"""
use Plausible
use Plausible.Teams.Adapter
@ -8,6 +8,20 @@ defmodule Plausible.Teams.Adapter.Read.Ownership do
alias Plausible.Auth
alias Plausible.Site.Memberships.Invitations
def get_owner(site, user) do
switch(user,
team_fn: fn team ->
case Teams.Sites.get_owner(team) do
{:ok, user} -> user
_ -> nil
end
end,
user_fn: fn _ ->
Plausible.Repo.preload(site, :owner).owner
end
)
end
def ensure_can_take_ownership(site, user) do
switch(
user,
@ -39,11 +53,9 @@ defmodule Plausible.Teams.Adapter.Read.Ownership do
on_ee do
def check_feature_access(site, new_owner) do
team_or_user = team_or_user(new_owner)
missing_features =
Plausible.Billing.Quota.Usage.features_usage(nil, [site.id])
|> Enum.filter(&(&1.check_availability(team_or_user) != :ok))
|> Enum.filter(&(&1.check_availability(new_owner) != :ok))
if missing_features == [] do
:ok

View File

@ -25,11 +25,11 @@ defmodule PlausibleWeb.Api.InternalController do
"conversions" => Plausible.Billing.Feature.Goals
}
def disable_feature(conn, %{"domain" => domain, "feature" => feature}) do
with %User{id: user_id} <- conn.assigns[:current_user],
with %User{id: user_id} = user <- conn.assigns[:current_user],
site <- Sites.get_by_domain(domain),
true <- Sites.has_admin_access?(user_id, site) || Auth.is_super_admin?(user_id),
{:ok, mod} <- Map.fetch(@features, feature),
{:ok, _site} <- mod.toggle(site, override: false) do
{:ok, _site} <- mod.toggle(site, user, override: false) do
json(conn, "ok")
else
{:error, :upgrade_required} ->

View File

@ -81,7 +81,7 @@ defmodule PlausibleWeb.SiteController do
feature_mod =
Enum.find(Plausible.Billing.Feature.list(), &(&1.toggle_field() == toggle_field))
case feature_mod.toggle(site, override: value == "true") do
case feature_mod.toggle(site, conn.assigns.current_user, override: value == "true") do
{:ok, updated_site} ->
message =
if Map.fetch!(updated_site, toggle_field) do

View File

@ -1,5 +1,6 @@
defmodule Plausible.AuthTest do
use Plausible.DataCase, async: true
use Plausible.Teams.Test
alias Plausible.Auth
describe "user_completed_setup?" do
@ -52,14 +53,14 @@ defmodule Plausible.AuthTest do
describe "create_api_key/3" do
test "creates a new api key" do
user = insert(:user)
user = new_user()
key = Ecto.UUID.generate()
assert {:ok, %Auth.ApiKey{}} = Auth.create_api_key(user, "my new key", key)
end
@tag :ee_only
test "defaults to 600 requests per hour limit in EE" do
user = insert(:user)
user = new_user()
{:ok, %Auth.ApiKey{hourly_request_limit: hourly_request_limit}} =
Auth.create_api_key(user, "my new EE key", Ecto.UUID.generate())
@ -78,8 +79,8 @@ defmodule Plausible.AuthTest do
end
test "errors when key already exists" do
u1 = insert(:user)
u2 = insert(:user)
u1 = new_user()
u2 = new_user()
key = Ecto.UUID.generate()
assert {:ok, %Auth.ApiKey{}} = Auth.create_api_key(u1, "my new key", key)
assert {:error, changeset} = Auth.create_api_key(u2, "my other key", key)
@ -100,16 +101,16 @@ defmodule Plausible.AuthTest do
describe "delete_api_key/2" do
test "deletes the record" do
user = insert(:user)
user = new_user()
assert {:ok, api_key} = Auth.create_api_key(user, "my new key", Ecto.UUID.generate())
assert :ok = Auth.delete_api_key(user, api_key.id)
refute Plausible.Repo.reload(api_key)
end
test "returns error when api key does not exist or does not belong to user" do
me = insert(:user)
me = new_user()
other_user = insert(:user)
other_user = new_user()
{:ok, other_api_key} = Auth.create_api_key(other_user, "my new key", Ecto.UUID.generate())
assert {:error, :not_found} = Auth.delete_api_key(me, other_api_key.id)

View File

@ -1,28 +1,25 @@
defmodule Plausible.Billing.FeatureTest do
use Plausible.DataCase
use Plausible.Teams.Test
@v1_plan_id "558018"
for mod <- [Plausible.Billing.Feature.Funnels, Plausible.Billing.Feature.RevenueGoals] do
test "#{mod}.check_availability/1 returns :ok when site owner is on a enterprise plan" do
user =
insert(:user,
enterprise_plan:
build(:enterprise_plan, paddle_plan_id: "123321", features: [unquote(mod)]),
subscription: build(:subscription, paddle_plan_id: "123321")
)
new_user()
|> subscribe_to_enterprise_plan(paddle_plan_id: "123321", features: [unquote(mod)])
assert :ok == unquote(mod).check_availability(user)
end
test "#{mod}.check_availability/1 returns :ok when site owner is on a business plan" do
user = insert(:user, subscription: build(:business_subscription))
user = new_user() |> subscribe_to_business_plan()
assert :ok == unquote(mod).check_availability(user)
end
test "#{mod}.check_availability/1 returns error when site owner is on a growth plan" do
user = insert(:user, subscription: build(:growth_subscription))
user = new_user() |> subscribe_to_growth_plan()
assert {:error, :upgrade_required} == unquote(mod).check_availability(user)
end
@ -33,29 +30,26 @@ defmodule Plausible.Billing.FeatureTest do
end
test "Plausible.Billing.Feature.StatsAPI.check_availability/2 returns :ok when user is on a business plan" do
user = insert(:user, subscription: build(:business_subscription))
user = new_user() |> subscribe_to_business_plan()
assert :ok == Plausible.Billing.Feature.StatsAPI.check_availability(user)
end
test "Plausible.Billing.Feature.StatsAPI.check_availability/2 returns :ok when user is on an old plan" do
user = insert(:user, subscription: build(:subscription, paddle_plan_id: @v1_plan_id))
user = new_user() |> subscribe_to_plan(@v1_plan_id)
assert :ok == Plausible.Billing.Feature.StatsAPI.check_availability(user)
end
test "Plausible.Billing.Feature.StatsAPI.check_availability/2 returns :ok when user is on trial" do
user = insert(:user)
user = new_user()
assert :ok == Plausible.Billing.Feature.StatsAPI.check_availability(user)
end
test "Plausible.Billing.Feature.StatsAPI.check_availability/2 returns :ok when user is on an enterprise plan" do
user =
insert(:user,
enterprise_plan:
build(:enterprise_plan,
paddle_plan_id: "123321",
features: [Plausible.Billing.Feature.StatsAPI]
),
subscription: build(:subscription, paddle_plan_id: "123321")
new_user()
|> subscribe_to_enterprise_plan(
paddle_plan_id: "123321",
features: [Plausible.Billing.Feature.StatsAPI]
)
assert :ok == Plausible.Billing.Feature.StatsAPI.check_availability(user)
@ -63,46 +57,40 @@ defmodule Plausible.Billing.FeatureTest do
@tag :ee_only
test "Plausible.Billing.Feature.StatsAPI.check_availability/2 returns error when user is on a growth plan" do
user = insert(:user, subscription: build(:growth_subscription))
user = new_user() |> subscribe_to_growth_plan()
assert {:error, :upgrade_required} ==
Plausible.Billing.Feature.StatsAPI.check_availability(user)
end
test "Plausible.Billing.Feature.StatsAPI.check_availability/2 returns :ok when user trial hasn't started and was created before the business tier launch" do
user = insert(:user, inserted_at: ~N[2020-01-01T00:00:00], trial_expiry_date: nil)
user = new_user(inserted_at: ~N[2020-01-01T00:00:00], trial_expiry_date: nil)
assert :ok == Plausible.Billing.Feature.StatsAPI.check_availability(user)
end
test "Plausible.Billing.Feature.StatsAPI.check_availability/2 returns :ok if user is subscribed and account was created after business tier launch" do
user = insert(:user, trial_expiry_date: nil, subscription: build(:business_subscription))
user = new_user(trial_expiry_date: nil) |> subscribe_to_business_plan()
assert :ok == Plausible.Billing.Feature.StatsAPI.check_availability(user)
end
@tag :ee_only
test "Plausible.Billing.Feature.StatsAPI.check_availability/2 returns error when user trial hasn't started and was created after the business tier launch" do
user = insert(:user, trial_expiry_date: nil)
user = new_user(trial_expiry_date: nil)
assert {:error, :upgrade_required} ==
Plausible.Billing.Feature.StatsAPI.check_availability(user)
end
test "Plausible.Billing.Feature.Props.check_availability/1 applies grandfathering to old plans" do
user = insert(:user, subscription: build(:subscription, paddle_plan_id: @v1_plan_id))
user = new_user() |> subscribe_to_plan(@v1_plan_id)
assert :ok == Plausible.Billing.Feature.Props.check_availability(user)
end
test "Plausible.Billing.Feature.Goals.check_availability/2 always returns :ok" do
u1 = insert(:user, subscription: build(:subscription, paddle_plan_id: @v1_plan_id))
u2 = insert(:user, subscription: build(:growth_subscription))
u3 = insert(:user, subscription: build(:business_subscription))
u4 =
insert(:user,
enterprise_plan: build(:enterprise_plan, paddle_plan_id: "123321"),
subscription: build(:subscription, paddle_plan_id: "123321")
)
u1 = new_user() |> subscribe_to_plan(@v1_plan_id)
u2 = new_user() |> subscribe_to_growth_plan()
u3 = new_user() |> subscribe_to_business_plan()
u4 = new_user() |> subscribe_to_enterprise_plan(paddle_plan_id: "123321")
assert :ok == Plausible.Billing.Feature.Goals.check_availability(u1)
assert :ok == Plausible.Billing.Feature.Goals.check_availability(u2)
@ -115,51 +103,56 @@ defmodule Plausible.Billing.FeatureTest do
{Plausible.Billing.Feature.Props, :props_enabled}
] do
test "#{mod}.toggle/2 toggles #{property} on and off" do
site = insert(:site, [{:members, [build(:user)]}, {unquote(property), false}])
user = new_user()
site = new_site([{:owner, user}, {unquote(property), false}])
{:ok, site} = unquote(mod).toggle(site)
{:ok, site} = unquote(mod).toggle(site, user)
assert Map.get(site, unquote(property))
assert unquote(mod).enabled?(site)
refute unquote(mod).opted_out?(site)
{:ok, site} = unquote(mod).toggle(site)
{:ok, site} = unquote(mod).toggle(site, user)
refute Map.get(site, unquote(property))
refute unquote(mod).enabled?(site)
assert unquote(mod).opted_out?(site)
end
test "#{mod}.toggle/2 accepts an override option" do
site = insert(:site, [{:members, [build(:user)]}, {unquote(property), false}])
user = new_user()
site = new_site([{:owner, user}, {unquote(property), false}])
{:ok, site} = unquote(mod).toggle(site, override: false)
{:ok, site} = unquote(mod).toggle(site, user, override: false)
refute Map.get(site, unquote(property))
refute unquote(mod).enabled?(site)
end
test "#{mod}.toggle/2 errors when enabling a feature the site owner does not have access to the feature" do
user = insert(:user, subscription: build(:growth_subscription))
site = insert(:site, [{:members, [user]}, {unquote(property), false}])
{:error, :upgrade_required} = unquote(mod).toggle(site)
user = new_user() |> subscribe_to_growth_plan()
site = new_site([{:owner, user}, {unquote(property), false}])
{:error, :upgrade_required} = unquote(mod).toggle(site, user)
refute unquote(mod).enabled?(site)
end
test "#{mod}.toggle/2 does not error when disabling a feature the site owner does not have access to" do
user = insert(:user, subscription: build(:growth_subscription))
site = insert(:site, [{:members, [user]}, {unquote(property), true}])
{:ok, site} = unquote(mod).toggle(site)
user = new_user() |> subscribe_to_growth_plan()
site = new_site([{:owner, user}, {unquote(property), true}])
{:ok, site} = unquote(mod).toggle(site, user)
assert unquote(mod).opted_out?(site)
end
end
test "Plausible.Billing.Feature.Goals.toggle/2 toggles conversions_enabled on and off" do
site = insert(:site, [{:members, [build(:user)]}, {:conversions_enabled, false}])
user = new_user()
site = new_site(owner: user, conversions_enabled: false)
{:ok, site} = Plausible.Billing.Feature.Goals.toggle(site)
{:ok, site} = Plausible.Billing.Feature.Goals.toggle(site, user)
assert Map.get(site, :conversions_enabled)
assert Plausible.Billing.Feature.Goals.enabled?(site)
refute Plausible.Billing.Feature.Goals.opted_out?(site)
{:ok, site} = Plausible.Billing.Feature.Goals.toggle(site)
{:ok, site} = Plausible.Billing.Feature.Goals.toggle(site, user)
refute Map.get(site, :conversions_enabled)
refute Plausible.Billing.Feature.Goals.enabled?(site)
assert Plausible.Billing.Feature.Goals.opted_out?(site)
@ -167,14 +160,14 @@ defmodule Plausible.Billing.FeatureTest do
for mod <- [Plausible.Billing.Feature.Funnels, Plausible.Billing.Feature.Props] do
test "#{mod}.enabled?/1 returns false when user does not have access to the feature even when enabled" do
user = insert(:user, subscription: build(:growth_subscription))
site = insert(:site, [{:members, [user]}, {unquote(mod).toggle_field(), true}])
user = new_user() |> subscribe_to_growth_plan()
site = new_site([{:owner, user}, {unquote(mod).toggle_field(), true}])
refute unquote(mod).enabled?(site)
end
test "#{mod}.opted_out?/1 returns false when feature toggle is enabled even when user does not have access to the feature" do
user = insert(:user, subscription: build(:growth_subscription))
site = insert(:site, [{:members, [user]}, {unquote(mod).toggle_field(), true}])
user = new_user() |> subscribe_to_growth_plan()
site = new_site([{:owner, user}, {unquote(mod).toggle_field(), true}])
refute unquote(mod).opted_out?(site)
end
end

View File

@ -510,8 +510,8 @@ defmodule Plausible.Billing.QuotaTest do
on_ee do
test "returns [Funnels] when user/site uses funnels" do
user = insert(:user)
site = insert(:site, memberships: [build(:site_membership, user: user, role: :owner)])
user = new_user()
site = new_site(owner: user)
goals = insert_list(3, :goal, site: site, event_name: fn -> Ecto.UUID.generate() end)
steps = Enum.map(goals, &%{"goal_id" => &1.id})
@ -550,13 +550,13 @@ defmodule Plausible.Billing.QuotaTest do
on_ee do
test "returns multiple features used by the user" do
user = insert(:user)
user = new_user()
insert(:api_key, user: user)
site =
insert(:site,
new_site(
allowed_event_props: ["dummy"],
memberships: [build(:site_membership, user: user, role: :owner)]
owner: user
)
insert(:goal, currency: :USD, site: site, event_name: "Purchase")

View File

@ -3,6 +3,7 @@ defmodule Plausible.FunnelsTest do
@moduletag :ee_only
use Plausible
use Plausible.Teams.Test
on_ee do
alias Plausible.Goals
@ -10,7 +11,7 @@ defmodule Plausible.FunnelsTest do
alias Plausible.Stats
setup do
site = insert(:site)
site = new_site()
{:ok, g1} = Goals.create(site, %{"page_path" => "/go/to/blog/**"})
{:ok, g2} = Goals.create(site, %{"event_name" => "Signup"})

View File

@ -1,10 +1,11 @@
defmodule Plausible.GoalsTest do
use Plausible.DataCase
use Plausible
use Plausible.Teams.Test
alias Plausible.Goals
test "create/2 creates goals and trims input" do
site = insert(:site)
site = new_site()
{:ok, goal} = Goals.create(site, %{"page_path" => "/foo bar "})
assert goal.page_path == "/foo bar"
assert goal.display_name == "Visit /foo bar"
@ -20,33 +21,33 @@ defmodule Plausible.GoalsTest do
end
test "create/2 creates pageview goal and adds a leading slash if missing" do
site = insert(:site)
site = new_site()
{:ok, goal} = Goals.create(site, %{"page_path" => "foo bar"})
assert goal.page_path == "/foo bar"
end
test "create/2 validates goal name is at most 120 chars" do
site = insert(:site)
site = new_site()
assert {:error, changeset} = Goals.create(site, %{"event_name" => String.duplicate("a", 130)})
assert {"should be at most %{count} character(s)", _} = changeset.errors[:event_name]
end
test "create/2 fails to create the same pageview goal twice" do
site = insert(:site)
site = new_site()
{:ok, _} = Goals.create(site, %{"page_path" => "foo bar"})
assert {:error, changeset} = Goals.create(site, %{"page_path" => "foo bar"})
assert {"has already been taken", _} = changeset.errors[:page_path]
end
test "create/2 fails to create the same custom event goal twice" do
site = insert(:site)
site = new_site()
{:ok, _} = Goals.create(site, %{"event_name" => "foo bar"})
assert {:error, changeset} = Goals.create(site, %{"event_name" => "foo bar"})
assert {"has already been taken", _} = changeset.errors[:event_name]
end
test "create/2 fails to create the same currency goal twice" do
site = insert(:site)
site = new_site()
{:ok, _} = Goals.create(site, %{"event_name" => "foo bar", "currency" => "EUR"})
assert {:error, changeset} =
@ -56,7 +57,7 @@ defmodule Plausible.GoalsTest do
end
test "create/2 fails to create a goal with 'pageleave' as event_name (reserved)" do
site = insert(:site)
site = new_site()
assert {:error, changeset} = Goals.create(site, %{"event_name" => "pageleave"})
assert {"The event name 'pageleave' is reserved and cannot be used as a goal", _} =
@ -65,14 +66,14 @@ defmodule Plausible.GoalsTest do
@tag :ee_only
test "create/2 sets site.updated_at for revenue goal" do
site_1 = insert(:site, updated_at: DateTime.add(DateTime.utc_now(), -3600))
site_1 = new_site(updated_at: DateTime.add(DateTime.utc_now(), -3600))
{:ok, _goal_1} = Goals.create(site_1, %{"event_name" => "Checkout", "currency" => "BRL"})
assert NaiveDateTime.compare(site_1.updated_at, Plausible.Repo.reload!(site_1).updated_at) ==
:lt
site_2 = insert(:site, updated_at: DateTime.add(DateTime.utc_now(), -3600))
site_2 = new_site(updated_at: DateTime.add(DateTime.utc_now(), -3600))
{:ok, _goal_2} = Goals.create(site_2, %{"event_name" => "Read Article", "currency" => nil})
assert NaiveDateTime.compare(site_2.updated_at, Plausible.Repo.reload!(site_2).updated_at) ==
@ -81,7 +82,7 @@ defmodule Plausible.GoalsTest do
@tag :ee_only
test "create/2 creates revenue goal" do
site = insert(:site)
site = new_site()
{:ok, goal} = Goals.create(site, %{"event_name" => "Purchase", "currency" => "EUR"})
assert goal.event_name == "Purchase"
assert goal.page_path == nil
@ -90,8 +91,8 @@ defmodule Plausible.GoalsTest do
@tag :ee_only
test "create/2 returns error when site does not have access to revenue goals" do
user = insert(:user, subscription: build(:growth_subscription))
site = insert(:site, members: [user])
user = new_user() |> subscribe_to_growth_plan()
site = new_site(owner: user)
{:error, :upgrade_required} =
Goals.create(site, %{"event_name" => "Purchase", "currency" => "EUR"})
@ -99,7 +100,7 @@ defmodule Plausible.GoalsTest do
@tag :ee_only
test "create/2 fails for unknown currency code" do
site = insert(:site)
site = new_site()
assert {:error, changeset} =
Goals.create(site, %{"event_name" => "Purchase", "currency" => "Euro"})
@ -108,7 +109,7 @@ defmodule Plausible.GoalsTest do
end
test "update/2 updates a goal" do
site = insert(:site)
site = new_site()
{:ok, goal1} = Goals.create(site, %{"page_path" => "/foo bar "})
{:ok, goal2} = Goals.update(goal1, %{"page_path" => "/", "display_name" => "Homepage"})
assert goal1.id == goal2.id
@ -118,7 +119,7 @@ defmodule Plausible.GoalsTest do
@tag :ee_only
test "list_revenue_goals/1 lists event_names and currencies for each revenue goal" do
site = insert(:site)
site = new_site()
Goals.create(site, %{"event_name" => "One", "currency" => "EUR"})
Goals.create(site, %{"event_name" => "Two", "currency" => "EUR"})
@ -135,7 +136,7 @@ defmodule Plausible.GoalsTest do
end
test "create/2 clears currency for pageview goals" do
site = insert(:site)
site = new_site()
{:ok, goal} = Goals.create(site, %{"page_path" => "/purchase", "currency" => "EUR"})
assert goal.event_name == nil
assert goal.page_path == "/purchase"
@ -143,7 +144,7 @@ defmodule Plausible.GoalsTest do
end
test "for_site/1 returns trimmed input even if it was saved with trailing whitespace" do
site = insert(:site)
site = new_site()
insert(:goal, %{site: site, event_name: " Signup "})
insert(:goal, %{site: site, page_path: " /Signup "})
@ -153,7 +154,7 @@ defmodule Plausible.GoalsTest do
end
test "goals are present after domain change" do
site = insert(:site)
site = new_site()
insert(:goal, %{site: site, event_name: " Signup "})
insert(:goal, %{site: site, page_path: " /Signup "})
@ -163,7 +164,7 @@ defmodule Plausible.GoalsTest do
end
test "goals are removed when site is deleted" do
site = insert(:site)
site = new_site()
insert(:goal, %{site: site, event_name: " Signup "})
insert(:goal, %{site: site, page_path: " /Signup "})
@ -173,7 +174,7 @@ defmodule Plausible.GoalsTest do
end
test "goals can be deleted" do
site = insert(:site)
site = new_site()
goal = insert(:goal, %{site: site, event_name: " Signup "})
:ok = Goals.delete(goal.id, site)
assert [] = Goals.for_site(site)
@ -181,7 +182,7 @@ defmodule Plausible.GoalsTest do
on_ee do
test "goals can be fetched with funnel count preloaded" do
site = insert(:site)
site = new_site()
goals =
Enum.map(1..4, fn i ->
@ -218,7 +219,7 @@ defmodule Plausible.GoalsTest do
end
test "deleting goals with funnels triggers funnel reduction" do
site = insert(:site)
site = new_site()
{:ok, g1} = Goals.create(site, %{"page_path" => "/1"})
{:ok, g2} = Goals.create(site, %{"page_path" => "/2"})
{:ok, g3} = Goals.create(site, %{"page_path" => "/3"})
@ -257,7 +258,7 @@ defmodule Plausible.GoalsTest do
end
test "must be either page_path or event_name" do
site = insert(:site)
site = new_site()
assert {:error, changeset} =
Goals.create(site, %{"page_path" => "/foo", "event_name" => "/foo"})

View File

@ -9,7 +9,7 @@ defmodule Plausible.Google.APITest do
import Mox
setup :verify_on_exit!
setup [:create_user, :create_new_site]
setup [:create_user, :create_site]
describe "fetch_stats/3 errors" do
setup %{user: user, site: site} do

View File

@ -4,7 +4,7 @@ defmodule Plausible.Imported.BufferTest do
import Ecto.Query
alias Plausible.Imported.Buffer
setup [:create_user, :create_new_site, :set_buffer_size]
setup [:create_user, :create_site, :set_buffer_size]
defp set_buffer_size(_setup_args) do
imported_setting = Application.fetch_env!(:plausible, :imported)

View File

@ -13,7 +13,7 @@ defmodule Plausible.Imported.CSVImporterTest do
end
describe "new_import/3 and parse_args/1" do
setup [:create_user, :create_new_site]
setup [:create_user, :create_site]
test "parses job args properly", %{user: user, site: site} do
tables = [
@ -81,7 +81,7 @@ defmodule Plausible.Imported.CSVImporterTest do
end
describe "import_data/2" do
setup [:create_user, :create_new_site, :clean_buckets]
setup [:create_user, :create_site, :clean_buckets]
@describetag :tmp_dir

View File

@ -33,7 +33,7 @@ defmodule Plausible.Imported.GoogleAnalytics4Test do
setup :verify_on_exit!
describe "parse_args/1 and import_data/2" do
setup [:create_user, :create_new_site]
setup [:create_user, :create_site]
test "imports data returned from GA4 Data API", %{conn: conn, user: user, site: site} do
past = DateTime.add(DateTime.utc_now(), -3600, :second)

View File

@ -1,16 +1,17 @@
defmodule Plausible.PropsTest do
use Plausible.DataCase
use Plausible.Teams.Test
test "allow/2 returns error when user plan does not include props" do
user = insert(:user, subscription: build(:growth_subscription))
site = insert(:site, members: [user])
user = new_user() |> subscribe_to_growth_plan()
site = new_site(owner: user)
assert {:error, :upgrade_required} = Plausible.Props.allow(site, "my-prop-1")
assert %Plausible.Site{allowed_event_props: nil} = Plausible.Repo.reload!(site)
end
test "allow/2 adds props to the array" do
site = insert(:site)
site = new_site()
assert {:ok, site} = Plausible.Props.allow(site, "my-prop-1")
assert {:ok, site} = Plausible.Props.allow(site, "my-prop-2")
@ -20,7 +21,7 @@ defmodule Plausible.PropsTest do
end
test "allow/2 takes a single prop or multiple" do
site = insert(:site)
site = new_site()
assert {:ok, site} = Plausible.Props.allow(site, "my-prop-1")
assert {:ok, site} = Plausible.Props.allow(site, ["my-prop-3", "my-prop-2"])
@ -30,14 +31,14 @@ defmodule Plausible.PropsTest do
end
test "allow/2 trims trailing whitespaces" do
site = insert(:site)
site = new_site()
assert {:ok, site} = Plausible.Props.allow(site, " my-prop-1 ")
assert %Plausible.Site{allowed_event_props: ["my-prop-1"]} = Plausible.Repo.reload!(site)
end
test "allow/2 fails when prop list is too long" do
site = insert(:site)
site = new_site()
props = for i <- 1..300, do: "my-prop-#{i}"
assert {:ok, site} = Plausible.Props.allow(site, props)
@ -49,7 +50,7 @@ defmodule Plausible.PropsTest do
end
test "allow/2 fails when prop key is too long" do
site = insert(:site)
site = new_site()
long_prop = String.duplicate("a", 301)
assert {:error, changeset} = Plausible.Props.allow(site, long_prop)
@ -57,7 +58,7 @@ defmodule Plausible.PropsTest do
end
test "allow/2 fails when prop key is empty" do
site = insert(:site)
site = new_site()
assert {:error, changeset} = Plausible.Props.allow(site, "")
assert {"must be between 1 and 300 characters", []} == changeset.errors[:allowed_event_props]
@ -67,7 +68,7 @@ defmodule Plausible.PropsTest do
end
test "allow/2 does not fail when prop key is already in the list" do
site = insert(:site)
site = new_site()
assert {:ok, site} = Plausible.Props.allow(site, "my-prop-1")
assert {:ok, site} = Plausible.Props.allow(site, "my-prop-1")
@ -75,7 +76,7 @@ defmodule Plausible.PropsTest do
end
test "disallow/2 removes the prop from the array" do
site = insert(:site)
site = new_site()
assert {:ok, site} = Plausible.Props.allow(site, "my-prop-1")
assert {:ok, site} = Plausible.Props.allow(site, "my-prop-2")
@ -84,7 +85,7 @@ defmodule Plausible.PropsTest do
end
test "disallow/2 does not fail when prop is not in the list" do
site = insert(:site)
site = new_site()
assert {:ok, site} = Plausible.Props.allow(site, "my-prop-1")
assert {:ok, site} = Plausible.Props.disallow(site, "my-prop-2")
@ -92,8 +93,8 @@ defmodule Plausible.PropsTest do
end
test "allow_existing_props/2 returns error when user plan does not include props" do
user = insert(:user, subscription: build(:growth_subscription))
site = insert(:site, members: [user])
user = new_user() |> subscribe_to_growth_plan()
site = new_site(owner: user)
populate_stats(site, [
build(:event,
@ -118,7 +119,7 @@ defmodule Plausible.PropsTest do
end
test "allow_existing_props/1 saves the most frequent prop keys" do
site = insert(:site)
site = new_site()
populate_stats(site, [
build(:event,
@ -145,7 +146,7 @@ defmodule Plausible.PropsTest do
end
test "allow_existing_props/1 skips invalid keys" do
site = insert(:site)
site = new_site()
populate_stats(site, [
build(:event,
@ -172,7 +173,7 @@ defmodule Plausible.PropsTest do
end
test "allow_existing_props/1 can be run multiple times" do
site = insert(:site)
site = new_site()
populate_stats(site, [
build(:event,
@ -227,7 +228,7 @@ defmodule Plausible.PropsTest do
end
test "suggest_keys_to_allow/2 returns prop keys from events" do
site = insert(:site)
site = new_site()
populate_stats(site, [
build(:event,
@ -252,7 +253,7 @@ defmodule Plausible.PropsTest do
end
test "suggest_keys_to_allow/2 does not return internal prop keys from special event types" do
site = insert(:site)
site = new_site()
populate_stats(site, [
build(:event,
@ -282,7 +283,7 @@ defmodule Plausible.PropsTest do
end
test "configured?/1 returns whether the site has allow at least one prop" do
site = insert(:site)
site = new_site()
refute Plausible.Props.configured?(site)
{:ok, site} = Plausible.Props.allow(site, "hello-world")

View File

@ -1,5 +1,6 @@
defmodule Plausible.Site.CacheTest do
use Plausible.DataCase, async: true
use Plausible.Teams.Test
alias Plausible.{Site, Goal}
alias Plausible.Site.Cache
@ -60,7 +61,7 @@ defmodule Plausible.Site.CacheTest do
name: :"cache_supervisor_#{test}"
)
%{id: site_id} = site = insert(:site, domain: "site1.example.com")
%{id: site_id} = site = new_site(domain: "site1.example.com")
{:ok, _goal} =
Plausible.Goals.create(site, %{"event_name" => "Purchase", "currency" => :BRL})
@ -95,7 +96,7 @@ defmodule Plausible.Site.CacheTest do
yesterday = DateTime.utc_now() |> DateTime.add(-1 * 60 * 60 * 24)
# the site was added yesterday so full refresh will pick it up
%{id: site_id} = site = insert(:site, domain: "site1.example.com", updated_at: yesterday)
%{id: site_id} = site = new_site(domain: "site1.example.com", updated_at: yesterday)
# the goal was added yesterday so full refresh will pick it up
Plausible.Goals.create(site, %{"event_name" => "Purchase", "currency" => :BRL},

View File

@ -3,7 +3,7 @@ defmodule Plausible.Stats.ComparisonsTest do
alias Plausible.Stats.{DateTimeRange, Query, Comparisons}
import Plausible.TestUtils
setup [:create_user, :create_new_site]
setup [:create_user, :create_site]
def build_query(site, params, now) do
query = Query.from(site, params)

View File

@ -1,11 +1,12 @@
defmodule Plausible.Stats.Filters.QueryParserTest do
use Plausible.DataCase
use Plausible.Teams.Test
alias Plausible.Stats.DateTimeRange
alias Plausible.Stats.Filters
import Plausible.Stats.Filters.QueryParser
setup [:create_user, :create_new_site]
setup [:create_user, :create_site]
@now DateTime.new!(~D[2021-05-05], ~T[12:30:00], "Etc/UTC")
@date_range_realtime %DateTimeRange{
@ -1289,10 +1290,7 @@ defmodule Plausible.Stats.Filters.QueryParserTest do
describe "custom props access" do
test "filters - no access", %{site: site, user: user} do
ep =
insert(:enterprise_plan, features: [Plausible.Billing.Feature.StatsAPI], user_id: user.id)
insert(:subscription, user: user, paddle_plan_id: ep.paddle_plan_id)
subscribe_to_enterprise_plan(user, features: [Plausible.Billing.Feature.StatsAPI])
%{
"site_id" => site.domain,
@ -1307,10 +1305,7 @@ defmodule Plausible.Stats.Filters.QueryParserTest do
end
test "dimensions - no access", %{site: site, user: user} do
ep =
insert(:enterprise_plan, features: [Plausible.Billing.Feature.StatsAPI], user_id: user.id)
insert(:subscription, user: user, paddle_plan_id: ep.paddle_plan_id)
subscribe_to_enterprise_plan(user, features: [Plausible.Billing.Feature.StatsAPI])
%{
"site_id" => site.domain,
@ -1523,10 +1518,7 @@ defmodule Plausible.Stats.Filters.QueryParserTest do
test "no access", %{site: site, user: user, subscription: subscription} do
Repo.delete!(subscription)
plan =
insert(:enterprise_plan, features: [Plausible.Billing.Feature.StatsAPI], user_id: user.id)
insert(:subscription, user: user, paddle_plan_id: plan.paddle_plan_id)
subscribe_to_enterprise_plan(user, features: [Plausible.Billing.Feature.StatsAPI])
%{
"site_id" => site.domain,

View File

@ -1,10 +1,11 @@
defmodule PlausibleWeb.Components.Billing.NoticeTest do
use Plausible.DataCase
use Plausible.Teams.Test
import Plausible.LiveViewTest, only: [render_component: 2]
alias PlausibleWeb.Components.Billing.Notice
test "premium_feature/1 does not render a notice when user is on trial" do
me = insert(:user)
me = new_user()
assert render_component(&Notice.premium_feature/1,
billable_user: me,
@ -14,7 +15,7 @@ defmodule PlausibleWeb.Components.Billing.NoticeTest do
end
test "premium_feature/1 renders an upgrade link when user is the site owner and does not have access to the feature" do
me = insert(:user, subscription: build(:growth_subscription))
me = new_user() |> subscribe_to_growth_plan()
rendered =
render_component(&Notice.premium_feature/1,
@ -29,8 +30,8 @@ defmodule PlausibleWeb.Components.Billing.NoticeTest do
end
test "premium_feature/1 does not render an upgrade link when user is not the site owner" do
me = insert(:user)
owner = insert(:user, subscription: build(:growth_subscription))
me = new_user() |> subscribe_to_growth_plan()
owner = new_user() |> subscribe_to_growth_plan()
rendered =
render_component(&Notice.premium_feature/1,
@ -44,7 +45,7 @@ defmodule PlausibleWeb.Components.Billing.NoticeTest do
end
test "premium_feature/1 does not render a notice when the user has access to the feature" do
me = insert(:user, subscription: build(:business_subscription))
me = new_user() |> subscribe_to_business_plan()
rendered =
render_component(&Notice.premium_feature/1,
@ -57,7 +58,7 @@ defmodule PlausibleWeb.Components.Billing.NoticeTest do
end
test "limit_exceeded/1 when billable user is on growth displays upgrade link" do
me = insert(:user, subscription: build(:growth_subscription))
me = new_user() |> subscribe_to_growth_plan()
rendered =
render_component(&Notice.limit_exceeded/1,
@ -73,7 +74,7 @@ defmodule PlausibleWeb.Components.Billing.NoticeTest do
end
test "limit_exceeded/1 when billable user is on growth but is not current user does not display upgrade link" do
me = insert(:user, subscription: build(:growth_subscription))
me = new_user() |> subscribe_to_growth_plan()
rendered =
render_component(&Notice.limit_exceeded/1,
@ -89,7 +90,7 @@ defmodule PlausibleWeb.Components.Billing.NoticeTest do
@tag :ee_only
test "limit_exceeded/1 when billable user is on trial displays upgrade link" do
me = insert(:user)
me = new_user()
rendered =
render_component(&Notice.limit_exceeded/1,
@ -106,11 +107,7 @@ defmodule PlausibleWeb.Components.Billing.NoticeTest do
@tag :ee_only
test "limit_exceeded/1 when billable user is on an enterprise plan displays support email" do
me =
insert(:user,
enterprise_plan: build(:enterprise_plan, paddle_plan_id: "123321"),
subscription: build(:subscription, paddle_plan_id: "123321")
)
me = new_user() |> subscribe_to_enterprise_plan()
rendered =
render_component(&Notice.limit_exceeded/1,
@ -128,7 +125,7 @@ defmodule PlausibleWeb.Components.Billing.NoticeTest do
@tag :ee_only
test "limit_exceeded/1 when billable user is on a business plan displays support email" do
me = insert(:user, subscription: build(:business_subscription))
me = new_user() |> subscribe_to_business_plan()
rendered =
render_component(&Notice.limit_exceeded/1,

View File

@ -108,7 +108,7 @@ defmodule PlausibleWeb.Api.ExternalSitesControllerTest do
end
describe "DELETE /api/v1/sites/:site_id" do
setup :create_new_site
setup :create_site
test "delete a site by its domain", %{conn: conn, site: site} do
conn = delete(conn, "/api/v1/sites/" <> site.domain)
@ -439,7 +439,7 @@ defmodule PlausibleWeb.Api.ExternalSitesControllerTest do
end
describe "DELETE /api/v1/sites/goals/:goal_id" do
setup :create_new_site
setup :create_site
test "delete a goal by its id", %{conn: conn, site: site} do
conn =
@ -624,7 +624,7 @@ defmodule PlausibleWeb.Api.ExternalSitesControllerTest do
end
describe "GET /api/v1/sites/:site_id" do
setup :create_new_site
setup :create_site
test "get a site by its domain", %{conn: conn, site: site} do
site =
@ -687,7 +687,7 @@ defmodule PlausibleWeb.Api.ExternalSitesControllerTest do
end
describe "GET /api/v1/goals" do
setup :create_new_site
setup :create_site
test "returns empty when there are no goals for site", %{conn: conn, site: site} do
conn = get(conn, "/api/v1/sites/goals?site_id=" <> site.domain)
@ -832,7 +832,7 @@ defmodule PlausibleWeb.Api.ExternalSitesControllerTest do
end
describe "PUT /api/v1/sites/:site_id" do
setup :create_new_site
setup :create_site
test "can change domain name", %{conn: conn, site: site} do
old_domain = site.domain

View File

@ -1,9 +1,10 @@
defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
use PlausibleWeb.ConnCase
use Plausible.Teams.Test
import Plausible.TestUtils
alias Plausible.Billing.Feature
setup [:create_user, :create_new_site, :create_api_key, :use_api_key]
setup [:create_user, :create_site, :create_api_key, :use_api_key]
@user_id Enum.random(1000..9999)
describe "feature access" do
@ -12,8 +13,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
user: user,
site: site
} do
ep = insert(:enterprise_plan, features: [Feature.StatsAPI], user_id: user.id)
insert(:subscription, user: user, paddle_plan_id: ep.paddle_plan_id)
subscribe_to_enterprise_plan(user, features: [Feature.StatsAPI])
conn =
get(conn, "/api/v1/stats/aggregate", %{
@ -30,8 +30,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AggregateTest do
user: user,
site: site
} do
ep = insert(:enterprise_plan, features: [Feature.StatsAPI], user_id: user.id)
insert(:subscription, user: user, paddle_plan_id: ep.paddle_plan_id)
subscribe_to_enterprise_plan(user, features: [Feature.StatsAPI])
conn =
get(conn, "/api/v1/stats/aggregate", %{

View File

@ -1,5 +1,6 @@
defmodule PlausibleWeb.Api.ExternalStatsController.AuthTest do
use PlausibleWeb.ConnCase
use Plausible.Teams.Test
setup [:create_user, :create_api_key]
@ -156,8 +157,8 @@ defmodule PlausibleWeb.Api.ExternalStatsController.AuthTest do
user: user,
api_key: api_key
} do
insert(:growth_subscription, user: user)
site = insert(:site, members: [user])
subscribe_to_growth_plan(user)
site = new_site(owner: user)
conn
|> with_api_key(api_key)

View File

@ -1,10 +1,12 @@
defmodule PlausibleWeb.Api.ExternalStatsController.BreakdownTest do
use PlausibleWeb.ConnCase
use Plausible.Teams.Test
alias Plausible.Billing.Feature
@user_id Enum.random(1000..9999)
setup [:create_user, :create_new_site, :create_api_key, :use_api_key]
setup [:create_user, :create_site, :create_api_key, :use_api_key]
describe "feature access" do
test "cannot break down by a custom prop without access to the props feature", %{
@ -12,8 +14,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.BreakdownTest do
user: user,
site: site
} do
ep = insert(:enterprise_plan, features: [Feature.StatsAPI], user_id: user.id)
insert(:subscription, user: user, paddle_plan_id: ep.paddle_plan_id)
subscribe_to_enterprise_plan(user, features: [Feature.StatsAPI])
conn =
get(conn, "/api/v1/stats/breakdown", %{
@ -30,8 +31,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.BreakdownTest do
user: user,
site: site
} do
ep = insert(:enterprise_plan, features: [Feature.StatsAPI], user_id: user.id)
insert(:subscription, user: user, paddle_plan_id: ep.paddle_plan_id)
subscribe_to_enterprise_plan(user, features: [Feature.StatsAPI])
conn =
get(conn, "/api/v1/stats/breakdown", %{
@ -47,10 +47,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.BreakdownTest do
user: user,
site: site
} do
ep =
insert(:enterprise_plan, features: [Feature.StatsAPI], user_id: user.id)
insert(:subscription, user: user, paddle_plan_id: ep.paddle_plan_id)
subscribe_to_enterprise_plan(user, features: [Feature.StatsAPI])
conn =
get(conn, "/api/v1/stats/breakdown", %{

View File

@ -1,7 +1,7 @@
defmodule PlausibleWeb.Api.ExternalStatsController.QueryComparisonsTest do
use PlausibleWeb.ConnCase
setup [:create_user, :create_new_site, :create_api_key, :use_api_key, :create_site_import]
setup [:create_user, :create_site, :create_api_key, :use_api_key, :create_site_import]
test "aggregates a single metric", %{conn: conn, site: site} do
populate_stats(site, [

View File

@ -3,7 +3,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.QueryGoalDimensionTest do
@user_id Enum.random(1000..9999)
setup [:create_user, :create_new_site, :create_api_key, :use_api_key]
setup [:create_user, :create_site, :create_api_key, :use_api_key]
describe "breakdown by event:goal" do
test "returns custom event goals and pageview goals", %{conn: conn, site: site} do

View File

@ -3,7 +3,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.QueryImportedTest do
@user_id Enum.random(1000..9999)
setup [:create_user, :create_new_site, :create_api_key, :use_api_key]
setup [:create_user, :create_site, :create_api_key, :use_api_key]
describe "aggregation with imported data" do
setup :create_site_import

View File

@ -1,7 +1,7 @@
defmodule PlausibleWeb.Api.ExternalStatsController.QuerySpecialMetricsTest do
use PlausibleWeb.ConnCase
setup [:create_user, :create_new_site, :create_api_key, :use_api_key]
setup [:create_user, :create_site, :create_api_key, :use_api_key]
test "returns conversion_rate in a goal filtered custom prop breakdown", %{
conn: conn,

View File

@ -3,7 +3,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.QueryTest do
@user_id Enum.random(1000..9999)
setup [:create_user, :create_new_site, :create_api_key, :use_api_key]
setup [:create_user, :create_site, :create_api_key, :use_api_key]
test "aggregates a single metric", %{conn: conn, site: site} do
populate_stats(site, [

View File

@ -1,8 +1,10 @@
defmodule PlausibleWeb.Api.ExternalStatsController.QueryValidationsTest do
use PlausibleWeb.ConnCase
use Plausible.Teams.Test
alias Plausible.Billing.Feature
setup [:create_user, :create_new_site, :create_api_key, :use_api_key]
setup [:create_user, :create_site, :create_api_key, :use_api_key]
describe "feature access" do
test "cannot break down by a custom prop without access to the props feature", %{
@ -10,8 +12,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.QueryValidationsTest do
user: user,
site: site
} do
ep = insert(:enterprise_plan, features: [Feature.StatsAPI], user_id: user.id)
insert(:subscription, user: user, paddle_plan_id: ep.paddle_plan_id)
subscribe_to_enterprise_plan(user, features: [Feature.StatsAPI])
conn =
post(conn, "/api/v2/query", %{
@ -30,8 +31,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.QueryValidationsTest do
user: user,
site: site
} do
ep = insert(:enterprise_plan, features: [Feature.StatsAPI], user_id: user.id)
insert(:subscription, user: user, paddle_plan_id: ep.paddle_plan_id)
subscribe_to_enterprise_plan(user, features: [Feature.StatsAPI])
conn =
post(conn, "/api/v2/query", %{
@ -49,10 +49,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.QueryValidationsTest do
user: user,
site: site
} do
ep =
insert(:enterprise_plan, features: [Feature.StatsAPI], user_id: user.id)
insert(:subscription, user: user, paddle_plan_id: ep.paddle_plan_id)
subscribe_to_enterprise_plan(user, features: [Feature.StatsAPI])
conn =
post(conn, "/api/v2/query", %{
@ -72,8 +69,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.QueryValidationsTest do
user: user,
site: site
} do
ep = insert(:enterprise_plan, features: [Feature.StatsAPI], user_id: user.id)
insert(:subscription, user: user, paddle_plan_id: ep.paddle_plan_id)
subscribe_to_enterprise_plan(user, features: [Feature.StatsAPI])
conn =
post(conn, "/api/v2/query", %{

View File

@ -1,8 +1,9 @@
defmodule PlausibleWeb.Api.ExternalStatsController.TimeseriesTest do
use PlausibleWeb.ConnCase
use Plausible.Teams.Test
alias Plausible.Billing.Feature
setup [:create_user, :create_new_site, :create_api_key, :use_api_key]
setup [:create_user, :create_site, :create_api_key, :use_api_key]
describe "feature access" do
test "cannot filter by a custom prop without access to the props feature", %{
@ -10,8 +11,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.TimeseriesTest do
user: user,
site: site
} do
ep = insert(:enterprise_plan, features: [Feature.StatsAPI], user_id: user.id)
insert(:subscription, user: user, paddle_plan_id: ep.paddle_plan_id)
subscribe_to_enterprise_plan(user, features: [Feature.StatsAPI])
conn =
get(conn, "/api/v1/stats/timeseries", %{
@ -30,8 +30,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController.TimeseriesTest do
user: user,
site: site
} do
ep = insert(:enterprise_plan, features: [Feature.StatsAPI], user_id: user.id)
insert(:subscription, user: user, paddle_plan_id: ep.paddle_plan_id)
subscribe_to_enterprise_plan(user, features: [Feature.StatsAPI])
conn =
get(conn, "/api/v1/stats/timeseries", %{

View File

@ -4,7 +4,7 @@ defmodule PlausibleWeb.Api.InternalController.DocsQueryTest do
@user_id Enum.random(1000..9999)
describe "POST /api/docs/query not logged in" do
setup [:create_user, :create_new_site]
setup [:create_user, :create_site]
test "rejects request when not logged in", %{conn: conn, site: site} do
populate_stats(site, [
@ -25,7 +25,7 @@ defmodule PlausibleWeb.Api.InternalController.DocsQueryTest do
end
describe "POST /api/docs/query logged in" do
setup [:create_user, :create_new_site, :log_in]
setup [:create_user, :create_site, :log_in]
test "rejects when accessing any other site", %{conn: conn} do
conn =

View File

@ -2,7 +2,7 @@ defmodule PlausibleWeb.Api.StatsController.BrowsersTest do
use PlausibleWeb.ConnCase
describe "GET /api/stats/:domain/browsers" do
setup [:create_user, :log_in, :create_new_site, :create_site_import]
setup [:create_user, :log_in, :create_site, :create_site_import]
test "returns top browsers by unique visitors", %{conn: conn, site: site} do
populate_stats(site, [
@ -274,7 +274,7 @@ defmodule PlausibleWeb.Api.StatsController.BrowsersTest do
end
describe "GET /api/stats/:domain/browser-versions" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns correct conversion_rate when browser_version clashes across browsers", %{
conn: conn,

View File

@ -32,7 +32,7 @@ defmodule PlausibleWeb.Api.StatsController.CitiesTest do
])
end
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import, :seed]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import, :seed]
test "returns top cities by new visitors", %{conn: conn, site: site} do
conn = get(conn, "/api/stats/#{site.domain}/cities?period=day")

View File

@ -4,7 +4,7 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
@user_id Enum.random(1000..9999)
describe "GET /api/stats/:domain/conversions" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "returns mixed conversions in ordered by count", %{conn: conn, site: site} do
populate_stats(site, [
@ -324,9 +324,12 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
site: site,
user: user
} do
user
|> Plausible.Auth.User.end_trial()
|> Plausible.Repo.update!()
user =
user
|> Plausible.Auth.User.end_trial()
|> Plausible.Repo.update!()
Plausible.Teams.sync_team(user)
populate_stats(site, [
build(:event,
@ -438,7 +441,7 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
end
describe "GET /api/stats/:domain/conversions - with goal filter" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "does not consider custom event pathname as a pageview goal completion", %{
conn: conn,
@ -625,7 +628,7 @@ defmodule PlausibleWeb.Api.StatsController.ConversionsTest do
end
describe "GET /api/stats/:domain/conversions - with goal and prop=(none) filter" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "returns only the conversion that is filtered for", %{conn: conn, site: site} do
populate_stats(site, [

View File

@ -2,7 +2,7 @@ defmodule PlausibleWeb.Api.StatsController.CountriesTest do
use PlausibleWeb.ConnCase
describe "GET /api/stats/:domain/countries" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns top countries by new visitors", %{conn: conn, site: site} do
populate_stats(site, [

View File

@ -1,8 +1,9 @@
defmodule PlausibleWeb.Api.StatsController.CustomPropBreakdownTest do
use PlausibleWeb.ConnCase
use Plausible.Teams.Test
describe "GET /api/stats/:domain/custom-prop-values/:prop_key" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns breakdown by a custom property", %{conn: conn, site: site} do
prop_key = "parim_s6ber"
@ -151,7 +152,7 @@ defmodule PlausibleWeb.Api.StatsController.CustomPropBreakdownTest do
end
describe "GET /api/stats/:domain/custom-prop-values/:prop_key - with goal filter" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "returns property breakdown for goal", %{conn: conn, site: site} do
populate_stats(site, [
@ -906,7 +907,7 @@ defmodule PlausibleWeb.Api.StatsController.CustomPropBreakdownTest do
end
describe "GET /api/stats/:domain/custom-prop-values/:prop_key - other filters" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "returns prop-breakdown with a page filter", %{conn: conn, site: site} do
prop_key = "parim_s6ber"
@ -1104,10 +1105,10 @@ defmodule PlausibleWeb.Api.StatsController.CustomPropBreakdownTest do
end
describe "GET /api/stats/:domain/custom-prop-values/:prop_key - for a Growth subscription" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
setup %{user: user, site: site} do
insert(:growth_subscription, user: user)
subscribe_to_growth_plan(user)
populate_stats(site, [
build(:pageview,
@ -1144,7 +1145,7 @@ defmodule PlausibleWeb.Api.StatsController.CustomPropBreakdownTest do
end
describe "with imported data" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "gracefully ignores unsupported WP Search Queries goal for imported data", %{
conn: conn,

View File

@ -1,6 +1,7 @@
defmodule PlausibleWeb.Api.StatsController.FunnelsTest do
use PlausibleWeb.ConnCase, async: true
use Plausible
use Plausible.Teams.Test
@moduletag :ee_only
on_ee do
@ -15,7 +16,7 @@ defmodule PlausibleWeb.Api.StatsController.FunnelsTest do
]
describe "GET /api/stats/funnel - default" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "computes funnel for a day", %{conn: conn, site: site} do
{:ok, funnel} = setup_funnel(site, @build_funnel_with)
@ -229,7 +230,7 @@ defmodule PlausibleWeb.Api.StatsController.FunnelsTest do
site: site
} do
{:ok, funnel} = setup_funnel(site, @build_funnel_with)
insert(:growth_subscription, user: user)
subscribe_to_growth_plan(user)
resp =
conn
@ -244,7 +245,7 @@ defmodule PlausibleWeb.Api.StatsController.FunnelsTest do
end
describe "GET /api/stats/funnel - disallowed filters" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "event:page", %{conn: conn, site: site} do
{:ok, funnel} = setup_funnel(site, @build_funnel_with)

View File

@ -12,7 +12,7 @@ defmodule PlausibleWeb.Api.StatsController.ImportedTest do
for import_type <- [:new_and_legacy, :new] do
describe "Parse and import third party data fetched from Google Analytics as #{import_type} import" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
setup %{user: user, site: site} do
import_params =

View File

@ -4,7 +4,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
@user_id Enum.random(1000..9999)
describe "GET /api/stats/main-graph - plot" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "displays pageviews for the last 30 minutes in realtime graph", %{conn: conn, site: site} do
populate_stats(site, [
@ -389,7 +389,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
end
describe "GET /api/stats/main-graph - pageviews plot" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "displays pageviews for a month", %{conn: conn, site: site} do
populate_stats(site, [
@ -455,7 +455,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
end
describe "GET /api/stats/main-graph - visitors plot" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "displays visitors per hour with short visits", %{
conn: conn,
@ -585,7 +585,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
end
describe "GET /api/stats/main-graph - conversion_rate plot" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "returns 400 when conversion rate is queried without a goal filter", %{
conn: conn,
@ -630,7 +630,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
end
describe "GET /api/stats/main-graph - events (total conversions) plot" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "returns 400 when the `events` metric is queried without a goal filter", %{
conn: conn,
@ -737,7 +737,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
end
describe "GET /api/stats/main-graph - bounce_rate plot" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "displays bounce_rate for a month", %{conn: conn, site: site} do
populate_stats(site, [
@ -801,7 +801,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
end
describe "GET /api/stats/main-graph - visit_duration plot" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "displays visit_duration for a month", %{conn: conn, site: site} do
populate_stats(site, [
@ -868,7 +868,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
end
describe "GET /api/stats/main-graph - varying intervals" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "displays visitors for 6mo on a day scale", %{conn: conn, site: site} do
populate_stats(site, [
@ -1118,7 +1118,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
end
describe "GET /api/stats/main-graph - comparisons" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns past month stats when period=30d and comparison=previous_period", %{
conn: conn,
@ -1292,7 +1292,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
describe "GET /api/stats/main-graph - total_revenue plot" do
@describetag :ee_only
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "plots total_revenue for a month", %{conn: conn, site: site} do
insert(:goal, site: site, event_name: "Payment", currency: "USD")
@ -1427,7 +1427,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
describe "GET /api/stats/main-graph - average_revenue plot" do
@describetag :ee_only
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "plots total_revenue for a month", %{conn: conn, site: site} do
insert(:goal, site: site, event_name: "Payment", currency: "USD")
@ -1567,7 +1567,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do
end
describe "present_index" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "exists for a date range that includes the current day", %{conn: conn, site: site} do
populate_stats(site, [

View File

@ -2,7 +2,7 @@ defmodule PlausibleWeb.Api.StatsController.OperatingSystemsTest do
use PlausibleWeb.ConnCase
describe "GET /api/stats/:domain/operating-systems" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns operating systems by unique visitors", %{conn: conn, site: site} do
populate_stats(site, [
@ -215,7 +215,7 @@ defmodule PlausibleWeb.Api.StatsController.OperatingSystemsTest do
end
describe "GET /api/stats/:domain/operating-system-versions" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns top OS versions by unique visitors", %{conn: conn, site: site} do
populate_stats(site, [

View File

@ -4,7 +4,7 @@ defmodule PlausibleWeb.Api.StatsController.PagesTest do
@user_id Enum.random(1000..9999)
describe "GET /api/stats/:domain/pages" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns top pages by visitors", %{conn: conn, site: site} do
populate_stats(site, [
@ -1454,7 +1454,7 @@ defmodule PlausibleWeb.Api.StatsController.PagesTest do
end
describe "GET /api/stats/:domain/entry-pages" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns top entry pages by visitors", %{conn: conn, site: site} do
populate_stats(site, [
@ -1861,7 +1861,7 @@ defmodule PlausibleWeb.Api.StatsController.PagesTest do
end
describe "GET /api/stats/:domain/exit-pages" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns top exit pages by visitors", %{conn: conn, site: site} do
populate_stats(site, [

View File

@ -32,7 +32,7 @@ defmodule PlausibleWeb.Api.StatsController.RegionsTest do
])
end
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import, :seed]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import, :seed]
test "returns top cities by new visitors", %{conn: conn, site: site} do
conn = get(conn, "/api/stats/#{site.domain}/regions?period=day")

View File

@ -2,7 +2,7 @@ defmodule PlausibleWeb.Api.StatsController.ScreenSizesTest do
use PlausibleWeb.ConnCase
describe "GET /api/stats/:domain/screen-sizes" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns screen sizes by new visitors", %{conn: conn, site: site} do
populate_stats(site, [

View File

@ -4,7 +4,7 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
@user_id Enum.random(1000..9999)
describe "GET /api/stats/:domain/sources" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns top sources by unique user ids", %{conn: conn, site: site} do
populate_stats(site, [
@ -676,7 +676,7 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
end
describe "UTM parameters with hostname filter" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
for {resource, attr} <- [
utm_campaigns: :utm_campaign,
@ -722,7 +722,7 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
end
describe "GET /api/stats/:domain/channels" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "returns top channels by unique user ids", %{conn: conn, site: site} do
populate_stats(site, [
@ -772,7 +772,7 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
end
describe "GET /api/stats/:domain/utm_mediums" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns top utm_mediums by unique user ids", %{conn: conn, site: site} do
populate_stats(site, [
@ -924,7 +924,7 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
end
describe "GET /api/stats/:domain/utm_campaigns" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns top utm_campaigns by unique user ids", %{conn: conn, site: site} do
populate_stats(site, [
@ -1084,7 +1084,7 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
end
describe "GET /api/stats/:domain/utm_sources" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns top utm_sources by unique user ids", %{conn: conn, site: site} do
populate_stats(site, [
@ -1132,7 +1132,7 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
end
describe "GET /api/stats/:domain/utm_terms" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns top utm_terms by unique user ids", %{conn: conn, site: site} do
populate_stats(site, [
@ -1292,7 +1292,7 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
end
describe "GET /api/stats/:domain/utm_contents" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns top utm_contents by unique user ids", %{conn: conn, site: site} do
populate_stats(site, [
@ -1452,7 +1452,7 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
end
describe "GET /api/stats/:domain/sources - with goal filter" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "returns top referrers for a custom goal including conversion_rate", %{
conn: conn,
@ -1718,7 +1718,7 @@ defmodule PlausibleWeb.Api.StatsController.SourcesTest do
end
describe "GET /api/stats/:domain/referrer-drilldown" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "returns top referrers for a particular source", %{conn: conn, site: site} do
populate_stats(site, [

View File

@ -112,7 +112,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
end
test "returns suggestions for regions", %{conn: conn, user: user} do
{:ok, [site: site]} = create_new_site(%{user: user})
{:ok, [site: site]} = create_site(%{user: user})
populate_stats(site, [
build(:pageview, country_code: "EE", subdivision1_code: "EE-37"),
@ -129,7 +129,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
end
test "returns suggestions for cities", %{conn: conn, user: user} do
{:ok, [site: site]} = create_new_site(%{user: user})
{:ok, [site: site]} = create_site(%{user: user})
populate_stats(site, [
build(:pageview,
@ -256,7 +256,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
end
test "returns suggestions for hostnames", %{conn: conn1, user: user} do
{:ok, [site: site]} = create_new_site(%{user: user})
{:ok, [site: site]} = create_site(%{user: user})
populate_stats(site, [
build(:pageview,
@ -299,7 +299,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
end
test "returns suggestions for hostnames limited by shields", %{conn: conn1, user: user} do
{:ok, [site: site]} = create_new_site(%{user: user})
{:ok, [site: site]} = create_site(%{user: user})
Plausible.Shields.add_hostname_rule(site, %{"hostname" => "*.example.com"})
Plausible.Shields.add_hostname_rule(site, %{"hostname" => "erin.rogue.com"})
@ -378,7 +378,7 @@ defmodule PlausibleWeb.Api.StatsController.SuggestionsTest do
end
describe "suggestions for props" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "returns suggestions for prop key ordered by count", %{conn: conn, site: site} do
populate_stats(site, [

View File

@ -1,10 +1,11 @@
defmodule PlausibleWeb.Api.StatsController.TopStatsTest do
use PlausibleWeb.ConnCase
use Plausible.Teams.Test
@user_id Enum.random(1000..9999)
describe "GET /api/stats/top-stats - default" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "returns graph_metric key for graphable top stats", %{conn: conn, site: site} do
[visitors, visits, pageviews, views_per_visit, bounce_rate, visit_duration] =
@ -477,7 +478,7 @@ defmodule PlausibleWeb.Api.StatsController.TopStatsTest do
end
describe "GET /api/stats/top-stats - with imported data" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "returns divisible metrics as 0 when no stats exist", %{
site: site,
@ -643,7 +644,7 @@ defmodule PlausibleWeb.Api.StatsController.TopStatsTest do
end
describe "GET /api/stats/top-stats - with_imported_switch info" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
setup context do
insert(:site_import,
@ -777,7 +778,7 @@ defmodule PlausibleWeb.Api.StatsController.TopStatsTest do
end
describe "GET /api/stats/top-stats - realtime" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "shows current visitors (last 5 minutes)", %{conn: conn, site: site} do
populate_stats(site, [
@ -883,7 +884,7 @@ defmodule PlausibleWeb.Api.StatsController.TopStatsTest do
end
describe "GET /api/stats/top-stats - filters" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "returns graph_metric key for top stats with a page filter", %{
conn: conn,
@ -1257,7 +1258,7 @@ defmodule PlausibleWeb.Api.StatsController.TopStatsTest do
end
describe "GET /api/stats/top-stats - filtered for goal" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "returns total unique visitors", %{conn: conn, site: site} do
populate_stats(site, [
@ -1599,7 +1600,7 @@ defmodule PlausibleWeb.Api.StatsController.TopStatsTest do
test "does not return average and total when site owner is on a growth plan",
%{conn: conn, site: site, user: user} do
insert(:growth_subscription, user: user)
subscribe_to_growth_plan(user)
insert(:goal, site: site, event_name: "Payment", currency: "USD")
populate_stats(site, [
@ -1621,7 +1622,7 @@ defmodule PlausibleWeb.Api.StatsController.TopStatsTest do
end
describe "GET /api/stats/top-stats - with comparisons" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "does not return comparisons by default", %{site: site, conn: conn} do
populate_stats(site, [

View File

@ -542,7 +542,7 @@ defmodule PlausibleWeb.AuthControllerTest do
end
describe "DELETE /me" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
use Plausible.Repo
test "deletes the user", %{conn: conn, user: user, site: site} do

View File

@ -145,6 +145,8 @@ defmodule PlausibleWeb.BillingControllerTest do
test "data-product attribute on the checkout link is the paddle_plan_id of the enterprise plan",
%{conn: conn, user: user} do
{:ok, team} = Plausible.Teams.get_by_owner(user)
doc =
conn
|> get(Routes.billing_path(conn, :upgrade_to_enterprise_plan))
@ -153,7 +155,7 @@ defmodule PlausibleWeb.BillingControllerTest do
assert %{
"disableLogout" => true,
"email" => user.email,
"passthrough" => user.id,
"passthrough" => "user:#{user.id};team:#{team.id}",
"product" => @configured_enterprise_plan_paddle_plan_id,
"success" => Routes.billing_path(PlausibleWeb.Endpoint, :upgrade_success),
"theme" => "none"
@ -316,6 +318,8 @@ defmodule PlausibleWeb.BillingControllerTest do
test "renders paddle button with the correct checkout params",
%{conn: conn, user: user} do
{:ok, team} = Plausible.Teams.get_by_owner(user)
doc =
conn
|> get(Routes.billing_path(conn, :upgrade_to_enterprise_plan))
@ -324,7 +328,7 @@ defmodule PlausibleWeb.BillingControllerTest do
assert %{
"disableLogout" => true,
"email" => user.email,
"passthrough" => user.id,
"passthrough" => "user:#{user.id};team:#{team.id}",
"product" => @configured_enterprise_plan_paddle_plan_id,
"success" => Routes.billing_path(PlausibleWeb.Endpoint, :upgrade_success),
"theme" => "none"

View File

@ -17,7 +17,7 @@ defmodule PlausibleWeb.GoogleAnalyticsControllerTest do
setup :verify_on_exit!
describe "GET /:domain/import/google-analytics/property" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "lists Google Analytics properties", %{conn: conn, site: site} do
expect(
@ -207,7 +207,7 @@ defmodule PlausibleWeb.GoogleAnalyticsControllerTest do
end
describe "POST /:domain/import/google-analytics/property" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "redirects to confirmation", %{conn: conn, site: site} do
expect(
@ -505,7 +505,7 @@ defmodule PlausibleWeb.GoogleAnalyticsControllerTest do
end
describe "GET /:domain/import/google-analytics/confirm" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "renders confirmation form for Google Analytics 4 import", %{conn: conn, site: site} do
expect(
@ -730,7 +730,7 @@ defmodule PlausibleWeb.GoogleAnalyticsControllerTest do
end
describe "POST /:domain/settings/google-import" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "creates Google Analytics 4 site import instance", %{conn: conn, site: site} do
conn =

View File

@ -1532,7 +1532,7 @@ defmodule PlausibleWeb.SiteControllerTest do
end
describe "DELETE /:domain/settings/:forget_import/:import_id" do
setup [:create_user, :log_in, :create_new_site, :create_legacy_site_import]
setup [:create_user, :log_in, :create_site, :create_legacy_site_import]
test "removes site import, associated data and cancels oban job for a particular import", %{
conn: conn,
@ -1610,7 +1610,7 @@ defmodule PlausibleWeb.SiteControllerTest do
end
describe "DELETE /:domain/settings/forget_imported" do
setup [:create_user, :log_in, :create_new_site]
setup [:create_user, :log_in, :create_site]
test "removes actual imported data from Clickhouse", %{conn: conn, user: user, site: site} do
Plausible.Imported.NoopImporter.new_import(

View File

@ -1,13 +1,14 @@
defmodule PlausibleWeb.StatsControllerTest do
use PlausibleWeb.ConnCase, async: false
use Plausible.Repo
use Plausible.Teams.Test
import Plausible.Test.Support.HTML
@react_container "div#stats-react-container"
describe "GET /:domain - anonymous user" do
test "public site - shows site stats", %{conn: conn} do
site = insert(:site, public: true)
site = new_site(public: true)
populate_stats(site, [build(:pageview)])
conn = get(conn, "/#{site.domain}")
@ -182,7 +183,7 @@ defmodule PlausibleWeb.StatsControllerTest do
end
describe "GET /:domain/export" do
setup [:create_user, :create_new_site, :log_in]
setup [:create_user, :create_site, :log_in]
test "exports all the necessary CSV files", %{conn: conn, site: site} do
conn = get(conn, "/" <> site.domain <> "/export")
@ -223,7 +224,7 @@ defmodule PlausibleWeb.StatsControllerTest do
{:ok, site} = Plausible.Props.allow(site, ["author"])
site = Repo.preload(site, :owner)
insert(:growth_subscription, user: site.owner)
subscribe_to_growth_plan(site.owner)
populate_stats(site, [
build(:pageview, "meta.key": ["author"], "meta.value": ["a"]),
@ -252,7 +253,7 @@ defmodule PlausibleWeb.StatsControllerTest do
{:ok, site} = Plausible.Props.allow(site, ["author"])
site = Repo.preload(site, :owner)
insert(:growth_subscription, user: site.owner)
subscribe_to_growth_plan(site.owner)
populate_stats(site, [
build(:pageview, "meta.key": ["author"], "meta.value": ["a"])
@ -612,7 +613,7 @@ defmodule PlausibleWeb.StatsControllerTest do
end
describe "GET /:domain/export - for past 6 months" do
setup [:create_user, :create_new_site, :log_in]
setup [:create_user, :create_site, :log_in]
test "exports 6 months of data in zipped csvs", %{conn: conn, site: site} do
populate_exported_stats(site)
@ -622,7 +623,7 @@ defmodule PlausibleWeb.StatsControllerTest do
end
describe "GET /:domain/export - with path filter" do
setup [:create_user, :create_new_site, :log_in]
setup [:create_user, :create_site, :log_in]
test "exports filtered data in zipped csvs", %{conn: conn, site: site} do
populate_exported_stats(site)
@ -634,7 +635,7 @@ defmodule PlausibleWeb.StatsControllerTest do
end
describe "GET /:domain/export - with a custom prop filter" do
setup [:create_user, :create_new_site, :log_in]
setup [:create_user, :create_site, :log_in]
test "custom-props.csv only returns the prop and its value in filter", %{
conn: conn,
@ -763,7 +764,7 @@ defmodule PlausibleWeb.StatsControllerTest do
end
describe "GET /:domain/export - with goal filter" do
setup [:create_user, :create_new_site, :log_in]
setup [:create_user, :create_site, :log_in]
test "exports goal-filtered data in zipped csvs", %{conn: conn, site: site} do
populate_exported_stats(site)

View File

@ -1,5 +1,6 @@
defmodule PlausibleWeb.Live.ChoosePlanTest do
use PlausibleWeb.ConnCase, async: true
use Plausible.Teams.Test
@moduletag :ee_only
import Phoenix.LiveViewTest
@ -193,6 +194,7 @@ defmodule PlausibleWeb.Live.ChoosePlanTest do
user: user
} do
{:ok, lv, _doc} = get_liveview(conn)
{:ok, team} = Plausible.Teams.get_by_owner(user)
set_slider(lv, "200k")
doc = element(lv, @yearly_interval_button) |> render_click()
@ -200,7 +202,7 @@ defmodule PlausibleWeb.Live.ChoosePlanTest do
assert %{
"disableLogout" => true,
"email" => user.email,
"passthrough" => user.id,
"passthrough" => "user:#{user.id};team:#{team.id}",
"product" => @v4_growth_200k_yearly_plan_id,
"success" => Routes.billing_path(PlausibleWeb.Endpoint, :upgrade_success),
"theme" => "none"
@ -500,8 +502,8 @@ defmodule PlausibleWeb.Live.ChoosePlanTest do
conn: conn,
user: user
} do
another_user = insert(:user)
pending_site = insert(:site, members: [another_user])
another_user = new_user()
pending_site = new_site(owner: another_user)
Plausible.Props.allow(pending_site, ["author"])
@ -1065,6 +1067,7 @@ defmodule PlausibleWeb.Live.ChoosePlanTest do
test "renders Paddle upgrade buttons", %{conn: conn, user: user} do
{:ok, lv, _doc} = get_liveview(conn)
{:ok, team} = Plausible.Teams.get_by_owner(user)
set_slider(lv, "200k")
doc = element(lv, @yearly_interval_button) |> render_click()
@ -1072,7 +1075,7 @@ defmodule PlausibleWeb.Live.ChoosePlanTest do
assert %{
"disableLogout" => true,
"email" => user.email,
"passthrough" => user.id,
"passthrough" => "user:#{user.id};team:#{team.id}",
"product" => @v4_growth_200k_yearly_plan_id,
"success" => Routes.billing_path(PlausibleWeb.Endpoint, :upgrade_success),
"theme" => "none"

View File

@ -15,6 +15,7 @@ defmodule PlausibleWeb.Live.FunnelSettingsTest do
user
|> Plausible.Auth.User.end_trial()
|> Plausible.Repo.update!()
|> Plausible.Teams.sync_team()
conn = get(conn, "/#{site.domain}/settings/funnels")
resp = conn |> html_response(200) |> text()

View File

@ -33,6 +33,7 @@ defmodule PlausibleWeb.Live.GoalSettingsTest do
user
|> Plausible.Auth.User.end_trial()
|> Plausible.Repo.update!()
|> Plausible.Teams.sync_team()
conn = get(conn, "/#{site.domain}/settings/goals")

View File

@ -11,6 +11,7 @@ defmodule PlausibleWeb.Live.PropsSettingsTest do
user
|> Plausible.Auth.User.end_trial()
|> Plausible.Repo.update!()
|> Plausible.Teams.sync_team()
conn = get(conn, "/#{site.domain}/settings/properties")
resp = conn |> html_response(200) |> text()

View File

@ -1,5 +1,6 @@
defmodule PlausibleWeb.Plugins.API.Controllers.CapabilitiesTest do
use PlausibleWeb.PluginsAPICase, async: true
use Plausible.Teams.Test
alias PlausibleWeb.Plugins.API.Schemas
describe "examples" do
@ -88,7 +89,7 @@ defmodule PlausibleWeb.Plugins.API.Controllers.CapabilitiesTest do
@tag :ee_only
test "growth", %{conn: conn, site: site, token: token} do
site = Plausible.Repo.preload(site, :owner)
insert(:growth_subscription, user: site.owner)
subscribe_to_growth_plan(site.owner)
resp =
conn

View File

@ -1,5 +1,6 @@
defmodule PlausibleWeb.Plugins.API.Controllers.CustomPropsTest do
use PlausibleWeb.PluginsAPICase, async: true
use Plausible.Teams.Test
alias PlausibleWeb.Plugins.API.Schemas
describe "examples" do
@ -42,7 +43,7 @@ defmodule PlausibleWeb.Plugins.API.Controllers.CustomPropsTest do
conn: conn
} do
site = Plausible.Repo.preload(site, :owner)
insert(:growth_subscription, user: site.owner)
subscribe_to_growth_plan(site.owner)
url = Routes.plugins_api_custom_props_url(PlausibleWeb.Endpoint, :enable)
@ -66,7 +67,7 @@ defmodule PlausibleWeb.Plugins.API.Controllers.CustomPropsTest do
conn: conn
} do
site = Plausible.Repo.preload(site, :owner)
insert(:growth_subscription, user: site.owner)
subscribe_to_growth_plan(site.owner)
url = Routes.plugins_api_custom_props_url(PlausibleWeb.Endpoint, :enable)

View File

@ -1,6 +1,7 @@
defmodule PlausibleWeb.Plugins.API.Controllers.FunnelsTest do
use PlausibleWeb.PluginsAPICase, async: true
use Plausible
use Plausible.Teams.Test
@moduletag :ee_only
@ -249,7 +250,7 @@ defmodule PlausibleWeb.Plugins.API.Controllers.FunnelsTest do
test "fails for insufficient plan", %{conn: conn, token: token, site: site} do
site = Plausible.Repo.preload(site, :owner)
insert(:growth_subscription, user: site.owner)
subscribe_to_growth_plan(site.owner)
url = Routes.plugins_api_funnels_url(PlausibleWeb.Endpoint, :create)

View File

@ -1,5 +1,6 @@
defmodule PlausibleWeb.Plugins.API.Controllers.GoalsTest do
use PlausibleWeb.PluginsAPICase, async: true
use Plausible.Teams.Test
alias PlausibleWeb.Plugins.API.Schemas
describe "examples" do
@ -53,7 +54,7 @@ defmodule PlausibleWeb.Plugins.API.Controllers.GoalsTest do
conn: conn
} do
site = Plausible.Repo.preload(site, :owner)
insert(:growth_subscription, user: site.owner)
subscribe_to_growth_plan(site.owner)
url = Routes.plugins_api_goals_url(PlausibleWeb.Endpoint, :create)
@ -79,7 +80,7 @@ defmodule PlausibleWeb.Plugins.API.Controllers.GoalsTest do
conn: conn
} do
site = Plausible.Repo.preload(site, :owner)
insert(:growth_subscription, user: site.owner)
subscribe_to_growth_plan(site.owner)
url = Routes.plugins_api_goals_url(PlausibleWeb.Endpoint, :create)

View File

@ -1,5 +1,6 @@
defmodule PlausibleWeb.Plugs.AuthorizePublicAPITest do
use PlausibleWeb.ConnCase, async: false
use Plausible.Teams.Test
alias PlausibleWeb.Plugs.AuthorizePublicAPI
@ -115,8 +116,8 @@ defmodule PlausibleWeb.Plugs.AuthorizePublicAPITest do
test "halts with error when API key owner does not have access to the requested site", %{
conn: conn
} do
user = insert(:user)
site = insert(:site)
user = new_user()
site = new_site()
api_key = insert(:api_key, user: user)
conn =
@ -183,8 +184,8 @@ defmodule PlausibleWeb.Plugs.AuthorizePublicAPITest do
test "passes and sets current user and site when valid API key and site ID provided", %{
conn: conn
} do
user = insert(:user)
site = insert(:site, members: [user])
user = new_user()
site = new_site(owner: user)
api_key = insert(:api_key, user: user)
conn =

View File

@ -34,7 +34,6 @@ defmodule PlausibleWeb.PluginsAPICase do
end
setup %{test: test} = tags do
import Plausible.Factory
:ok = Ecto.Adapters.SQL.Sandbox.checkout(Plausible.Repo)
unless tags[:async] do
@ -43,7 +42,7 @@ defmodule PlausibleWeb.PluginsAPICase do
conn = Phoenix.ConnTest.build_conn()
site = insert(:site)
site = Plausible.Teams.Test.new_site()
{:ok, _token, raw_token} = Plausible.Plugins.API.Tokens.create(site, Atom.to_string(test))
{:ok, conn: conn, site: site, token: raw_token}

View File

@ -142,6 +142,13 @@ defmodule Plausible.Teams.Test do
user
end
def subscribe_to_business_plan(user) do
{:ok, team} = Teams.get_or_create(user)
insert(:business_subscription, user: user, team: team)
user
end
def subscribe_to_plan(user, paddle_plan_id) do
{:ok, team} = Teams.get_or_create(user)
@ -149,7 +156,7 @@ defmodule Plausible.Teams.Test do
user
end
def subscribe_to_enterprise_plan(user, attrs) do
def subscribe_to_enterprise_plan(user, attrs \\ []) do
{:ok, team} = Teams.get_or_create(user)
{subscription?, attrs} = Keyword.pop(attrs, :subscription?, true)

View File

@ -35,16 +35,11 @@ defmodule Plausible.TestUtils do
end
def create_user(_) do
{:ok, user: Factory.insert(:user)}
{:ok, user: Plausible.Teams.Test.new_user()}
end
def create_site(%{user: user}) do
site =
Factory.insert(:site,
members: [user]
)
{:ok, site: site}
{:ok, site: Plausible.Teams.Test.new_site(owner: user)}
end
def create_legacy_site_import(%{site: site}) do
@ -64,11 +59,6 @@ defmodule Plausible.TestUtils do
{:ok, site_import: site_import}
end
def create_new_site(%{user: user}) do
site = Factory.insert(:site, members: [user])
{:ok, site: site}
end
def create_api_key(%{user: user}) do
api_key = Factory.insert(:api_key, user: user)