mirror of
https://github.com/plausible/analytics.git
synced 2024-11-23 03:04:43 +03:00
39aa81a16f
* Create a stub of site settings section for imports and exports * Use legacy site import indication to determine UA import handling * Add provisional logos for upcoming import sources * Stub basics of import page * Add very rudimentary support for multiple UA imports * Implement imports list as live view * Add support for opening LV modal from backend and closing from frontend * Introduce notion of themes to `button` and `button_link` components * Add confirmation modal on deleting import * Swap GA4 logo * Implement disabled state support for `button_link` component * Disable export and non-implemented import sources * Use native starts start date for upper boundary of import time range * Ensure integrations view uses legacy UA import flow * Remove unnecessary preload in SiteController * Remove unnecessary exception for legacy imports * Move API controller stats tests under PlausibleWeb * Test listing imports * Add test for explicit listener setup * Add tests for legacy flag state in UA importer * Add test for purging legacy import data * Add tests for `Sites.native_stats_start_date` * Test forgetting imports * Add `Stats.Clickhouse.imported_pageview_counts/1` and fix test flakiness * Show page view counts on imports list * Add tests for static imports and exports view * Adjust button look slightly * Use `case` instead of `cond` * Make feature flag customisable per site * Fix buttons and empty state styling * Add another import to seeds * Use JS confirm dialog instead of modal for deletion confirmations * Revert "Add support for opening LV modal from backend and closing from frontend" This reverts commit 260e6c753032b451542e24be9edc2118790b5a00. * Default `legacy` to false when inserting new import jobs * Drop `method` attribute from `button_link` and `unstyled_link` components
255 lines
8.1 KiB
Elixir
255 lines
8.1 KiB
Elixir
defmodule Plausible.Workers.ImportAnalyticsTest do
|
|
use Plausible.DataCase
|
|
use Bamboo.Test
|
|
|
|
alias Plausible.Imported.SiteImport
|
|
alias Plausible.Workers.ImportAnalytics
|
|
|
|
require Plausible.Imported.SiteImport
|
|
|
|
@moduletag capture_log: true
|
|
|
|
describe "perform/1" do
|
|
setup do
|
|
%{
|
|
import_opts: [
|
|
start_date: Timex.today() |> Timex.shift(days: -7),
|
|
end_date: Timex.today()
|
|
]
|
|
}
|
|
end
|
|
|
|
test "updates site import after successful import", %{
|
|
import_opts: import_opts
|
|
} do
|
|
user = insert(:user, trial_expiry_date: Timex.today() |> Timex.shift(days: 1))
|
|
site = insert(:site, members: [user])
|
|
|
|
{:ok, job} = Plausible.Imported.NoopImporter.new_import(site, user, import_opts)
|
|
|
|
assert [%{status: SiteImport.pending()}] = Plausible.Imported.list_all_imports(site)
|
|
|
|
# before_start callback triggered
|
|
assert_received {:before_start, import_id}
|
|
|
|
assert :ok =
|
|
job
|
|
|> Repo.reload!()
|
|
|> ImportAnalytics.perform()
|
|
|
|
assert [%{id: ^import_id, status: SiteImport.completed()}] =
|
|
Plausible.Imported.list_all_imports(site)
|
|
|
|
# on_success callback triggered
|
|
assert_received {:on_success, ^import_id}
|
|
end
|
|
|
|
test "clears stats_start_date field for the site after successful import", %{
|
|
import_opts: import_opts
|
|
} do
|
|
user = insert(:user, trial_expiry_date: Timex.today() |> Timex.shift(days: 1))
|
|
site = insert(:site, members: [user], stats_start_date: ~D[2005-01-01])
|
|
|
|
{:ok, job} = Plausible.Imported.NoopImporter.new_import(site, user, import_opts)
|
|
|
|
assert :ok =
|
|
job
|
|
|> Repo.reload!()
|
|
|> ImportAnalytics.perform()
|
|
|
|
site = Repo.reload!(site)
|
|
assert site.stats_start_date == nil
|
|
assert Plausible.Sites.stats_start_date(site) == import_opts[:start_date]
|
|
assert Repo.reload!(site).stats_start_date == import_opts[:start_date]
|
|
end
|
|
|
|
test "sends email to owner after successful import", %{import_opts: import_opts} do
|
|
user = insert(:user, trial_expiry_date: Timex.today() |> Timex.shift(days: 1))
|
|
site = insert(:site, members: [user])
|
|
|
|
{:ok, job} = Plausible.Imported.NoopImporter.new_import(site, user, import_opts)
|
|
|
|
assert :ok =
|
|
job
|
|
|> Repo.reload!()
|
|
|> ImportAnalytics.perform()
|
|
|
|
assert_email_delivered_with(
|
|
to: [user],
|
|
subject: "Noop data imported for #{site.domain}"
|
|
)
|
|
end
|
|
|
|
test "updates site import record after failed import", %{import_opts: import_opts} do
|
|
user = insert(:user, trial_expiry_date: Timex.today() |> Timex.shift(days: 1))
|
|
site = insert(:site, members: [user])
|
|
import_opts = Keyword.put(import_opts, :error, true)
|
|
|
|
{:ok, job} = Plausible.Imported.NoopImporter.new_import(site, user, import_opts)
|
|
|
|
assert {:discard, "Something went wrong"} =
|
|
job
|
|
|> Repo.reload!()
|
|
|> ImportAnalytics.perform()
|
|
|
|
assert [%{status: SiteImport.failed()}] = Plausible.Imported.list_all_imports(site)
|
|
end
|
|
|
|
test "clears any orphaned data during import", %{import_opts: import_opts} do
|
|
user = insert(:user, trial_expiry_date: Timex.today() |> Timex.shift(days: 1))
|
|
site = insert(:site, members: [user])
|
|
import_opts = Keyword.put(import_opts, :error, true)
|
|
|
|
{:ok, job} = Plausible.Imported.NoopImporter.new_import(site, user, import_opts)
|
|
|
|
populate_stats(site, [
|
|
build(:imported_visitors, import_id: job.args.import_id, pageviews: 10)
|
|
])
|
|
|
|
assert {:discard, _} =
|
|
job
|
|
|> Repo.reload!()
|
|
|> ImportAnalytics.perform()
|
|
|
|
assert eventually(fn ->
|
|
count = Plausible.Stats.Clickhouse.imported_pageview_count(site)
|
|
{count == 0, count}
|
|
end)
|
|
|
|
# on_failure callback triggered
|
|
assert_received {:on_failure, _import_id}
|
|
end
|
|
|
|
test "sends email to owner after failed import", %{import_opts: import_opts} do
|
|
user = insert(:user, trial_expiry_date: Timex.today() |> Timex.shift(days: 1))
|
|
site = insert(:site, members: [user])
|
|
import_opts = Keyword.put(import_opts, :error, true)
|
|
|
|
{:ok, job} = Plausible.Imported.NoopImporter.new_import(site, user, import_opts)
|
|
|
|
assert {:discard, _} =
|
|
job
|
|
|> Repo.reload!()
|
|
|> ImportAnalytics.perform()
|
|
|
|
assert_email_delivered_with(
|
|
to: [user],
|
|
subject: "Noop import failed for #{site.domain}"
|
|
)
|
|
end
|
|
end
|
|
|
|
describe "perform/1 notifications" do
|
|
setup do
|
|
on_exit(fn ->
|
|
Ecto.Adapters.SQL.Sandbox.unboxed_run(Plausible.Repo, fn ->
|
|
Repo.delete_all(Plausible.Site)
|
|
Repo.delete_all(Plausible.Auth.User)
|
|
end)
|
|
|
|
:ok
|
|
end)
|
|
|
|
%{
|
|
import_opts: [
|
|
start_date: Timex.today() |> Timex.shift(days: -7),
|
|
end_date: Timex.today()
|
|
]
|
|
}
|
|
end
|
|
|
|
test "sends oban notification to calling process on completion when instructed", %{
|
|
import_opts: import_opts
|
|
} do
|
|
Ecto.Adapters.SQL.Sandbox.unboxed_run(Plausible.Repo, fn ->
|
|
user = insert(:user, trial_expiry_date: Timex.today() |> Timex.shift(days: 1))
|
|
site = insert(:site, members: [user])
|
|
import_opts = Keyword.put(import_opts, :listen?, true)
|
|
|
|
{:ok, job} = Plausible.Imported.NoopImporter.new_import(site, user, import_opts)
|
|
import_id = job.args[:import_id]
|
|
|
|
job
|
|
|> Repo.reload!()
|
|
|> ImportAnalytics.perform()
|
|
|
|
assert_receive {:notification, :analytics_imports_jobs, %{"complete" => ^import_id}}
|
|
end)
|
|
end
|
|
|
|
test "sends oban notification to calling process on permanent failure when instructed", %{
|
|
import_opts: import_opts
|
|
} do
|
|
Ecto.Adapters.SQL.Sandbox.unboxed_run(Plausible.Repo, fn ->
|
|
user = insert(:user, trial_expiry_date: Timex.today() |> Timex.shift(days: 1))
|
|
site = insert(:site, members: [user])
|
|
|
|
import_opts =
|
|
import_opts
|
|
|> Keyword.put(:listen?, true)
|
|
|> Keyword.put(:error, true)
|
|
|
|
{:ok, job} = Plausible.Imported.NoopImporter.new_import(site, user, import_opts)
|
|
import_id = job.args[:import_id]
|
|
|
|
job
|
|
|> Repo.reload!()
|
|
|> ImportAnalytics.perform()
|
|
|
|
assert_receive {:notification, :analytics_imports_jobs, %{"fail" => ^import_id}}
|
|
end)
|
|
end
|
|
|
|
test "sends oban notification to calling process on transient failure when instructed", %{
|
|
import_opts: import_opts
|
|
} do
|
|
Ecto.Adapters.SQL.Sandbox.unboxed_run(Plausible.Repo, fn ->
|
|
user = insert(:user, trial_expiry_date: Timex.today() |> Timex.shift(days: 1))
|
|
site = insert(:site, members: [user])
|
|
|
|
import_opts =
|
|
import_opts
|
|
|> Keyword.put(:listen?, true)
|
|
|> Keyword.put(:crash, true)
|
|
|
|
{:ok, job} = Plausible.Imported.NoopImporter.new_import(site, user, import_opts)
|
|
import_id = job.args[:import_id]
|
|
|
|
site_import = Repo.get(Plausible.Imported.SiteImport, import_id)
|
|
|
|
# emulate oban error handler
|
|
try do
|
|
job
|
|
|> Repo.reload!()
|
|
|> ImportAnalytics.perform()
|
|
rescue
|
|
_ -> ImportAnalytics.import_fail_transient(site_import)
|
|
end
|
|
|
|
assert_receive {:notification, :analytics_imports_jobs, %{"transient_fail" => ^import_id}}
|
|
end)
|
|
end
|
|
|
|
test "sends oban notification to calling process on completion when listener setup separately",
|
|
%{
|
|
import_opts: import_opts
|
|
} do
|
|
Ecto.Adapters.SQL.Sandbox.unboxed_run(Plausible.Repo, fn ->
|
|
user = insert(:user, trial_expiry_date: Timex.today() |> Timex.shift(days: 1))
|
|
site = insert(:site, members: [user])
|
|
|
|
{:ok, job} = Plausible.Imported.NoopImporter.new_import(site, user, import_opts)
|
|
import_id = job.args[:import_id]
|
|
|
|
:ok = Plausible.Imported.Importer.listen()
|
|
|
|
job
|
|
|> Repo.reload!()
|
|
|> ImportAnalytics.perform()
|
|
|
|
assert_receive {:notification, :analytics_imports_jobs, %{"complete" => ^import_id}}
|
|
end)
|
|
end
|
|
end
|
|
end
|