berrypod/test/berrypod_web/live/admin/providers_test.exs
jamey 0853b6f528 share provider connection logic between setup wizard and providers form
Extract Products.connect_provider/2 that tests the connection, fetches
shop_id, creates the record, and enqueues sync. Both the setup wizard
and the providers form now use this shared function instead of
duplicating the flow. Also makes the products empty state context-aware
(distinguishes "no provider" from "provider connected but no products").

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 15:19:17 +00:00

282 lines
7.8 KiB
Elixir

defmodule BerrypodWeb.Admin.ProvidersTest do
use BerrypodWeb.ConnCase, async: false
import Phoenix.LiveViewTest
import Berrypod.AccountsFixtures
import Berrypod.ProductsFixtures
import Mox
alias Berrypod.Providers.MockProvider
setup :verify_on_exit!
setup do
user = user_fixture()
%{user: user}
end
# -- Index page --
describe "index - unauthenticated" do
test "redirects to login", %{conn: conn} do
{:error, redirect} = live(conn, ~p"/admin/providers")
assert {:redirect, %{to: path}} = redirect
assert path == ~p"/users/log-in"
end
end
describe "index - empty state" do
setup %{conn: conn, user: user} do
%{conn: log_in_user(conn, user)}
end
test "shows empty state when no connections exist", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/admin/providers")
assert html =~ "Connect a print-on-demand provider"
end
test "shows connect buttons for both providers", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/providers")
assert has_element?(view, ~s(a[href="/admin/providers/new?type=printify"]))
assert has_element?(view, ~s(a[href="/admin/providers/new?type=printful"]))
end
end
describe "index - with connection" do
setup %{conn: conn, user: user} do
connection =
provider_connection_fixture(%{
provider_type: "printify",
name: "My Printify Shop"
})
%{conn: log_in_user(conn, user), connection: connection}
end
test "lists provider connections", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/admin/providers")
assert html =~ "Printify"
assert html =~ "My Printify Shop"
end
test "shows edit link", %{conn: conn, connection: connection} do
{:ok, view, _html} = live(conn, ~p"/admin/providers")
assert has_element?(view, ~s(a[href="/admin/providers/#{connection.id}/edit"]))
end
test "shows product count", %{conn: conn, connection: connection} do
product_fixture(%{provider_connection: connection})
{:ok, _view, html} = live(conn, ~p"/admin/providers")
assert html =~ "1 product"
end
test "shows never synced warning", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/admin/providers")
assert html =~ "Never synced"
end
end
describe "index - delete" do
setup %{conn: conn, user: user} do
connection =
provider_connection_fixture(%{
provider_type: "printify",
name: "Delete Me Shop"
})
%{conn: log_in_user(conn, user), connection: connection}
end
test "deletes connection and shows flash", %{conn: conn, connection: connection} do
{:ok, view, _html} = live(conn, ~p"/admin/providers")
html = render_click(view, "delete", %{"id" => to_string(connection.id)})
assert html =~ "Provider connection deleted"
refute html =~ "Delete Me Shop"
end
end
describe "index - sync" do
setup %{conn: conn, user: user} do
Application.put_env(:berrypod, :provider_modules, %{
"printify" => MockProvider
})
on_exit(fn -> Application.delete_env(:berrypod, :provider_modules) end)
connection =
provider_connection_fixture(%{
provider_type: "printify",
name: "Sync Test Shop"
})
%{conn: log_in_user(conn, user), connection: connection}
end
test "starts sync and shows flash", %{conn: conn, connection: connection} do
stub(MockProvider, :fetch_products, fn _conn -> {:ok, []} end)
{:ok, view, _html} = live(conn, ~p"/admin/providers")
html = render_click(view, "sync", %{"id" => to_string(connection.id)})
assert html =~ "Sync started"
end
end
# -- Form page --
describe "form - new" do
setup %{conn: conn, user: user} do
Application.put_env(:berrypod, :provider_modules, %{
"printify" => MockProvider
})
on_exit(fn -> Application.delete_env(:berrypod, :provider_modules) end)
%{conn: log_in_user(conn, user)}
end
test "renders new Printify form", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/admin/providers/new?type=printify")
assert html =~ "Connect to Printify"
assert html =~ "Printify API key"
assert html =~ "Log in to Printify"
end
test "renders new Printful form", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/admin/providers/new?type=printful")
assert html =~ "Connect to Printful"
assert html =~ "Printful API key"
assert html =~ "Log in to Printful"
end
test "defaults to Printify when no type param", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/admin/providers/new")
assert html =~ "Connect to Printify"
end
test "test connection shows error when no api key", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/providers/new")
html = render_click(view, "test_connection")
assert html =~ "Please enter your API key"
end
test "saves new connection", %{conn: conn} do
expect(MockProvider, :test_connection, fn _conn ->
{:ok, %{shop_name: "My Printify Shop", shop_id: 12345}}
end)
{:ok, view, _html} = live(conn, ~p"/admin/providers/new")
{:ok, _view, html} =
view
|> form("#provider-form", %{
"provider_connection" => %{
"api_key" => "test_key_123"
}
})
|> render_submit()
|> follow_redirect(conn, ~p"/admin/settings")
assert html =~ "Connected to Printify"
end
end
describe "form - test connection" do
setup %{conn: conn, user: user} do
Application.put_env(:berrypod, :provider_modules, %{
"printify" => MockProvider
})
on_exit(fn -> Application.delete_env(:berrypod, :provider_modules) end)
%{conn: log_in_user(conn, user)}
end
test "shows success when connection is valid", %{conn: conn} do
expect(MockProvider, :test_connection, fn _conn ->
{:ok, %{shop_name: "My Printify Shop", shop_id: 12345}}
end)
{:ok, view, _html} = live(conn, ~p"/admin/providers/new")
# Validate first to set pending_api_key
view
|> form("#provider-form", %{
"provider_connection" => %{"api_key" => "valid_key_123"}
})
|> render_change()
html = render_click(view, "test_connection")
assert html =~ "Connected to My Printify Shop"
end
test "shows error when connection fails", %{conn: conn} do
expect(MockProvider, :test_connection, fn _conn ->
{:error, :unauthorized}
end)
{:ok, view, _html} = live(conn, ~p"/admin/providers/new")
view
|> form("#provider-form", %{
"provider_connection" => %{"api_key" => "bad_key"}
})
|> render_change()
html = render_click(view, "test_connection")
assert html =~ "doesn&#39;t seem to be valid"
end
end
describe "form - edit" do
setup %{conn: conn, user: user} do
connection =
provider_connection_fixture(%{
provider_type: "printify",
name: "Edit Me Shop"
})
%{conn: log_in_user(conn, user), connection: connection}
end
test "renders edit form", %{conn: conn, connection: connection} do
{:ok, _view, html} = live(conn, ~p"/admin/providers/#{connection.id}/edit")
assert html =~ "Printify settings"
assert html =~ "Connection enabled"
assert html =~ "Save changes"
end
test "saves changes", %{conn: conn, connection: connection} do
{:ok, view, _html} = live(conn, ~p"/admin/providers/#{connection.id}/edit")
{:ok, _view, html} =
view
|> form("#provider-form", %{
"provider_connection" => %{"enabled" => "true"}
})
|> render_submit()
|> follow_redirect(conn, ~p"/admin/settings")
assert html =~ "Settings saved"
end
end
end