diff --git a/lib/plausible/imported.ex b/lib/plausible/imported.ex index 53ceda18fd14..14a758be9222 100644 --- a/lib/plausible/imported.ex +++ b/lib/plausible/imported.ex @@ -51,8 +51,10 @@ defmodule Plausible.Imported do @spec imported_custom_props() :: [String.t()] def imported_custom_props do - Plausible.Props.internal_keys() - |> Enum.map(&("event:props:" <> &1)) + # NOTE: Keep up to date with `Plausible.Props.internal_keys/1`, + # but _ignore_ unsupported keys. Currently, `search_query` is + # not supported in imported queries. + Enum.map(~w(url path), &("event:props:" <> &1)) end @spec goals_with_url() :: [String.t()] diff --git a/lib/plausible/props.ex b/lib/plausible/props.ex index c1e659a90689..25c9ca46b85b 100644 --- a/lib/plausible/props.ex +++ b/lib/plausible/props.ex @@ -16,7 +16,9 @@ defmodule Plausible.Props do @max_prop_value_length 2000 def max_prop_value_length, do: @max_prop_value_length + # NOTE: Keep up to date with `Plausible.Imported.imported_custom_props/0`. @internal_keys ~w(url path search_query) + @doc """ Lists prop keys used internally. diff --git a/test/plausible_web/controllers/api/external_stats_controller/query_imported_test.exs b/test/plausible_web/controllers/api/external_stats_controller/query_imported_test.exs index 82f87a9cb67c..0662f1f91ad2 100644 --- a/test/plausible_web/controllers/api/external_stats_controller/query_imported_test.exs +++ b/test/plausible_web/controllers/api/external_stats_controller/query_imported_test.exs @@ -481,6 +481,44 @@ defmodule PlausibleWeb.Api.ExternalStatsController.QueryImportedTest do end end + test "gracefully ignores unsupported WP Search Queries goal for imported data", %{ + conn: conn, + site: site + } do + insert(:goal, event_name: "WP Search Queries", site: site) + site_import = insert(:site_import, site: site) + + populate_stats(site, site_import.id, [ + build(:event, + name: "WP Search Queries", + "meta.key": ["search_query", "result_count"], + "meta.value": ["some phrase", "12"] + ), + build(:imported_custom_events, + name: "view_search_results", + visitors: 100, + events: 200 + ), + build(:imported_visitors, visitors: 9) + ]) + + conn = + post(conn, "/api/v2/query", %{ + "site_id" => site.domain, + "metrics" => ["visitors", "events", "conversion_rate"], + "date_range" => "all", + "dimensions" => ["event:props:search_query"], + "filters" => [ + ["is", "event:goal", ["WP Search Queries"]] + ], + "include" => %{"imports" => true} + }) + + assert json_response(conn, 200)["results"] == [ + %{"dimensions" => ["some phrase"], "metrics" => [1, 1, 100.0]} + ] + end + test "adds a warning when query params are not supported for imported data", %{ conn: conn, site: site diff --git a/test/plausible_web/controllers/api/stats_controller/custom_prop_breakdown_test.exs b/test/plausible_web/controllers/api/stats_controller/custom_prop_breakdown_test.exs index d916347897ab..729667d89283 100644 --- a/test/plausible_web/controllers/api/stats_controller/custom_prop_breakdown_test.exs +++ b/test/plausible_web/controllers/api/stats_controller/custom_prop_breakdown_test.exs @@ -1141,6 +1141,99 @@ defmodule PlausibleWeb.Api.StatsController.CustomPropBreakdownTest do describe "with imported data" do setup [:create_user, :log_in, :create_new_site] + test "gracefully ignores unsupported WP Search Queries goal for imported data", %{ + conn: conn, + site: site + } do + insert(:goal, event_name: "WP Search Queries", site: site) + site_import = insert(:site_import, site: site) + + populate_stats(site, site_import.id, [ + build(:event, + name: "WP Search Queries", + "meta.key": ["search_query", "result_count"], + "meta.value": ["some phrase", "12"] + ), + build(:imported_custom_events, + name: "view_search_results", + visitors: 100, + events: 200 + ), + build(:imported_visitors, visitors: 9) + ]) + + filters = Jason.encode!(%{goal: "WP Search Queries"}) + + conn = + get( + conn, + "/api/stats/#{site.domain}/custom-prop-values/search_query?period=day&with_imported=true&filters=#{filters}" + ) + + assert json_response(conn, 200)["results"] == [ + %{ + "visitors" => 1, + "name" => "some phrase", + "events" => 1, + "conversion_rate" => 100.0 + } + ] + end + + test "returns path breakdown for 404 goal", %{conn: conn, site: site} do + insert(:goal, event_name: "404", site: site) + site_import = insert(:site_import, site: site) + + populate_stats(site, site_import.id, [ + build(:event, + name: "404", + "meta.key": ["path"], + "meta.value": ["/some/path/first.bin"] + ), + build(:imported_custom_events, + name: "404", + visitors: 2, + events: 5, + path: "/some/path/first.bin" + ), + build(:imported_custom_events, + name: "404", + visitors: 5, + events: 10, + path: "/some/path/second.bin" + ), + build(:imported_custom_events, + name: "view_search_results", + visitors: 100, + events: 200 + ), + build(:imported_visitors, visitors: 9) + ]) + + filters = Jason.encode!(%{goal: "404"}) + + conn = + get( + conn, + "/api/stats/#{site.domain}/custom-prop-values/path?period=day&with_imported=true&filters=#{filters}" + ) + + assert json_response(conn, 200)["results"] == [ + %{ + "visitors" => 5, + "name" => "/some/path/second.bin", + "events" => 10, + "conversion_rate" => 50.0 + }, + %{ + "visitors" => 3, + "name" => "/some/path/first.bin", + "events" => 6, + "conversion_rate" => 30.0 + } + ] + end + for goal_name <- ["Outbound Link: Click", "File Download", "Cloaked Link: Click"] do test "returns url breakdown for #{goal_name} goal", %{conn: conn, site: site} do insert(:goal, event_name: unquote(goal_name), site: site)