prop/test/microwaveprop_web/live/import_live_test.exs
Graham McIntire 959f3a3f69
Some checks failed
Build and Push / Build and Push Docker Image (push) Failing after 4m31s
Fix LiveView crashes and stabilize test suite
2026-08-01 09:26:47 -05:00

147 lines
4.2 KiB
Elixir

defmodule MicrowavepropWeb.ImportLiveTest do
use MicrowavepropWeb.ConnCase, async: true
import Phoenix.LiveViewTest
alias Microwaveprop.Radio.ImportRun
alias Microwaveprop.Repo
defp log_in_submitter(conn, email) do
user = Microwaveprop.AccountsFixtures.user_fixture(%{email: email})
log_in_user(conn, user)
end
defp insert_run(attrs) do
defaults = %{
submitter_email: "importer@example.com",
rows: %{"rows" => [], "refinement_ids" => []},
total_rows: 10,
processed_rows: 0,
imported_count: 0,
refined_count: 0,
error_count: 0,
errors: %{},
status: "pending"
}
{:ok, run} =
%ImportRun{}
|> ImportRun.changeset(Map.merge(defaults, attrs))
|> Repo.insert()
run
end
describe "mount" do
test "renders the initial state of a pending import", %{conn: conn} do
run = insert_run(%{total_rows: 25, submitter_email: "alice@example.com"})
conn = log_in_submitter(conn, run.submitter_email)
{:ok, _lv, html} = live(conn, ~p"/imports/#{run.id}")
assert html =~ "Contact Import"
assert html =~ "alice@example.com"
assert html =~ "25"
assert html =~ ~r/id="import-status-badge"[^>]*>\s*Pending/
assert html =~ ~s(id="import-progress-bar")
assert html =~ ~s(id="import-imported-count")
assert html =~ ~s(id="import-refined-count")
assert html =~ ~s(id="import-error-count")
end
test "redirects to / with a flash when the import is not found", %{conn: conn} do
missing_id = Ecto.UUID.generate()
assert {:error, {:live_redirect, %{to: "/", flash: flash}}} =
live(conn, ~p"/imports/#{missing_id}")
assert flash["error"] =~ "Import not found"
end
test "redirects to / for an obviously bad id", %{conn: conn} do
assert {:error, {:live_redirect, %{to: "/"}}} =
live(conn, ~p"/imports/not-a-uuid")
end
end
describe "live updates" do
test "updates counters when an import_progress message is broadcast", %{conn: conn} do
run = insert_run(%{total_rows: 100})
conn = log_in_submitter(conn, run.submitter_email)
{:ok, lv, _html} = live(conn, ~p"/imports/#{run.id}")
updated = %{
run
| processed_rows: 50,
imported_count: 48,
refined_count: 1,
error_count: 1,
status: "running",
errors: %{"7" => ["band is invalid"]}
}
Phoenix.PubSub.broadcast(
Microwaveprop.PubSub,
"csv_import:#{run.id}",
{:import_progress, run.id, updated}
)
html = render(lv)
assert html =~ ~r/id="import-imported-count"[^>]*>\s*48/
assert html =~ ~r/id="import-refined-count"[^>]*>\s*1/
assert html =~ ~r/id="import-error-count"[^>]*>\s*1/
assert html =~ ~r/id="import-status-badge"[^>]*>\s*Running/
assert html =~ "band is invalid"
end
test "shows the complete UI once status flips to complete", %{conn: conn} do
run = insert_run(%{total_rows: 3})
conn = log_in_submitter(conn, run.submitter_email)
{:ok, lv, _html} = live(conn, ~p"/imports/#{run.id}")
done = %{
run
| processed_rows: 3,
imported_count: 3,
status: "complete",
completed_at: DateTime.utc_now()
}
Phoenix.PubSub.broadcast(
Microwaveprop.PubSub,
"csv_import:#{run.id}",
{:import_progress, run.id, done}
)
html = render(lv)
assert html =~ "Import complete"
assert html =~ ~s(id="import-complete-panel")
assert html =~ "View contacts"
assert html =~ ~r/id="import-status-badge"[^>]*>\s*Complete/
end
test "shows the errors section when error_count > 0", %{conn: conn} do
run =
insert_run(%{
total_rows: 2,
processed_rows: 2,
imported_count: 1,
error_count: 1,
status: "complete",
errors: %{"2" => ["band is invalid"]}
})
conn = log_in_submitter(conn, run.submitter_email)
{:ok, _lv, html} = live(conn, ~p"/imports/#{run.id}")
assert html =~ ~s(id="import-errors-section")
assert html =~ "Row 2"
assert html =~ "band is invalid"
end
end
end