mirror of
https://github.com/plausible/analytics.git
synced 2025-01-08 19:17:06 +03:00
Switch on team schema in site settings controller actions and LVs (#4834)
* Populate `current_team` to site's team and make site and subscription preloads consistent * Accept only full `User` struct in `Users.get_for_user(!)` * Make all uses of `Sites.get_for_user(!)` switch on team schema * Remove redundant preloads for funnel/props settings * Use adapter transitions in subscription settings * Use team's schema subscription when listing invoices * Fix typespec * Turn owned site IDs into a specific query * Add clauses for when FF is on but no team has been created * Fix formatting --------- Co-authored-by: Adam Rutkowski <hq@mtod.org>
This commit is contained in:
parent
9af498833e
commit
4ff2a66548
@ -206,7 +206,7 @@ defmodule PlausibleWeb.Api.ExternalSitesController do
|
||||
end
|
||||
|
||||
defp get_site(user, site_id, roles) do
|
||||
case Sites.get_for_user(user.id, site_id, roles) do
|
||||
case Plausible.Teams.Adapter.Read.Sites.get_for_user(user, site_id, roles) do
|
||||
nil -> {:error, :site_not_found}
|
||||
site -> {:ok, site}
|
||||
end
|
||||
|
@ -6,7 +6,7 @@ defmodule PlausibleWeb.Live.FunnelSettings do
|
||||
|
||||
use Plausible.Funnel
|
||||
|
||||
alias Plausible.{Sites, Goals, Funnels}
|
||||
alias Plausible.{Goals, Funnels}
|
||||
|
||||
def mount(
|
||||
_params,
|
||||
@ -16,7 +16,11 @@ defmodule PlausibleWeb.Live.FunnelSettings do
|
||||
socket =
|
||||
socket
|
||||
|> assign_new(:site, fn %{current_user: current_user} ->
|
||||
Sites.get_for_user!(current_user, domain, [:owner, :admin, :super_admin])
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(current_user, domain, [
|
||||
:owner,
|
||||
:admin,
|
||||
:super_admin
|
||||
])
|
||||
end)
|
||||
|> assign_new(:all_funnels, fn %{site: %{id: ^site_id} = site} ->
|
||||
Funnels.list(site)
|
||||
@ -102,7 +106,11 @@ defmodule PlausibleWeb.Live.FunnelSettings do
|
||||
|
||||
def handle_event("delete-funnel", %{"funnel-id" => id}, socket) do
|
||||
site =
|
||||
Sites.get_for_user!(socket.assigns.current_user, socket.assigns.domain, [:owner, :admin])
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(
|
||||
socket.assigns.current_user,
|
||||
socket.assigns.domain,
|
||||
[:owner, :admin]
|
||||
)
|
||||
|
||||
id = String.to_integer(id)
|
||||
:ok = Funnels.delete(site, id)
|
||||
|
@ -9,11 +9,15 @@ defmodule PlausibleWeb.Live.FunnelSettings.Form do
|
||||
use Plausible.Funnel
|
||||
|
||||
import PlausibleWeb.Live.Components.Form
|
||||
alias Plausible.{Sites, Goals, Funnels}
|
||||
alias Plausible.{Goals, Funnels}
|
||||
|
||||
def mount(_params, %{"domain" => domain} = session, socket) do
|
||||
site =
|
||||
Sites.get_for_user!(socket.assigns.current_user, domain, [:owner, :admin, :super_admin])
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(socket.assigns.current_user, domain, [
|
||||
:owner,
|
||||
:admin,
|
||||
:super_admin
|
||||
])
|
||||
|
||||
# We'll have the options trimmed to only the data we care about, to keep
|
||||
# it minimal at the socket assigns, yet, we want to retain specific %Goal{}
|
||||
|
@ -83,7 +83,7 @@ defmodule Plausible.Billing.PaddleApi do
|
||||
end
|
||||
end
|
||||
|
||||
@spec get_invoices(Plausible.Billing.Subscription.t()) ::
|
||||
@spec get_invoices(Plausible.Billing.Subscription.t() | nil) ::
|
||||
{:ok, list()}
|
||||
| {:error, :request_failed}
|
||||
| {:error, :no_invoices}
|
||||
|
@ -58,7 +58,7 @@ defmodule Plausible.Billing.Quota.Limits do
|
||||
@monthly_pageview_limit_for_free_10k 10_000
|
||||
@monthly_pageview_limit_for_trials :unlimited
|
||||
|
||||
@spec monthly_pageview_limit(User.t() | Subscription.t()) ::
|
||||
@spec monthly_pageview_limit(User.t() | Subscription.t() | nil) ::
|
||||
non_neg_integer() | :unlimited
|
||||
def monthly_pageview_limit(%User{} = user) do
|
||||
user = Users.with_subscription(user)
|
||||
|
@ -55,7 +55,7 @@ defmodule Plausible.Sites do
|
||||
|
||||
@spec set_option(Auth.User.t(), Site.t(), atom(), any()) :: Site.UserPreference.t()
|
||||
def set_option(user, site, option, value) when option in Site.UserPreference.options() do
|
||||
get_for_user!(user.id, site.domain)
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(user, site.domain)
|
||||
|
||||
user
|
||||
|> Site.UserPreference.changeset(site, %{option => value})
|
||||
@ -91,7 +91,7 @@ defmodule Plausible.Sites do
|
||||
end)
|
||||
|> Ecto.Multi.run(:clear_changed_from, fn
|
||||
_repo, %{site_changeset: %{changes: %{domain: domain}}} ->
|
||||
case get_for_user(user.id, domain, [:owner]) do
|
||||
case Plausible.Teams.Adapter.Read.Sites.get_for_user(user, domain, [:owner]) do
|
||||
%Site{domain_changed_from: ^domain} = site ->
|
||||
site
|
||||
|> Ecto.Changeset.change()
|
||||
@ -204,46 +204,6 @@ defmodule Plausible.Sites do
|
||||
base <> domain <> "?auth=" <> link.slug
|
||||
end
|
||||
|
||||
@spec get_for_user!(Auth.User.t() | pos_integer(), String.t(), [
|
||||
:super_admin | :owner | :admin | :viewer
|
||||
]) ::
|
||||
Site.t()
|
||||
def get_for_user!(user, domain, roles \\ [:owner, :admin, :viewer])
|
||||
|
||||
def get_for_user!(%Auth.User{id: user_id}, domain, roles) do
|
||||
get_for_user!(user_id, domain, roles)
|
||||
end
|
||||
|
||||
def get_for_user!(user_id, domain, roles) do
|
||||
if :super_admin in roles and Auth.is_super_admin?(user_id) do
|
||||
get_by_domain!(domain)
|
||||
else
|
||||
user_id
|
||||
|> get_for_user_q(domain, List.delete(roles, :super_admin))
|
||||
|> Repo.one!()
|
||||
end
|
||||
end
|
||||
|
||||
@spec get_for_user(Auth.User.t() | pos_integer(), String.t(), [
|
||||
:super_admin | :owner | :admin | :viewer
|
||||
]) ::
|
||||
Site.t() | nil
|
||||
def get_for_user(user, domain, roles \\ [:owner, :admin, :viewer])
|
||||
|
||||
def get_for_user(%Auth.User{id: user_id}, domain, roles) do
|
||||
get_for_user(user_id, domain, roles)
|
||||
end
|
||||
|
||||
def get_for_user(user_id, domain, roles) do
|
||||
if :super_admin in roles and Auth.is_super_admin?(user_id) do
|
||||
get_by_domain(domain)
|
||||
else
|
||||
user_id
|
||||
|> get_for_user_q(domain, List.delete(roles, :super_admin))
|
||||
|> Repo.one()
|
||||
end
|
||||
end
|
||||
|
||||
def update_installation_meta!(site, meta) do
|
||||
site
|
||||
|> Ecto.Changeset.change()
|
||||
@ -251,17 +211,6 @@ defmodule Plausible.Sites do
|
||||
|> Repo.update!()
|
||||
end
|
||||
|
||||
defp get_for_user_q(user_id, domain, roles) do
|
||||
from(s in Site,
|
||||
join: sm in Site.Membership,
|
||||
on: sm.site_id == s.id,
|
||||
where: sm.user_id == ^user_id,
|
||||
where: sm.role in ^roles,
|
||||
where: s.domain == ^domain or s.domain_changed_from == ^domain,
|
||||
select: s
|
||||
)
|
||||
end
|
||||
|
||||
def has_goals?(site) do
|
||||
Repo.exists?(
|
||||
from(g in Plausible.Goal,
|
||||
|
@ -9,8 +9,9 @@ defmodule Plausible.Teams do
|
||||
alias Plausible.Repo
|
||||
use Plausible
|
||||
|
||||
@spec on_trial?(Teams.Team.t()) :: boolean()
|
||||
@spec on_trial?(Teams.Team.t() | nil) :: boolean()
|
||||
on_ee do
|
||||
def on_trial?(nil), do: false
|
||||
def on_trial?(%Teams.Team{trial_expiry_date: nil}), do: false
|
||||
|
||||
def on_trial?(team) do
|
||||
@ -38,6 +39,19 @@ defmodule Plausible.Teams do
|
||||
Repo.preload(team, :sites).sites
|
||||
end
|
||||
|
||||
def owned_sites_ids(nil) do
|
||||
[]
|
||||
end
|
||||
|
||||
def owned_sites_ids(team) do
|
||||
Repo.all(
|
||||
from s in Plausible.Site,
|
||||
where: s.team_id == ^team.id,
|
||||
select: s.id,
|
||||
order_by: [desc: s.id]
|
||||
)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Create (when necessary) and load team relation for provided site.
|
||||
|
||||
@ -110,6 +124,19 @@ defmodule Plausible.Teams do
|
||||
end
|
||||
end
|
||||
|
||||
def last_subscription_join_query() do
|
||||
from(subscription in last_subscription_query(),
|
||||
where: subscription.team_id == parent_as(:team).id
|
||||
)
|
||||
end
|
||||
|
||||
def last_subscription_query() do
|
||||
from(subscription in Plausible.Billing.Subscription,
|
||||
order_by: [desc: subscription.inserted_at, desc: subscription.id],
|
||||
limit: 1
|
||||
)
|
||||
end
|
||||
|
||||
defp create_my_team(user) do
|
||||
team =
|
||||
"My Team"
|
||||
@ -135,11 +162,4 @@ defmodule Plausible.Teams do
|
||||
{:error, :exists_already}
|
||||
end
|
||||
end
|
||||
|
||||
defp last_subscription_query() do
|
||||
from(subscription in Plausible.Billing.Subscription,
|
||||
order_by: [desc: subscription.inserted_at, desc: subscription.id],
|
||||
limit: 1
|
||||
)
|
||||
end
|
||||
end
|
||||
|
@ -11,6 +11,13 @@ defmodule Plausible.Teams.Adapter do
|
||||
end
|
||||
end
|
||||
|
||||
def user_or_team(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)
|
||||
@ -22,8 +29,11 @@ defmodule Plausible.Teams.Adapter do
|
||||
{:error, _} -> nil
|
||||
end
|
||||
|
||||
team = Plausible.Teams.with_subscription(team)
|
||||
|
||||
team_fn.(team)
|
||||
else
|
||||
user = Plausible.Users.with_subscription(user)
|
||||
user_fn.(user)
|
||||
end
|
||||
end
|
||||
|
@ -4,6 +4,42 @@ defmodule Plausible.Teams.Adapter.Read.Billing do
|
||||
"""
|
||||
use Plausible.Teams.Adapter
|
||||
|
||||
def get_subscription(user) do
|
||||
case user_or_team(user) do
|
||||
%{subscription: subscription} -> subscription
|
||||
_ -> nil
|
||||
end
|
||||
end
|
||||
|
||||
def team_member_limit(user) do
|
||||
switch(user,
|
||||
team_fn: &Teams.Billing.team_member_limit/1,
|
||||
user_fn: &Plausible.Billing.Quota.Limits.team_member_limit/1
|
||||
)
|
||||
end
|
||||
|
||||
def team_member_usage(user, opts \\ []) do
|
||||
switch(user,
|
||||
team_fn: &Teams.Billing.team_member_usage(&1, opts),
|
||||
user_fn: &Plausible.Billing.Quota.Usage.team_member_usage(&1, opts)
|
||||
)
|
||||
end
|
||||
|
||||
def monthly_pageview_limit(user) do
|
||||
switch(user,
|
||||
team_fn: &Teams.Billing.monthly_pageview_limit/1,
|
||||
user_fn: &Plausible.Billing.Quota.Limits.monthly_pageview_limit/1
|
||||
)
|
||||
end
|
||||
|
||||
def monthly_pageview_usage(user, site_ids \\ nil) do
|
||||
switch(
|
||||
user,
|
||||
team_fn: &Teams.Billing.monthly_pageview_usage(&1, site_ids),
|
||||
user_fn: &Plausible.Billing.Quota.Usage.monthly_pageview_usage(&1, site_ids)
|
||||
)
|
||||
end
|
||||
|
||||
def check_needs_to_upgrade(user) do
|
||||
switch(
|
||||
user,
|
||||
|
@ -3,11 +3,13 @@ defmodule Plausible.Teams.Adapter.Read.Sites do
|
||||
Transition adapter for new schema reads
|
||||
"""
|
||||
|
||||
use Plausible.Teams.Adapter
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
alias Plausible.Repo
|
||||
alias Plausible.Site
|
||||
use Plausible.Teams.Adapter
|
||||
alias Plausible.Teams
|
||||
|
||||
def list(user, pagination_params, opts \\ []) do
|
||||
switch(
|
||||
@ -182,6 +184,73 @@ defmodule Plausible.Teams.Adapter.Read.Sites do
|
||||
end
|
||||
end
|
||||
|
||||
def get_for_user!(user, domain, roles \\ [:owner, :admin, :viewer]) do
|
||||
{query_fn, roles} = for_user_query_and_roles(user, roles)
|
||||
|
||||
if :super_admin in roles and Plausible.Auth.is_super_admin?(user.id) do
|
||||
Plausible.Sites.get_by_domain!(domain)
|
||||
else
|
||||
user.id
|
||||
|> query_fn.(domain, List.delete(roles, :super_admin))
|
||||
|> Repo.one!()
|
||||
end
|
||||
end
|
||||
|
||||
def get_for_user(user, domain, roles \\ [:owner, :admin, :viewer]) do
|
||||
{query_fn, roles} = for_user_query_and_roles(user, roles)
|
||||
|
||||
if :super_admin in roles and Plausible.Auth.is_super_admin?(user.id) do
|
||||
Plausible.Sites.get_by_domain(domain)
|
||||
else
|
||||
user.id
|
||||
|> query_fn.(domain, List.delete(roles, :super_admin))
|
||||
|> Repo.one()
|
||||
end
|
||||
end
|
||||
|
||||
defp for_user_query_and_roles(user, roles) do
|
||||
switch(
|
||||
user,
|
||||
team_fn: fn _ ->
|
||||
translated_roles =
|
||||
Enum.map(roles, fn
|
||||
:admin -> :editor
|
||||
other -> other
|
||||
end)
|
||||
|
||||
{&new_get_for_user_query/3, translated_roles}
|
||||
end,
|
||||
user_fn: fn _ ->
|
||||
{&old_get_for_user_query/3, roles}
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
defp old_get_for_user_query(user_id, domain, roles) do
|
||||
from(s in Plausible.Site,
|
||||
join: sm in Plausible.Site.Membership,
|
||||
on: sm.site_id == s.id,
|
||||
where: sm.user_id == ^user_id,
|
||||
where: sm.role in ^roles,
|
||||
where: s.domain == ^domain or s.domain_changed_from == ^domain,
|
||||
select: s
|
||||
)
|
||||
end
|
||||
|
||||
defp new_get_for_user_query(user_id, domain, roles) do
|
||||
roles = Enum.map(roles, &to_string/1)
|
||||
|
||||
from(s in Plausible.Site,
|
||||
join: t in assoc(s, :team),
|
||||
join: tm in assoc(t, :team_memberships),
|
||||
left_join: gm in assoc(tm, :guest_memberships),
|
||||
where: tm.user_id == ^user_id,
|
||||
where: coalesce(gm.role, tm.role) in ^roles,
|
||||
where: s.domain == ^domain or s.domain_changed_from == ^domain,
|
||||
select: s
|
||||
)
|
||||
end
|
||||
|
||||
defp maybe_filter_by_domain(query, domain)
|
||||
when byte_size(domain) >= 1 and byte_size(domain) <= 64 do
|
||||
where(query, [s], ilike(s.domain, ^"%#{domain}%"))
|
||||
|
@ -85,6 +85,10 @@ defmodule Plausible.Teams.Billing do
|
||||
|> length()
|
||||
end
|
||||
|
||||
defp get_site_limit_from_plan(nil) do
|
||||
@site_limit_for_trials
|
||||
end
|
||||
|
||||
defp get_site_limit_from_plan(team) do
|
||||
team =
|
||||
Teams.with_subscription(team)
|
||||
@ -96,6 +100,10 @@ defmodule Plausible.Teams.Billing do
|
||||
end
|
||||
end
|
||||
|
||||
def team_member_limit(nil) do
|
||||
@team_member_limit_for_trials
|
||||
end
|
||||
|
||||
def team_member_limit(team) do
|
||||
team = Teams.with_subscription(team)
|
||||
|
||||
@ -110,7 +118,7 @@ defmodule Plausible.Teams.Billing do
|
||||
team = Teams.with_subscription(team)
|
||||
with_features? = Keyword.get(opts, :with_features, false)
|
||||
pending_site_ids = Keyword.get(opts, :pending_ownership_site_ids, [])
|
||||
team_site_ids = team |> Teams.owned_sites() |> Enum.map(& &1.id)
|
||||
team_site_ids = Teams.owned_sites_ids(team)
|
||||
all_site_ids = pending_site_ids ++ team_site_ids
|
||||
|
||||
monthly_pageviews = monthly_pageview_usage(team, all_site_ids)
|
||||
@ -129,6 +137,50 @@ defmodule Plausible.Teams.Billing do
|
||||
end
|
||||
end
|
||||
|
||||
@monthly_pageview_limit_for_free_10k 10_000
|
||||
@monthly_pageview_limit_for_trials :unlimited
|
||||
|
||||
def monthly_pageview_limit(nil) do
|
||||
@monthly_pageview_limit_for_trials
|
||||
end
|
||||
|
||||
def monthly_pageview_limit(%Teams.Team{} = team) do
|
||||
team = Teams.with_subscription(team)
|
||||
monthly_pageview_limit(team.subscription)
|
||||
end
|
||||
|
||||
def monthly_pageview_limit(subscription) do
|
||||
case Plans.get_subscription_plan(subscription) do
|
||||
%EnterprisePlan{monthly_pageview_limit: limit} ->
|
||||
limit
|
||||
|
||||
%Plan{monthly_pageview_limit: limit} ->
|
||||
limit
|
||||
|
||||
:free_10k ->
|
||||
@monthly_pageview_limit_for_free_10k
|
||||
|
||||
_any ->
|
||||
if subscription do
|
||||
Sentry.capture_message("Unknown monthly pageview limit for plan",
|
||||
extra: %{paddle_plan_id: subscription.paddle_plan_id}
|
||||
)
|
||||
end
|
||||
|
||||
@monthly_pageview_limit_for_trials
|
||||
end
|
||||
end
|
||||
|
||||
def monthly_pageview_usage(team, site_ids \\ nil)
|
||||
|
||||
def monthly_pageview_usage(team, nil) do
|
||||
monthly_pageview_usage(team, Teams.owned_sites_ids(team))
|
||||
end
|
||||
|
||||
def monthly_pageview_usage(nil, _site_ids) do
|
||||
%{last_30_days: usage_cycle(nil, :last_30_days, [])}
|
||||
end
|
||||
|
||||
def monthly_pageview_usage(team, site_ids) do
|
||||
team = Teams.with_subscription(team)
|
||||
active_subscription? = Subscriptions.active?(team.subscription)
|
||||
|
@ -191,7 +191,7 @@ defmodule Plausible.Users do
|
||||
user
|
||||
end
|
||||
|
||||
defp last_subscription_query() do
|
||||
def last_subscription_query() do
|
||||
from(subscription in Subscription,
|
||||
order_by: [desc: subscription.inserted_at],
|
||||
limit: 1
|
||||
|
@ -12,7 +12,7 @@ defmodule PlausibleWeb.AdminController do
|
||||
usage = Quota.Usage.usage(user, with_features: true)
|
||||
|
||||
limits = %{
|
||||
monthly_pageviews: Quota.Limits.monthly_pageview_limit(user),
|
||||
monthly_pageviews: Quota.Limits.monthly_pageview_limit(user.subscription),
|
||||
sites: Quota.Limits.site_limit(user),
|
||||
team_members: Quota.Limits.team_member_limit(user)
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ defmodule PlausibleWeb.SettingsController do
|
||||
alias Plausible.Auth
|
||||
alias PlausibleWeb.UserAuth
|
||||
|
||||
alias Plausible.Billing.Quota
|
||||
|
||||
require Logger
|
||||
|
||||
def index(conn, _params) do
|
||||
@ -23,22 +21,25 @@ defmodule PlausibleWeb.SettingsController do
|
||||
|
||||
def subscription(conn, _params) do
|
||||
current_user = conn.assigns.current_user
|
||||
subscription = Plausible.Teams.Adapter.Read.Billing.get_subscription(current_user)
|
||||
|
||||
render(conn, :subscription,
|
||||
layout: {PlausibleWeb.LayoutView, :settings},
|
||||
subscription: current_user.subscription,
|
||||
pageview_limit: Quota.Limits.monthly_pageview_limit(current_user),
|
||||
pageview_usage: Quota.Usage.monthly_pageview_usage(current_user),
|
||||
site_usage: Quota.Usage.site_usage(current_user),
|
||||
site_limit: Quota.Limits.site_limit(current_user),
|
||||
team_member_limit: Quota.Limits.team_member_limit(current_user),
|
||||
team_member_usage: Quota.Usage.team_member_usage(current_user)
|
||||
subscription: subscription,
|
||||
pageview_limit: Plausible.Teams.Adapter.Read.Billing.monthly_pageview_limit(current_user),
|
||||
pageview_usage: Plausible.Teams.Adapter.Read.Billing.monthly_pageview_usage(current_user),
|
||||
site_usage: Plausible.Teams.Adapter.Read.Billing.site_usage(current_user),
|
||||
site_limit: Plausible.Teams.Adapter.Read.Billing.site_limit(current_user),
|
||||
team_member_limit: Plausible.Teams.Adapter.Read.Billing.team_member_limit(current_user),
|
||||
team_member_usage: Plausible.Teams.Adapter.Read.Billing.team_member_usage(current_user)
|
||||
)
|
||||
end
|
||||
|
||||
def invoices(conn, _params) do
|
||||
current_user = conn.assigns.current_user
|
||||
invoices = Plausible.Billing.paddle_api().get_invoices(current_user.subscription)
|
||||
subscription =
|
||||
Plausible.Teams.Adapter.Read.Billing.get_subscription(conn.assigns.current_user)
|
||||
|
||||
invoices = Plausible.Billing.paddle_api().get_invoices(subscription)
|
||||
render(conn, :invoices, layout: {PlausibleWeb.LayoutView, :settings}, invoices: invoices)
|
||||
end
|
||||
|
||||
|
@ -13,7 +13,6 @@ defmodule PlausibleWeb.Site.MembershipController do
|
||||
use PlausibleWeb, :controller
|
||||
use Plausible.Repo
|
||||
use Plausible
|
||||
alias Plausible.Sites
|
||||
alias Plausible.Site.{Membership, Memberships}
|
||||
|
||||
@only_owner_is_allowed_to [:transfer_ownership_form, :transfer_ownership]
|
||||
@ -26,8 +25,8 @@ defmodule PlausibleWeb.Site.MembershipController do
|
||||
|
||||
def invite_member_form(conn, _params) do
|
||||
site =
|
||||
conn.assigns.current_user.id
|
||||
|> Sites.get_for_user!(conn.assigns.site.domain)
|
||||
conn.assigns.current_user
|
||||
|> Plausible.Teams.Adapter.Read.Sites.get_for_user!(conn.assigns.site.domain)
|
||||
|> Plausible.Repo.preload(:owner)
|
||||
|
||||
limit = Plausible.Billing.Quota.Limits.team_member_limit(site.owner)
|
||||
@ -45,10 +44,10 @@ defmodule PlausibleWeb.Site.MembershipController do
|
||||
end
|
||||
|
||||
def invite_member(conn, %{"email" => email, "role" => role}) do
|
||||
site_domain = conn.assigns[:site].domain
|
||||
site_domain = conn.assigns.site.domain
|
||||
|
||||
site =
|
||||
Sites.get_for_user!(conn.assigns[:current_user].id, site_domain)
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(conn.assigns.current_user, site_domain)
|
||||
|> Plausible.Repo.preload(:owner)
|
||||
|
||||
case Memberships.create_invitation(site, conn.assigns.current_user, email, role) do
|
||||
@ -94,8 +93,10 @@ defmodule PlausibleWeb.Site.MembershipController do
|
||||
end
|
||||
|
||||
def transfer_ownership_form(conn, _params) do
|
||||
site_domain = conn.assigns[:site].domain
|
||||
site = Sites.get_for_user!(conn.assigns[:current_user].id, site_domain)
|
||||
site_domain = conn.assigns.site.domain
|
||||
|
||||
site =
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(conn.assigns.current_user, site_domain)
|
||||
|
||||
render(
|
||||
conn,
|
||||
@ -106,8 +107,10 @@ defmodule PlausibleWeb.Site.MembershipController do
|
||||
end
|
||||
|
||||
def transfer_ownership(conn, %{"email" => email}) do
|
||||
site_domain = conn.assigns[:site].domain
|
||||
site = Sites.get_for_user!(conn.assigns[:current_user].id, site_domain)
|
||||
site_domain = conn.assigns.site.domain
|
||||
|
||||
site =
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(conn.assigns.current_user, site_domain)
|
||||
|
||||
case Memberships.create_invitation(site, conn.assigns.current_user, email, :owner) do
|
||||
{:ok, _invitation} ->
|
||||
|
@ -152,13 +152,8 @@ defmodule PlausibleWeb.SiteController do
|
||||
end
|
||||
|
||||
def settings_goals(conn, _params) do
|
||||
site = Repo.preload(conn.assigns[:site], [:owner])
|
||||
owner = Plausible.Users.with_subscription(site.owner)
|
||||
site = Map.put(site, :owner, owner)
|
||||
|
||||
conn
|
||||
|> render("settings_goals.html",
|
||||
site: site,
|
||||
dogfood_page_path: "/:dashboard/settings/goals",
|
||||
connect_live_socket: true,
|
||||
layout: {PlausibleWeb.LayoutView, "site_settings.html"}
|
||||
@ -166,13 +161,8 @@ defmodule PlausibleWeb.SiteController do
|
||||
end
|
||||
|
||||
def settings_funnels(conn, _params) do
|
||||
site = Repo.preload(conn.assigns[:site], [:owner])
|
||||
owner = Plausible.Users.with_subscription(site.owner)
|
||||
site = Map.put(site, :owner, owner)
|
||||
|
||||
conn
|
||||
|> render("settings_funnels.html",
|
||||
site: site,
|
||||
dogfood_page_path: "/:dashboard/settings/funnels",
|
||||
connect_live_socket: true,
|
||||
layout: {PlausibleWeb.LayoutView, "site_settings.html"}
|
||||
@ -180,13 +170,8 @@ defmodule PlausibleWeb.SiteController do
|
||||
end
|
||||
|
||||
def settings_props(conn, _params) do
|
||||
site = Repo.preload(conn.assigns[:site], [:owner])
|
||||
owner = Plausible.Users.with_subscription(site.owner)
|
||||
site = Map.put(site, :owner, owner)
|
||||
|
||||
conn
|
||||
|> render("settings_props.html",
|
||||
site: site,
|
||||
dogfood_page_path: "/:dashboard/settings/properties",
|
||||
layout: {PlausibleWeb.LayoutView, "site_settings.html"},
|
||||
connect_live_socket: true
|
||||
|
@ -4,7 +4,7 @@ defmodule PlausibleWeb.Live.GoalSettings do
|
||||
"""
|
||||
use PlausibleWeb, :live_view
|
||||
|
||||
alias Plausible.{Sites, Goals}
|
||||
alias Plausible.Goals
|
||||
alias PlausibleWeb.Live.Components.Modal
|
||||
|
||||
def mount(
|
||||
@ -16,7 +16,7 @@ defmodule PlausibleWeb.Live.GoalSettings do
|
||||
socket
|
||||
|> assign_new(:site, fn %{current_user: current_user} ->
|
||||
current_user
|
||||
|> Sites.get_for_user!(domain, [:owner, :admin, :super_admin])
|
||||
|> Plausible.Teams.Adapter.Read.Sites.get_for_user!(domain, [:owner, :admin, :super_admin])
|
||||
|> Plausible.Imported.load_import_data()
|
||||
end)
|
||||
|> assign_new(:all_goals, fn %{site: site} ->
|
||||
|
@ -8,7 +8,6 @@ defmodule PlausibleWeb.Live.ImportsExportsSettings do
|
||||
|
||||
alias Plausible.Imported
|
||||
alias Plausible.Imported.SiteImport
|
||||
alias Plausible.Sites
|
||||
|
||||
require Plausible.Imported.SiteImport
|
||||
|
||||
@ -16,7 +15,11 @@ defmodule PlausibleWeb.Live.ImportsExportsSettings do
|
||||
socket =
|
||||
socket
|
||||
|> assign_new(:site, fn %{current_user: current_user} ->
|
||||
Sites.get_for_user!(current_user, domain, [:owner, :admin, :super_admin])
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(current_user, domain, [
|
||||
:owner,
|
||||
:admin,
|
||||
:super_admin
|
||||
])
|
||||
end)
|
||||
|> assign_new(:site_imports, fn %{site: site} ->
|
||||
site
|
||||
|
@ -32,7 +32,7 @@ defmodule PlausibleWeb.Live.Installation do
|
||||
socket
|
||||
) do
|
||||
site =
|
||||
Plausible.Sites.get_for_user!(socket.assigns.current_user, domain, [
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(socket.assigns.current_user, domain, [
|
||||
:owner,
|
||||
:admin,
|
||||
:super_admin,
|
||||
|
@ -5,14 +5,17 @@ defmodule PlausibleWeb.Live.Plugins.API.Settings do
|
||||
|
||||
use PlausibleWeb, :live_view
|
||||
|
||||
alias Plausible.Sites
|
||||
alias Plausible.Plugins.API.Tokens
|
||||
|
||||
def mount(_params, %{"domain" => domain} = session, socket) do
|
||||
socket =
|
||||
socket
|
||||
|> assign_new(:site, fn %{current_user: current_user} ->
|
||||
Sites.get_for_user!(current_user, domain, [:owner, :admin, :super_admin])
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(current_user, domain, [
|
||||
:owner,
|
||||
:admin,
|
||||
:super_admin
|
||||
])
|
||||
end)
|
||||
|> assign_new(:displayed_tokens, fn %{site: site} ->
|
||||
Tokens.list(site)
|
||||
|
@ -5,7 +5,6 @@ defmodule PlausibleWeb.Live.Plugins.API.TokenForm do
|
||||
use PlausibleWeb, live_view: :no_sentry_context
|
||||
import PlausibleWeb.Live.Components.Form
|
||||
|
||||
alias Plausible.Sites
|
||||
alias Plausible.Plugins.API.{Token, Tokens}
|
||||
|
||||
def mount(
|
||||
@ -20,7 +19,11 @@ defmodule PlausibleWeb.Live.Plugins.API.TokenForm do
|
||||
socket =
|
||||
socket
|
||||
|> assign_new(:site, fn %{current_user: current_user} ->
|
||||
Sites.get_for_user!(current_user, domain, [:owner, :admin, :super_admin])
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(current_user, domain, [
|
||||
:owner,
|
||||
:admin,
|
||||
:super_admin
|
||||
])
|
||||
end)
|
||||
|
||||
token = Token.generate()
|
||||
|
@ -11,7 +11,11 @@ defmodule PlausibleWeb.Live.PropsSettings do
|
||||
socket =
|
||||
socket
|
||||
|> assign_new(:site, fn %{current_user: current_user} ->
|
||||
Plausible.Sites.get_for_user!(current_user, domain, [:owner, :admin, :super_admin])
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(current_user, domain, [
|
||||
:owner,
|
||||
:admin,
|
||||
:super_admin
|
||||
])
|
||||
end)
|
||||
|> assign_new(:all_props, fn %{site: site} ->
|
||||
site.allowed_event_props || []
|
||||
|
@ -18,7 +18,11 @@ defmodule PlausibleWeb.Live.PropsSettings.Form do
|
||||
socket =
|
||||
socket
|
||||
|> assign_new(:site, fn %{current_user: current_user} ->
|
||||
Plausible.Sites.get_for_user!(current_user, domain, [:owner, :admin, :super_admin])
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(current_user, domain, [
|
||||
:owner,
|
||||
:admin,
|
||||
:super_admin
|
||||
])
|
||||
end)
|
||||
|> assign_new(:form, fn %{site: site} ->
|
||||
new_form(site)
|
||||
|
@ -5,7 +5,6 @@ defmodule PlausibleWeb.Live.Shields.Countries do
|
||||
use PlausibleWeb, :live_view
|
||||
|
||||
alias Plausible.Shields
|
||||
alias Plausible.Sites
|
||||
|
||||
def mount(
|
||||
_params,
|
||||
@ -15,7 +14,11 @@ defmodule PlausibleWeb.Live.Shields.Countries do
|
||||
socket =
|
||||
socket
|
||||
|> assign_new(:site, fn %{current_user: current_user} ->
|
||||
Sites.get_for_user!(current_user, domain, [:owner, :admin, :super_admin])
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(current_user, domain, [
|
||||
:owner,
|
||||
:admin,
|
||||
:super_admin
|
||||
])
|
||||
end)
|
||||
|> assign_new(:country_rules_count, fn %{site: site} ->
|
||||
Shields.count_country_rules(site)
|
||||
|
@ -5,13 +5,16 @@ defmodule PlausibleWeb.Live.Shields.Hostnames do
|
||||
use PlausibleWeb, :live_view
|
||||
|
||||
alias Plausible.Shields
|
||||
alias Plausible.Sites
|
||||
|
||||
def mount(_params, %{"domain" => domain}, socket) do
|
||||
socket =
|
||||
socket
|
||||
|> assign_new(:site, fn %{current_user: current_user} ->
|
||||
Sites.get_for_user!(current_user, domain, [:owner, :admin, :super_admin])
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(current_user, domain, [
|
||||
:owner,
|
||||
:admin,
|
||||
:super_admin
|
||||
])
|
||||
end)
|
||||
|> assign_new(:hostname_rules_count, fn %{site: site} ->
|
||||
Shields.count_hostname_rules(site)
|
||||
|
@ -5,7 +5,6 @@ defmodule PlausibleWeb.Live.Shields.IPAddresses do
|
||||
use PlausibleWeb, :live_view
|
||||
|
||||
alias Plausible.Shields
|
||||
alias Plausible.Sites
|
||||
|
||||
def mount(
|
||||
_params,
|
||||
@ -18,7 +17,11 @@ defmodule PlausibleWeb.Live.Shields.IPAddresses do
|
||||
socket =
|
||||
socket
|
||||
|> assign_new(:site, fn %{current_user: current_user} ->
|
||||
Sites.get_for_user!(current_user, domain, [:owner, :admin, :super_admin])
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(current_user, domain, [
|
||||
:owner,
|
||||
:admin,
|
||||
:super_admin
|
||||
])
|
||||
end)
|
||||
|> assign_new(:ip_rules_count, fn %{site: site} ->
|
||||
Shields.count_ip_rules(site)
|
||||
|
@ -5,13 +5,16 @@ defmodule PlausibleWeb.Live.Shields.Pages do
|
||||
use PlausibleWeb, :live_view
|
||||
|
||||
alias Plausible.Shields
|
||||
alias Plausible.Sites
|
||||
|
||||
def mount(_params, %{"domain" => domain}, socket) do
|
||||
socket =
|
||||
socket
|
||||
|> assign_new(:site, fn %{current_user: current_user} ->
|
||||
Sites.get_for_user!(current_user, domain, [:owner, :admin, :super_admin])
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(current_user, domain, [
|
||||
:owner,
|
||||
:admin,
|
||||
:super_admin
|
||||
])
|
||||
end)
|
||||
|> assign_new(:page_rules_count, fn %{site: site} ->
|
||||
Shields.count_page_rules(site)
|
||||
|
@ -18,7 +18,7 @@ defmodule PlausibleWeb.Live.Verification do
|
||||
socket
|
||||
) do
|
||||
site =
|
||||
Plausible.Sites.get_for_user!(socket.assigns.current_user, domain, [
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user!(socket.assigns.current_user, domain, [
|
||||
:owner,
|
||||
:admin,
|
||||
:super_admin,
|
||||
|
@ -107,9 +107,21 @@ defmodule PlausibleWeb.Plugs.AuthorizeSiteAccess do
|
||||
Sentry.Context.set_extra_context(%{site_id: site.id, domain: site.domain})
|
||||
Plausible.OpenTelemetry.add_site_attributes(site)
|
||||
|
||||
site = Plausible.Imported.load_import_data(site)
|
||||
site =
|
||||
site
|
||||
|> Plausible.Imported.load_import_data()
|
||||
|> Repo.preload(
|
||||
team: [subscription: Plausible.Teams.last_subscription_query()],
|
||||
owner: [subscription: Plausible.Users.last_subscription_query()]
|
||||
)
|
||||
|
||||
merge_assigns(conn, site: site, current_user_role: role)
|
||||
conn = merge_assigns(conn, site: site, current_user_role: role)
|
||||
|
||||
if not is_nil(current_user) and role not in [:public, nil] do
|
||||
assign(conn, :current_team, site.team)
|
||||
else
|
||||
conn
|
||||
end
|
||||
else
|
||||
error_not_found(conn)
|
||||
end
|
||||
|
@ -123,7 +123,8 @@ defmodule PlausibleWeb.UserAuth do
|
||||
defp get_session_by_token(token) do
|
||||
now = NaiveDateTime.utc_now(:second)
|
||||
|
||||
last_subscription_query = Plausible.Users.last_subscription_join_query()
|
||||
last_user_subscription_query = Plausible.Users.last_subscription_join_query()
|
||||
last_team_subscription_query = Plausible.Teams.last_subscription_join_query()
|
||||
|
||||
token_query =
|
||||
from(us in Auth.UserSession,
|
||||
@ -132,10 +133,13 @@ defmodule PlausibleWeb.UserAuth do
|
||||
left_join: tm in assoc(u, :team_memberships),
|
||||
on: tm.role != :guest,
|
||||
left_join: t in assoc(tm, :team),
|
||||
left_lateral_join: s in subquery(last_subscription_query),
|
||||
as: :team,
|
||||
left_lateral_join: ts in subquery(last_team_subscription_query),
|
||||
on: true,
|
||||
left_lateral_join: s in subquery(last_user_subscription_query),
|
||||
on: true,
|
||||
where: us.token == ^token and us.timeout_at > ^now,
|
||||
preload: [user: {u, subscription: s, team_memberships: {tm, team: t}}]
|
||||
preload: [user: {u, subscription: s, team_memberships: {tm, team: {t, subscription: ts}}}]
|
||||
)
|
||||
|
||||
case Repo.one(token_query) do
|
||||
|
@ -150,7 +150,7 @@ defmodule Plausible.Workers.CheckUsage do
|
||||
|
||||
defp check_pageview_usage_two_cycles(subscriber, usage_mod) do
|
||||
usage = usage_mod.monthly_pageview_usage(subscriber)
|
||||
limit = Quota.Limits.monthly_pageview_limit(subscriber)
|
||||
limit = Quota.Limits.monthly_pageview_limit(subscriber.subscription)
|
||||
|
||||
if Quota.exceeds_last_two_usage_cycles?(usage, limit) do
|
||||
{:over_limit, usage}
|
||||
@ -161,7 +161,7 @@ defmodule Plausible.Workers.CheckUsage do
|
||||
|
||||
defp check_pageview_usage_last_cycle(subscriber, usage_mod) do
|
||||
usage = usage_mod.monthly_pageview_usage(subscriber)
|
||||
limit = Quota.Limits.monthly_pageview_limit(subscriber)
|
||||
limit = Quota.Limits.monthly_pageview_limit(subscriber.subscription)
|
||||
|
||||
if :last_cycle in Quota.exceeded_cycles(usage, limit) do
|
||||
{:over_limit, usage}
|
||||
|
@ -157,16 +157,20 @@ defmodule Plausible.SitesTest do
|
||||
describe "get_for_user/2" do
|
||||
@tag :ee_only
|
||||
test "get site for super_admin" do
|
||||
user1 = insert(:user)
|
||||
user2 = insert(:user)
|
||||
user1 = new_user()
|
||||
user2 = new_user()
|
||||
patch_env(:super_admin_user_ids, [user2.id])
|
||||
|
||||
%{id: site_id, domain: domain} = insert(:site, members: [user1])
|
||||
assert %{id: ^site_id} = Sites.get_for_user(user1.id, domain)
|
||||
assert %{id: ^site_id} = Sites.get_for_user(user1.id, domain, [:owner])
|
||||
%{id: site_id, domain: domain} = new_site(owner: user1)
|
||||
assert %{id: ^site_id} = Plausible.Teams.Adapter.Read.Sites.get_for_user(user1, domain)
|
||||
|
||||
assert is_nil(Sites.get_for_user(user2.id, domain))
|
||||
assert %{id: ^site_id} = Sites.get_for_user(user2.id, domain, [:super_admin])
|
||||
assert %{id: ^site_id} =
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user(user1, domain, [:owner])
|
||||
|
||||
assert is_nil(Plausible.Teams.Adapter.Read.Sites.get_for_user(user2, domain))
|
||||
|
||||
assert %{id: ^site_id} =
|
||||
Plausible.Teams.Adapter.Read.Sites.get_for_user(user2, domain, [:super_admin])
|
||||
end
|
||||
end
|
||||
|
||||
@ -487,8 +491,8 @@ defmodule Plausible.SitesTest do
|
||||
|
||||
describe "set_option/4" do
|
||||
test "allows setting option multiple times" do
|
||||
user = insert(:user)
|
||||
site = insert(:site, members: [user])
|
||||
user = new_user()
|
||||
site = new_site(owner: user)
|
||||
|
||||
assert prefs =
|
||||
%{pinned_at: %NaiveDateTime{}} =
|
||||
@ -538,8 +542,8 @@ defmodule Plausible.SitesTest do
|
||||
|
||||
describe "toggle_pin/2" do
|
||||
test "allows pinning and unpinning site" do
|
||||
user = insert(:user)
|
||||
site = insert(:site, members: [user])
|
||||
user = new_user()
|
||||
site = new_site(owner: user)
|
||||
|
||||
site = %{site | pinned_at: nil}
|
||||
assert {:ok, prefs} = Sites.toggle_pin(user, site)
|
||||
@ -567,10 +571,10 @@ defmodule Plausible.SitesTest do
|
||||
end
|
||||
|
||||
test "returns error when pins limit hit" do
|
||||
user = insert(:user)
|
||||
user = new_user()
|
||||
|
||||
for _ <- 1..9 do
|
||||
site = insert(:site, members: [user])
|
||||
site = new_site(owner: user)
|
||||
assert {:ok, _} = Sites.toggle_pin(user, site)
|
||||
end
|
||||
|
||||
|
@ -232,15 +232,11 @@ defmodule PlausibleWeb.Api.ExternalSitesControllerTest do
|
||||
|
||||
test "returns 404 when api key owner does not have permissions to create a shared link", %{
|
||||
conn: conn,
|
||||
site: site,
|
||||
user: user
|
||||
} do
|
||||
Repo.update_all(
|
||||
from(sm in Plausible.Site.Membership,
|
||||
where: sm.site_id == ^site.id and sm.user_id == ^user.id
|
||||
),
|
||||
set: [role: :viewer]
|
||||
)
|
||||
site = new_site()
|
||||
|
||||
add_guest(site, user: user, role: :viewer)
|
||||
|
||||
conn =
|
||||
put(conn, "/api/v1/sites/shared-links", %{
|
||||
@ -383,15 +379,11 @@ defmodule PlausibleWeb.Api.ExternalSitesControllerTest do
|
||||
|
||||
test "returns 404 when api key owner does not have permissions to create a goal", %{
|
||||
conn: conn,
|
||||
site: site,
|
||||
user: user
|
||||
} do
|
||||
Repo.update_all(
|
||||
from(sm in Plausible.Site.Membership,
|
||||
where: sm.site_id == ^site.id and sm.user_id == ^user.id
|
||||
),
|
||||
set: [role: :viewer]
|
||||
)
|
||||
site = new_site()
|
||||
|
||||
add_guest(site, user: user, role: :viewer)
|
||||
|
||||
conn =
|
||||
put(conn, "/api/v1/sites/goals", %{
|
||||
|
@ -2,6 +2,7 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
use PlausibleWeb.ConnCase, async: true
|
||||
use Bamboo.Test
|
||||
use Plausible.Repo
|
||||
use Plausible.Teams.Test
|
||||
|
||||
import Mox
|
||||
import Plausible.Test.Support.HTML
|
||||
@ -23,7 +24,7 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
|
||||
@tag :ee_only
|
||||
test "shows subscription", %{conn: conn, user: user} do
|
||||
insert(:subscription, paddle_plan_id: "558018", user: user)
|
||||
subscribe_to_plan(user, "558018")
|
||||
conn = get(conn, Routes.settings_path(conn, :subscription))
|
||||
assert html_response(conn, 200) =~ "10k pageviews"
|
||||
assert html_response(conn, 200) =~ "monthly billing"
|
||||
@ -31,7 +32,7 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
|
||||
@tag :ee_only
|
||||
test "shows yearly subscription", %{conn: conn, user: user} do
|
||||
insert(:subscription, paddle_plan_id: "590752", user: user)
|
||||
subscribe_to_plan(user, "590752")
|
||||
conn = get(conn, Routes.settings_path(conn, :subscription))
|
||||
assert html_response(conn, 200) =~ "100k pageviews"
|
||||
assert html_response(conn, 200) =~ "yearly billing"
|
||||
@ -39,7 +40,7 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
|
||||
@tag :ee_only
|
||||
test "shows free subscription", %{conn: conn, user: user} do
|
||||
insert(:subscription, paddle_plan_id: "free_10k", user: user)
|
||||
subscribe_to_plan(user, "free_10k")
|
||||
conn = get(conn, Routes.settings_path(conn, :subscription))
|
||||
assert html_response(conn, 200) =~ "10k pageviews"
|
||||
assert html_response(conn, 200) =~ "N/A billing"
|
||||
@ -47,8 +48,7 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
|
||||
@tag :ee_only
|
||||
test "shows enterprise plan subscription", %{conn: conn, user: user} do
|
||||
insert(:subscription, paddle_plan_id: "123", user: user)
|
||||
|
||||
subscribe_to_plan(user, "123")
|
||||
configure_enterprise_plan(user)
|
||||
|
||||
conn = get(conn, Routes.settings_path(conn, :subscription))
|
||||
@ -61,20 +61,15 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
conn: conn,
|
||||
user: user
|
||||
} do
|
||||
insert(:subscription,
|
||||
paddle_plan_id: @configured_enterprise_plan_paddle_plan_id,
|
||||
user: user
|
||||
)
|
||||
|
||||
insert(:enterprise_plan,
|
||||
paddle_plan_id: "1234",
|
||||
user: user,
|
||||
monthly_pageview_limit: 10_000_000,
|
||||
billing_interval: :yearly
|
||||
)
|
||||
|
||||
configure_enterprise_plan(user)
|
||||
|
||||
subscribe_to_enterprise_plan(user,
|
||||
paddle_plan_id: "1234",
|
||||
monthly_pageview_limit: 10_000_000,
|
||||
billing_interval: :yearly,
|
||||
subscription?: false
|
||||
)
|
||||
|
||||
conn = get(conn, Routes.settings_path(conn, :subscription))
|
||||
assert html_response(conn, 200) =~ "20M pageviews"
|
||||
assert html_response(conn, 200) =~ "yearly billing"
|
||||
@ -102,7 +97,7 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
conn: conn,
|
||||
user: user
|
||||
} do
|
||||
insert(:subscription, paddle_plan_id: @v3_plan_id, user: user)
|
||||
subscribe_to_plan(user, @v3_plan_id)
|
||||
|
||||
doc =
|
||||
conn
|
||||
@ -161,7 +156,12 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
@tag :ee_only
|
||||
test "renders two links to '/billing/choose-plan' with the text 'Upgrade' for a configured enterprise plan",
|
||||
%{conn: conn, user: user} do
|
||||
configure_enterprise_plan(user)
|
||||
subscribe_to_enterprise_plan(user,
|
||||
paddle_plan_id: @configured_enterprise_plan_paddle_plan_id,
|
||||
monthly_pageview_limit: 20_000_000,
|
||||
billing_interval: :yearly,
|
||||
subscription?: false
|
||||
)
|
||||
|
||||
doc =
|
||||
conn
|
||||
@ -282,7 +282,7 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
conn: conn,
|
||||
user: user
|
||||
} do
|
||||
site = insert(:site, members: [user])
|
||||
site = new_site(owner: user)
|
||||
|
||||
populate_stats(site, [
|
||||
build(:event, name: "pageview", timestamp: Timex.shift(Timex.now(), days: -5)),
|
||||
@ -293,12 +293,7 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
|
||||
last_bill_date = Timex.shift(Timex.today(), days: -10)
|
||||
|
||||
insert(:subscription,
|
||||
paddle_plan_id: @v4_plan_id,
|
||||
user: user,
|
||||
status: :deleted,
|
||||
last_bill_date: last_bill_date
|
||||
)
|
||||
subscribe_to_plan(user, @v4_plan_id, last_bill_date: last_bill_date, status: :deleted)
|
||||
|
||||
html =
|
||||
conn
|
||||
@ -358,14 +353,11 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
assert element_exists?(doc, "#total_pageviews_penultimate_cycle")
|
||||
end
|
||||
|
||||
# for an active subscription
|
||||
subscription =
|
||||
insert(:subscription,
|
||||
paddle_plan_id: @v4_plan_id,
|
||||
user: user,
|
||||
subscribe_to_plan(user, @v4_plan_id,
|
||||
status: :active,
|
||||
last_bill_date: Timex.shift(Timex.now(), months: -6)
|
||||
)
|
||||
).subscription
|
||||
|
||||
get(conn, Routes.settings_path(conn, :subscription))
|
||||
|> html_response(200)
|
||||
@ -398,7 +390,7 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
|
||||
@tag :ee_only
|
||||
test "penultimate cycle is disabled if there's no usage", %{conn: conn, user: user} do
|
||||
site = insert(:site, members: [user])
|
||||
site = new_site(owner: user)
|
||||
|
||||
populate_stats(site, [
|
||||
build(:event, name: "pageview", timestamp: Timex.shift(Timex.now(), days: -5)),
|
||||
@ -407,11 +399,7 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
|
||||
last_bill_date = Timex.shift(Timex.today(), days: -10)
|
||||
|
||||
insert(:subscription,
|
||||
paddle_plan_id: @v4_plan_id,
|
||||
user: user,
|
||||
last_bill_date: last_bill_date
|
||||
)
|
||||
subscribe_to_plan(user, @v4_plan_id, last_bill_date: last_bill_date)
|
||||
|
||||
html =
|
||||
conn
|
||||
@ -429,11 +417,7 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
conn: conn,
|
||||
user: user
|
||||
} do
|
||||
insert(:subscription,
|
||||
paddle_plan_id: @v4_plan_id,
|
||||
user: user,
|
||||
last_bill_date: Timex.shift(Timex.today(), days: -1)
|
||||
)
|
||||
subscribe_to_plan(user, @v4_plan_id, last_bill_date: Timex.shift(Timex.today(), days: -1))
|
||||
|
||||
html =
|
||||
conn
|
||||
@ -450,7 +434,7 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
conn: conn,
|
||||
user: user
|
||||
} do
|
||||
site = insert(:site, members: [user])
|
||||
site = new_site(owner: user)
|
||||
|
||||
populate_stats(site, [
|
||||
build(:event, name: "pageview", timestamp: Timex.shift(Timex.now(), days: -1)),
|
||||
@ -474,15 +458,12 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
|> html_response(200)
|
||||
|> assert_usage.()
|
||||
|
||||
# for an expired subscription
|
||||
subscription =
|
||||
insert(:subscription,
|
||||
paddle_plan_id: @v4_plan_id,
|
||||
user: user,
|
||||
subscribe_to_plan(user, @v4_plan_id,
|
||||
status: :deleted,
|
||||
last_bill_date: ~D[2022-01-01],
|
||||
next_bill_date: ~D[2022-02-01]
|
||||
)
|
||||
).subscription
|
||||
|
||||
conn
|
||||
|> get(Routes.settings_path(conn, :subscription))
|
||||
@ -514,8 +495,8 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
|
||||
@tag :ee_only
|
||||
test "renders sites usage and limit", %{conn: conn, user: user} do
|
||||
insert(:subscription, paddle_plan_id: @v3_plan_id, user: user)
|
||||
insert(:site, members: [user])
|
||||
subscribe_to_plan(user, @v3_plan_id)
|
||||
new_site(owner: user)
|
||||
|
||||
site_usage_row_text =
|
||||
conn
|
||||
@ -541,7 +522,7 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
|
||||
@tag :ee_only
|
||||
test "renders team member usage without limit if it's unlimited", %{conn: conn, user: user} do
|
||||
insert(:subscription, paddle_plan_id: @v3_plan_id, user: user)
|
||||
subscribe_to_plan(user, @v3_plan_id)
|
||||
|
||||
team_member_usage_row_text =
|
||||
conn
|
||||
@ -570,11 +551,7 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
|
||||
@tag :ee_only
|
||||
test "shows invoices for subscribed user", %{conn: conn, user: user} do
|
||||
insert(:subscription,
|
||||
paddle_plan_id: "558018",
|
||||
paddle_subscription_id: "redundant",
|
||||
user: user
|
||||
)
|
||||
subscribe_to_plan(user, "558018")
|
||||
|
||||
html =
|
||||
conn
|
||||
@ -589,11 +566,7 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
|
||||
@tag :ee_only
|
||||
test "shows message on failed invoice request'", %{conn: conn, user: user} do
|
||||
insert(:subscription,
|
||||
paddle_plan_id: "558018",
|
||||
paddle_subscription_id: "invalid_subscription_id",
|
||||
user: user
|
||||
)
|
||||
subscribe_to_plan(user, "558018", paddle_subscription_id: "invalid_subscription_id")
|
||||
|
||||
html =
|
||||
conn
|
||||
@ -1125,9 +1098,8 @@ defmodule PlausibleWeb.SettingsControllerTest do
|
||||
end
|
||||
|
||||
defp configure_enterprise_plan(user) do
|
||||
insert(:enterprise_plan,
|
||||
subscribe_to_enterprise_plan(user,
|
||||
paddle_plan_id: @configured_enterprise_plan_paddle_plan_id,
|
||||
user: user,
|
||||
monthly_pageview_limit: 20_000_000,
|
||||
billing_interval: :yearly
|
||||
)
|
||||
|
@ -13,7 +13,7 @@ defmodule PlausibleWeb.Site.MembershipControllerTest do
|
||||
|
||||
describe "GET /sites/:domain/memberships/invite" do
|
||||
test "shows invite form", %{conn: conn, user: user} do
|
||||
site = insert(:site, members: [user])
|
||||
site = new_site(owner: user)
|
||||
|
||||
html =
|
||||
conn
|
||||
@ -27,11 +27,11 @@ defmodule PlausibleWeb.Site.MembershipControllerTest do
|
||||
|
||||
@tag :ee_only
|
||||
test "display a notice when is over limit", %{conn: conn, user: user} do
|
||||
memberships = [
|
||||
build(:site_membership, user: user, role: :owner) | build_list(5, :site_membership)
|
||||
]
|
||||
site = new_site(owner: user)
|
||||
|
||||
site = insert(:site, memberships: memberships)
|
||||
for _ <- 1..5 do
|
||||
add_guest(site, role: :viewer)
|
||||
end
|
||||
|
||||
html =
|
||||
conn
|
||||
@ -44,7 +44,7 @@ defmodule PlausibleWeb.Site.MembershipControllerTest do
|
||||
|
||||
describe "POST /sites/:domain/memberships/invite" do
|
||||
test "creates invitation", %{conn: conn, user: user} do
|
||||
site = insert(:site, members: [user])
|
||||
site = new_site(owner: user)
|
||||
|
||||
conn =
|
||||
post(conn, "/sites/#{site.domain}/memberships/invite", %{
|
||||
@ -60,11 +60,11 @@ defmodule PlausibleWeb.Site.MembershipControllerTest do
|
||||
|
||||
@tag :ee_only
|
||||
test "fails to create invitation when is over limit", %{conn: conn, user: user} do
|
||||
memberships = [
|
||||
build(:site_membership, user: user, role: :owner) | build_list(5, :site_membership)
|
||||
]
|
||||
site = new_site(owner: user)
|
||||
|
||||
site = insert(:site, memberships: memberships)
|
||||
for _ <- 1..5 do
|
||||
add_guest(site, role: :viewer)
|
||||
end
|
||||
|
||||
conn =
|
||||
post(conn, "/sites/#{site.domain}/memberships/invite", %{
|
||||
@ -110,7 +110,7 @@ defmodule PlausibleWeb.Site.MembershipControllerTest do
|
||||
end
|
||||
|
||||
test "sends invitation email for new user", %{conn: conn, user: user} do
|
||||
site = insert(:site, members: [user])
|
||||
site = new_site(owner: user)
|
||||
|
||||
post(conn, "/sites/#{site.domain}/memberships/invite", %{
|
||||
email: "john.doe@example.com",
|
||||
@ -125,7 +125,7 @@ defmodule PlausibleWeb.Site.MembershipControllerTest do
|
||||
|
||||
test "sends invitation email for existing user", %{conn: conn, user: user} do
|
||||
existing_user = insert(:user)
|
||||
site = insert(:site, members: [user])
|
||||
site = new_site(owner: user)
|
||||
|
||||
post(conn, "/sites/#{site.domain}/memberships/invite", %{
|
||||
email: existing_user.email,
|
||||
@ -139,14 +139,10 @@ defmodule PlausibleWeb.Site.MembershipControllerTest do
|
||||
end
|
||||
|
||||
test "renders form with error if the invitee is already a member", %{conn: conn, user: user} do
|
||||
second_member = insert(:user)
|
||||
site = new_site(owner: user)
|
||||
|
||||
memberships = [
|
||||
build(:site_membership, user: user, role: :owner),
|
||||
build(:site_membership, user: second_member)
|
||||
]
|
||||
|
||||
site = insert(:site, memberships: memberships)
|
||||
second_member = new_user()
|
||||
add_guest(site, user: second_member, role: :viewer)
|
||||
|
||||
conn =
|
||||
post(conn, "/sites/#{site.domain}/memberships/invite", %{
|
||||
@ -162,7 +158,7 @@ defmodule PlausibleWeb.Site.MembershipControllerTest do
|
||||
conn: conn,
|
||||
user: user
|
||||
} do
|
||||
site = insert(:site, members: [user])
|
||||
site = new_site(owner: user)
|
||||
|
||||
_req1 =
|
||||
post(conn, "/sites/#{site.domain}/memberships/invite", %{
|
||||
@ -202,7 +198,7 @@ defmodule PlausibleWeb.Site.MembershipControllerTest do
|
||||
|
||||
describe "GET /sites/:domain/transfer-ownership" do
|
||||
test "shows ownership transfer form", %{conn: conn, user: user} do
|
||||
site = insert(:site, members: [user])
|
||||
site = new_site(owner: user)
|
||||
|
||||
conn = get(conn, "/sites/#{site.domain}/transfer-ownership")
|
||||
|
||||
@ -212,7 +208,7 @@ defmodule PlausibleWeb.Site.MembershipControllerTest do
|
||||
|
||||
describe "POST /sites/:domain/transfer-ownership" do
|
||||
test "creates invitation with :owner role", %{conn: conn, user: user} do
|
||||
site = insert(:site, members: [user])
|
||||
site = new_site(owner: user)
|
||||
|
||||
conn =
|
||||
post(conn, "/sites/#{site.domain}/transfer-ownership", %{email: "john.doe@example.com"})
|
||||
@ -224,7 +220,7 @@ defmodule PlausibleWeb.Site.MembershipControllerTest do
|
||||
end
|
||||
|
||||
test "sends ownership transfer email for new user", %{conn: conn, user: user} do
|
||||
site = insert(:site, members: [user])
|
||||
site = new_site(owner: user)
|
||||
|
||||
post(conn, "/sites/#{site.domain}/transfer-ownership", %{email: "john.doe@example.com"})
|
||||
|
||||
@ -236,7 +232,7 @@ defmodule PlausibleWeb.Site.MembershipControllerTest do
|
||||
|
||||
test "sends invitation email for existing user", %{conn: conn, user: user} do
|
||||
existing_user = insert(:user)
|
||||
site = insert(:site, members: [user])
|
||||
site = new_site(owner: user)
|
||||
|
||||
post(conn, "/sites/#{site.domain}/transfer-ownership", %{email: existing_user.email})
|
||||
|
||||
@ -262,7 +258,7 @@ defmodule PlausibleWeb.Site.MembershipControllerTest do
|
||||
|
||||
test "fails to transfer ownership to invited user with proper error message", ctx do
|
||||
%{conn: conn, user: user} = ctx
|
||||
site = insert(:site, members: [user])
|
||||
site = new_site(owner: user)
|
||||
invited = "john.doe@example.com"
|
||||
|
||||
# invite a user but don't join
|
||||
|
@ -444,13 +444,7 @@ defmodule PlausibleWeb.SiteControllerTest do
|
||||
conn: conn,
|
||||
user: user
|
||||
} do
|
||||
:site
|
||||
|> insert(
|
||||
domain: "example.com",
|
||||
memberships: [
|
||||
build(:site_membership, user: user, role: :owner)
|
||||
]
|
||||
)
|
||||
new_site(domain: "example.com", owner: user)
|
||||
|> Plausible.Site.Domain.change("new.example.com")
|
||||
|
||||
conn =
|
||||
|
@ -149,11 +149,11 @@ defmodule Plausible.Teams.Test do
|
||||
user
|
||||
end
|
||||
|
||||
def subscribe_to_plan(user, paddle_plan_id) do
|
||||
def subscribe_to_plan(user, paddle_plan_id, attrs \\ []) do
|
||||
{:ok, team} = Teams.get_or_create(user)
|
||||
|
||||
insert(:subscription, user: user, team: team, paddle_plan_id: paddle_plan_id)
|
||||
user
|
||||
attrs = Keyword.merge([user: user, team: team, paddle_plan_id: paddle_plan_id], attrs)
|
||||
subscription = insert(:subscription, attrs)
|
||||
%{user | subscription: subscription}
|
||||
end
|
||||
|
||||
def subscribe_to_enterprise_plan(user, attrs \\ []) do
|
||||
|
Loading…
Reference in New Issue
Block a user