| defmodule PlausibleWeb.Live.CustomerSupportTest do |
| use PlausibleWeb.ConnCase, async: false |
|
|
| @moduletag :ee_only |
|
|
| on_ee do |
| @cs_index Routes.customer_support_path(PlausibleWeb.Endpoint, :index) |
|
|
| import Phoenix.LiveViewTest |
|
|
| alias Plausible.Auth.SSO |
|
|
| describe "unauthenticated" do |
| test "not allowed if not logged in", %{conn: conn} do |
| conn = get(conn, @cs_index) |
| assert response(conn, 403) == "Not allowed" |
| end |
| end |
|
|
| describe "authenticated regular user" do |
| test "not allowed if not superadmin", %{conn: conn} do |
| conn = get(conn, @cs_index) |
| assert response(conn, 403) == "Not allowed" |
| end |
| end |
|
|
| describe "authenticated superadmin" do |
| setup [:create_user, :log_in, :create_site] |
|
|
| setup %{user: user} do |
| patch_env(:super_admin_user_ids, [user.id]) |
| end |
|
|
| test "lists resources", %{conn: conn, site: site, user: user} do |
| conn = get(conn, @cs_index) |
| resp = html_response(conn, 200) |
| team = team_of(user) |
| consolidated_site = new_site(owner: user, consolidated: true) |
| assert_search_result(resp, "site", site.id) |
| assert_search_result(resp, "team", team.id) |
| assert_search_result(resp, "user", user.id) |
| refute_search_result(resp, "site", consolidated_site.id) |
| end |
|
|
| test "filters as you type", %{conn: conn, site: site, user: user} do |
| site2 = new_site(owner: user, domain: "hello.example.com") |
| {:ok, lv, _html} = live(conn, @cs_index) |
| type_into_input(lv, "filter-text", "hello") |
|
|
| html = render(lv) |
|
|
| assert_search_result(html, "site", site2.id) |
| refute_search_result(html, "site", site.id) |
|
|
| type_into_input(lv, "filter-text", "user:hello") |
| html = render(lv) |
|
|
| refute_search_result(html, "site", site2.id) |
|
|
| type_into_input(lv, "filter-text", "site:hello") |
| html = render(lv) |
|
|
| assert_search_result(html, "site", site2.id) |
| end |
|
|
| test "search teams by name", %{conn: conn} do |
| team1 = new_user(team: [name: "Team One"]) |> team_of() |
| team2 = new_user(team: [name: "Team Two"]) |> team_of() |
| team3 = new_user(team: [name: "Team Three"]) |> team_of() |
|
|
| {:ok, lv, _html} = live(conn, @cs_index) |
|
|
| type_into_input(lv, "filter-text", "team:Team") |
| html = render(lv) |
|
|
| assert_search_result(html, "team", team1.id) |
| assert_search_result(html, "team", team2.id) |
| assert_search_result(html, "team", team3.id) |
| end |
|
|
| test "search teams by partial name", %{conn: conn} do |
| team1 = new_user(team: [name: "Team One"]) |> team_of() |
| team2 = new_user(team: [name: "Team Two"]) |> team_of() |
| team3 = new_user(team: [name: "Team Three"]) |> team_of() |
|
|
| {:ok, lv, _html} = live(conn, @cs_index) |
|
|
| type_into_input(lv, "filter-text", "team:Team T") |
| html = render(lv) |
|
|
| refute_search_result(html, "team", team1.id) |
| assert_search_result(html, "team", team2.id) |
| assert_search_result(html, "team", team3.id) |
| end |
|
|
| test "search teams with subscription filter", %{conn: conn} do |
| team1 = new_user(team: [name: "Team One"]) |> team_of() |
| team2 = new_user(team: [name: "Team Two"]) |> subscribe_to_growth_plan() |> team_of() |
| team3 = new_user(team: [name: "Team Three"]) |> team_of() |
|
|
| {:ok, lv, _html} = live(conn, @cs_index) |
|
|
| type_into_input(lv, "filter-text", "team:Team T +sub") |
| html = render(lv) |
|
|
| refute_search_result(html, "team", team1.id) |
| assert_search_result(html, "team", team2.id) |
| refute_search_result(html, "team", team3.id) |
| end |
|
|
| test "search teams with sso filter before integration", %{conn: conn} do |
| team1 = new_user(team: [name: "Team One"]) |> team_of() |
| team2 = new_user(team: [name: "Team Two"]) |> subscribe_to_growth_plan() |> team_of() |
| team3 = new_user(team: [name: "Team Three"]) |> team_of() |
|
|
| {:ok, lv, _html} = live(conn, @cs_index) |
|
|
| type_into_input(lv, "filter-text", "team:Team T +sso") |
| html = render(lv) |
| refute_search_result(html, "team", team1.id) |
| refute_search_result(html, "team", team2.id) |
| refute_search_result(html, "team", team3.id) |
| end |
|
|
| test "search teams with sso filter after integration", %{conn: conn} do |
| team1 = new_user(team: [name: "Team One"]) |> team_of() |
| team2 = new_user(team: [name: "Team Two"]) |> subscribe_to_growth_plan() |> team_of() |
| team3 = new_user(team: [name: "Team Three"]) |> team_of() |
|
|
| integration = SSO.initiate_saml_integration(team2) |
| SSO.Domains.add(integration, "some-sso.example.com") |
| SSO.initiate_saml_integration(team3) |
|
|
| {:ok, lv, _html} = live(conn, @cs_index) |
|
|
| type_into_input(lv, "filter-text", "team:Team T +sso") |
| html = render(lv) |
| refute_search_result(html, "team", team1.id) |
| assert_search_result(html, "team", team2.id) |
| assert_search_result(html, "team", team3.id) |
| end |
|
|
| test "search teams by sso domain", %{conn: conn} do |
| team1 = new_user(team: [name: "Team One"]) |> team_of() |
| team2 = new_user(team: [name: "Team Two"]) |> subscribe_to_growth_plan() |> team_of() |
| team3 = new_user(team: [name: "Team Three"]) |> team_of() |
|
|
| integration = SSO.initiate_saml_integration(team2) |
| SSO.Domains.add(integration, "some-sso.example.com") |
|
|
| {:ok, lv, _html} = live(conn, @cs_index) |
|
|
| type_into_input(lv, "filter-text", "team:some-sso +sso") |
| html = render(lv) |
|
|
| refute_search_result(html, "team", team1.id) |
| assert_search_result(html, "team", team2.id) |
| refute_search_result(html, "team", team3.id) |
| end |
|
|
| test "search teams by identifier", %{conn: conn} do |
| team1 = new_user(team: [name: "Team One"]) |> team_of() |
| team2 = new_user(team: [name: "Team Two"]) |> team_of() |
|
|
| {:ok, lv, _html} = live(conn, @cs_index) |
|
|
| type_into_input(lv, "filter-text", "team:#{team2.identifier}") |
| html = render(lv) |
|
|
| refute_search_result(html, "team", team1.id) |
| assert_search_result(html, "team", team2.id) |
| end |
|
|
| test "search sites by domain_changed_from", %{conn: conn, user: user} do |
| {:ok, site} = |
| new_site(domain: "old.example.com", owner: user) |
| |> Plausible.Site.Domain.change("new.example.net") |
|
|
| {:ok, lv, _html} = live(conn, @cs_index) |
|
|
| type_into_input(lv, "filter-text", "site:old") |
| html = render(lv) |
|
|
| assert_search_result(html, "site", site.id) |
| end |
|
|
| test "search sites by tracker script ID", %{conn: conn} do |
| site = new_site() |
|
|
| tracker_script_configuration = |
| PlausibleWeb.Tracker.get_or_create_tracker_script_configuration!(site) |
|
|
| {:ok, lv, _html} = live(conn, @cs_index) |
|
|
| type_into_input(lv, "filter-text", "site:#{tracker_script_configuration.id}") |
|
|
| html = render(lv) |
|
|
| assert_search_result(html, "site", site.id) |
| end |
| end |
|
|
| defp assert_search_result(doc, type, id) do |
| assert link = find(doc, ~s|a[data-test-type="#{type}"][data-test-id="#{id}"]|) |
|
|
| assert text_of_attr(link, "href") == |
| apply(Routes, :"customer_support_#{type}_path", [ |
| PlausibleWeb.Endpoint, |
| :show, |
| id |
| ]) |
| end |
|
|
| defp refute_search_result(doc, type, id) do |
| refute element_exists?(doc, ~s|a[data-test-type="#{type}"][data-test-id="#{id}"]|) |
| end |
|
|
| defp type_into_input(lv, id, text) do |
| lv |
| |> element("form#filter-form") |
| |> render_change(%{id => text}) |
| end |
| end |
| end |
|
|