analytics/test/plausible_web/live/props_settings/form_test.exs
hq1 0822bc61df
Props Settings UI to match Goals Settings (#3322)
* Add hint to creatable ComboBoxes without suggestions available

* Load external resources once in funnel settings

* Load external resources once in goal settings

* Make Custom Props Settings UI match Goal Settings

* Remove unnecessary goals query

This should be done only once in the live view

* Remove funnels feature flag

* fixup

* Make the modal scrollable

* By default, focus first suggestion for creatables

* Add sample props to seeds

* Load all suggestions asynchronously, unless `Mix.env == :test`

* ComboBox: Fix inconsistent suggestions

We require "Create ..." element to be only focused
when there are no suggestions available.
This causes some issues, depending on the state,
the least focusable index might be either 0 ("Create...")
or 1. This patch addresses all the quirks with focus.

* Fix ComboBox max results message

So that AlpineJS doesn't think it's a focusable
option.

* Keep the state up to date when changing props

* Update seeds with sensible prop names

* Make escape work for closing combobox suggestions

Co-authored-by: Uku Taht <Uku.taht@gmail.com>

* Revert "Make escape work for closing combobox suggestions"

This reverts commit 306866d2a1.

@ukutaht unfortunately this makes it impossible to select
an suggestion.

* Revert "Revert "Make escape work for closing combobox suggestions""

This reverts commit 4844857812.

* Make ESC great again

* Improve readability

---------

Co-authored-by: Uku Taht <Uku.taht@gmail.com>
2023-09-13 14:55:29 +02:00

157 lines
4.9 KiB
Elixir

defmodule PlausibleWeb.Live.PropsSettings.FormTest do
use PlausibleWeb.ConnCase, async: true
import Phoenix.LiveViewTest
import Plausible.Test.Support.HTML
describe "Props submission" do
setup [:create_user, :log_in, :create_site]
test "renders form fields", %{conn: conn, site: site} do
lv = get_liveview(conn, site)
html = render(lv)
assert element_exists?(html, "form input[type=text][name=display-prop_input]")
assert element_exists?(html, "form input[type=hidden][name=prop]")
end
test "renders error on empty submission", %{conn: conn, site: site} do
lv = get_liveview(conn, site)
html = lv |> element("form") |> render_submit()
assert html =~ "must be between 1 and 300 characters"
end
test "renders error on whitespace submission", %{conn: conn, site: site} do
lv = get_liveview(conn, site)
html = lv |> element("form") |> render_submit(%{prop: " "})
assert html =~ "must be between 1 and 300 characters"
end
test "renders 'Create' suggestion", %{conn: conn, site: site} do
lv = get_liveview(conn, site)
type_into_combo(lv, "#prop_input", "Hello world")
html = render(lv)
assert text_of_element(html, "#dropdown-prop_input-option-0 a") == ~s/Create "Hello world"/
end
test "clicking suggestion fills out input", %{conn: conn, site: site} = context do
seed_props(context)
lv = get_liveview(conn, site)
type_into_combo(lv, "#prop_input", "amo")
doc =
lv
|> element(~s/ul#dropdown-prop_input li#dropdown-prop_input-option-1 a/)
|> render_click()
assert element_exists?(doc, ~s/input[type="hidden"][value="amount"]/)
end
test "allowing a single property", %{conn: conn, site: site} do
{parent, lv} = get_liveview(conn, site, with_parent?: true)
refute render(parent) =~ "foobarbaz"
lv |> element("form") |> render_submit(%{prop: "foobarbaz"})
parent_html = render(parent)
assert text_of_element(parent_html, "#prop-0") == "foobarbaz"
site = Plausible.Repo.reload!(site)
assert site.allowed_event_props == ["foobarbaz"]
end
test "allowing existing properties", %{conn: conn, site: site} = context do
seed_props(context)
{parent, lv} = get_liveview(conn, site, with_parent?: true)
parent_html = render(parent)
refute element_exists?(parent_html, "#prop-0")
refute element_exists?(parent_html, "#prop-1")
refute element_exists?(parent_html, "#prop-2")
lv
|> element(~s/button[phx-click="allow-existing-props"]/)
|> render_click()
parent_html = render(parent)
assert text_of_element(parent_html, "#prop-0") == "amount"
assert text_of_element(parent_html, "#prop-1") == "logged_in"
assert text_of_element(parent_html, "#prop-2") == "is_customer"
site = Plausible.Repo.reload!(site)
assert site.allowed_event_props == ["amount", "logged_in", "is_customer"]
end
test "does not show allow existing props button when there are no events with props", %{
conn: conn,
site: site
} do
lv = get_liveview(conn, site)
refute element_exists?(render(lv), ~s/button[phx-click="allow-existing-props"]/)
end
test "does not show allow existing props button after adding all suggestions",
%{
conn: conn,
site: site
} = context do
seed_props(context)
conn
|> get_liveview(site)
|> element(~s/button[phx-click="allow-existing-props"]/)
|> render_click()
site = Plausible.Repo.reload!(site)
assert site.allowed_event_props == ["amount", "logged_in", "is_customer"]
html =
conn
|> get_liveview(site)
|> render()
refute element_exists?(html, ~s/button[phx-click="allow-existing-props"]/)
end
end
defp seed_props(%{site: site}) do
populate_stats(site, [
build(:event,
name: "Payment",
"meta.key": ["amount"],
"meta.value": ["500"]
),
build(:event,
name: "Payment",
"meta.key": ["amount", "logged_in"],
"meta.value": ["100", "false"]
),
build(:event,
name: "Payment",
"meta.key": ["amount", "is_customer"],
"meta.value": ["100", "false"]
)
])
:ok
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")
lv |> element(~s/button[phx-click="add-prop"]/) |> render_click()
assert form_view = find_live_child(lv, "props-form")
if opts[:with_parent?] do
{lv, form_view}
else
form_view
end
end
defp type_into_combo(lv, id, text) do
lv
|> element("input##{id}")
|> render_change(%{
"_target" => ["display-#{id}"],
"display-#{id}" => "#{text}"
})
end
end