| defmodule PlausibleWeb.Live.PropsSettingsTest do |
| use PlausibleWeb.ConnCase, async: true |
| import Phoenix.LiveViewTest |
|
|
| describe "GET /:domain/settings/properties" do |
| setup [:create_user, :log_in, :create_site] |
|
|
| @tag :ee_only |
| test "renders with locked content when subscription is insufficient", %{ |
| conn: conn, |
| site: site, |
| user: user |
| } do |
| subscribe_to_growth_plan(user) |
|
|
| lock_notice = |
| conn |
| |> get("/#{site.domain}/settings/properties") |
| |> html_response(200) |
| |> text_of_element("#lock-notice") |
|
|
| assert lock_notice =~ "upgrade your subscription" |
| end |
|
|
| @tag :ee_only |
| test "does not lock content when subscription is sufficient", %{ |
| conn: conn, |
| site: site, |
| user: user |
| } do |
| subscribe_to_business_plan(user) |
|
|
| lock_notice = |
| conn |
| |> get("/#{site.domain}/settings/properties") |
| |> html_response(200) |
| |> text_of_element("#lock-notice") |
|
|
| refute lock_notice =~ "upgrade your subscription" |
| end |
|
|
| @tag :ee_only |
| test "guest editors should be able to access prop settings", %{site: site, conn: conn} do |
| guest_user = new_user() |
| add_guest(site, user: guest_user, role: :editor) |
|
|
| {:ok, conn: conn} = log_in(%{user: guest_user, conn: conn}) |
|
|
| lock_notice = |
| conn |
| |> get("/#{site.domain}/settings/properties") |
| |> html_response(200) |
| |> text_of_element("#lock-notice") |
|
|
| refute lock_notice =~ "upgrade your subscription" |
| end |
|
|
| test "lists props for the site and renders links", %{conn: conn, site: site} do |
| {:ok, site} = Plausible.Props.allow(site, ["amount", "logged_in", "is_customer"]) |
| conn = get(conn, "/#{site.domain}/settings/properties") |
|
|
| resp = html_response(conn, 200) |
| assert resp =~ "Attach custom properties" |
|
|
| assert element_exists?( |
| resp, |
| ~s|a[href="https://plausible.io/docs/custom-props/introduction"]| |
| ) |
|
|
| assert resp =~ "amount" |
| assert resp =~ "logged_in" |
| assert resp =~ "is_customer" |
| refute resp =~ "upgrade your subscription" |
| end |
|
|
| test "lists props with disallow actions", %{conn: conn, site: site} do |
| {:ok, site} = Plausible.Props.allow(site, ["amount", "logged_in", "is_customer"]) |
| conn = get(conn, "/#{site.domain}/settings/properties") |
| resp = html_response(conn, 200) |
|
|
| for p <- site.allowed_event_props do |
| assert element_exists?( |
| resp, |
| ~s/button[phx-click="disallow-prop"][phx-value-prop=#{p}]#disallow-prop-#{p}/ |
| ) |
| end |
| end |
|
|
| test "if no props are allowed, a proper info is displayed", %{conn: conn, site: site} do |
| conn = get(conn, "/#{site.domain}/settings/properties") |
| resp = html_response(conn, 200) |
| assert resp =~ "Create a custom property" |
| end |
|
|
| test "if props are enabled, no info about missing props is displayed", %{ |
| conn: conn, |
| site: site |
| } do |
| {:ok, site} = Plausible.Props.allow(site, ["amount", "logged_in", "is_customer"]) |
| conn = get(conn, "/#{site.domain}/settings/properties") |
| resp = html_response(conn, 200) |
| refute resp =~ "Create a custom property" |
| end |
|
|
| test "add property button is rendered", %{conn: conn, site: site} do |
| conn = get(conn, "/#{site.domain}/settings/properties") |
| resp = html_response(conn, 200) |
| assert element_exists?(resp, ~s/button[phx-click="add-prop"]/) |
| end |
|
|
| test "search props input is rendered", %{conn: conn, site: site} do |
| {:ok, site} = Plausible.Props.allow(site, ["amount", "logged_in", "is_customer"]) |
| conn = get(conn, "/#{site.domain}/settings/properties") |
| resp = html_response(conn, 200) |
| assert element_exists?(resp, ~s/input[type="text"]#filter-text/) |
| assert element_exists?(resp, ~s/form[phx-change="filter"]#filter-form/) |
| end |
| end |
|
|
| on_ee do |
| describe "GET /:domain/settings/properties - consolidated views" do |
| setup [:create_user, :create_team, :log_in] |
|
|
| setup %{team: team} = context do |
| new_site(team: team) |
| new_site(team: team) |
|
|
| {:ok, Map.put(context, :consolidated_view, new_consolidated_view(team))} |
| end |
|
|
| test "lists existing props and renders links", %{ |
| conn: conn, |
| consolidated_view: consolidated_view |
| } do |
| {:ok, consolidated_view} = |
| Plausible.Props.allow(consolidated_view, ["amount", "logged_in", "is_customer"]) |
|
|
| conn = get(conn, "/#{consolidated_view.domain}/settings/properties") |
|
|
| resp = html_response(conn, 200) |
| assert resp =~ "Attach custom properties" |
|
|
| assert element_exists?( |
| resp, |
| ~s|a[href="https://plausible.io/docs/custom-props/introduction"]| |
| ) |
|
|
| assert resp =~ "amount" |
| assert resp =~ "logged_in" |
| assert resp =~ "is_customer" |
| refute resp =~ "upgrade your subscription" |
| end |
|
|
| test "if no props are allowed, a proper info is displayed", %{ |
| conn: conn, |
| consolidated_view: consolidated_view |
| } do |
| conn = get(conn, "/#{consolidated_view.domain}/settings/properties") |
| resp = html_response(conn, 200) |
| assert resp =~ "Create a custom property" |
| end |
|
|
| test "add property button and search input are rendered", %{ |
| conn: conn, |
| consolidated_view: consolidated_view |
| } do |
| {:ok, consolidated_view} = |
| Plausible.Props.allow(consolidated_view, ["amount", "logged_in", "is_customer"]) |
|
|
| conn = get(conn, "/#{consolidated_view.domain}/settings/properties") |
| resp = html_response(conn, 200) |
| assert element_exists?(resp, ~s/button[phx-click="add-prop"]/) |
| assert element_exists?(resp, ~s/input[type="text"]#filter-text/) |
| assert element_exists?(resp, ~s/form[phx-change="filter"]#filter-form/) |
| end |
| end |
| end |
|
|
| describe "PropsSettings live view" do |
| setup [:create_user, :log_in, :create_site] |
|
|
| test "allows dashboard toggle", %{conn: conn, site: site} do |
| lv = get_liveview(conn, site) |
| lv |> element("#feature-props-toggle button") |> render_click() |
| assert render(lv) =~ "Custom Properties are now hidden from your dashboard" |
| assert Plausible.Billing.Feature.Props.opted_out?(Plausible.Repo.reload!(site)) |
| lv |> element("#feature-props-toggle button") |> render_click() |
| assert render(lv) =~ "Custom Properties are now visible again on your dashboard" |
| refute Plausible.Billing.Feature.Props.opted_out?(Plausible.Repo.reload!(site)) |
| end |
|
|
| test "allows prop removal", %{conn: conn, site: site} do |
| {:ok, site} = Plausible.Props.allow(site, ["amount", "logged_in"]) |
| {lv, html} = get_liveview(conn, site, with_html?: true) |
|
|
| assert html =~ "amount" |
| assert html =~ "logged_in" |
|
|
| html = lv |> element(~s/button#disallow-prop-amount/) |> render_click() |
|
|
| refute html =~ "amount" |
| assert html =~ "logged_in" |
|
|
| html = get(conn, "/#{site.domain}/settings/properties") |> html_response(200) |
|
|
| refute html =~ "amount" |
| assert html =~ "logged_in" |
| end |
|
|
| test "allows props filtering / search", %{conn: conn, site: site} do |
| {:ok, site} = Plausible.Props.allow(site, ["amount", "logged_in", "is_customer"]) |
| {lv, html} = get_liveview(conn, site, with_html?: true) |
|
|
| assert html =~ to_string("amount") |
| assert html =~ to_string("logged_in") |
| assert html =~ to_string("is_customer") |
|
|
| html = type_into_search(lv, "is_customer") |
|
|
| refute html =~ to_string("amount") |
| refute html =~ to_string("logged_in") |
| assert html =~ to_string("is_customer") |
| end |
|
|
| test "allows resetting filter text via backspace icon", %{conn: conn, site: site} do |
| {:ok, site} = Plausible.Props.allow(site, ["amount", "logged_in", "is_customer"]) |
| {lv, html} = get_liveview(conn, site, with_html?: true) |
|
|
| refute element_exists?(html, ~s/svg[phx-click="reset-filter-text"]#reset-filter/) |
|
|
| html = type_into_search(lv, to_string("is_customer")) |
|
|
| assert element_exists?(html, ~s/svg[phx-click="reset-filter-text"]#reset-filter/) |
|
|
| html = lv |> element(~s/svg#reset-filter/) |> render_click() |
|
|
| assert html =~ to_string("is_customer") |
| assert html =~ to_string("amount") |
| assert html =~ to_string("logged_in") |
| end |
|
|
| test "allows resetting filter text via no match link", %{conn: conn, site: site} do |
| {:ok, site} = Plausible.Props.allow(site, ["amount", "logged_in", "is_customer"]) |
| lv = get_liveview(conn, site) |
| html = type_into_search(lv, "Definitely this is not going to render any matches") |
|
|
| assert html =~ "No properties found for this site. Please refine or" |
| assert html =~ "reset your search" |
|
|
| assert element_exists?(html, ~s/a[phx-click="reset-filter-text"]#reset-filter-hint/) |
| html = lv |> element(~s/a#reset-filter-hint/) |> render_click() |
|
|
| refute html =~ "No properties found for this site. Please refine or" |
| end |
|
|
| test "clicking Add Property button renders the form view", %{conn: conn, site: site} do |
| lv = get_liveview(conn, site) |
| html = lv |> element(~s/button[phx-click="add-prop"]/) |> render_click() |
|
|
| assert html =~ "Add property for #{site.domain}" |
|
|
| assert element_exists?( |
| html, |
| ~s/div#props-form form[phx-submit="allow-prop"][phx-click-away="cancel-allow-prop"]/ |
| ) |
| end |
| end |
|
|
| defp get_liveview(conn, site, opts \\ []) do |
| conn = assign(conn, :live_module, PlausibleWeb.Live.PropsSettings) |
| {:ok, lv, html} = live(conn, "/#{site.domain}/settings/properties") |
|
|
| if Keyword.get(opts, :with_html?) do |
| {lv, html} |
| else |
| lv |
| end |
| end |
|
|
| defp type_into_search(lv, text) do |
| lv |
| |> element("form#filter-form") |
| |> render_change(%{ |
| "_target" => ["filter-text"], |
| "filter-text" => "#{text}" |
| }) |
| end |
| end |
|
|