All checks were successful
deploy / deploy (push) Successful in 1m26s
Replace put_flash calls with inline feedback for form saves: - Email settings: "Now send a test email" after saving - Settings: from address and signing secret saves - Page editor: save button shows "Saved" checkmark Inline feedback appears next to save buttons and auto-clears after 3 seconds. Banners (put_flash) remain for page-level outcomes like deletions, state changes, and async operations. Task 3 of notification overhaul. Theme editor skipped as it auto-saves. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
283 lines
8.0 KiB
Elixir
283 lines
8.0 KiB
Elixir
defmodule BerrypodWeb.Admin.SettingsTest do
|
|
use BerrypodWeb.ConnCase, async: false
|
|
|
|
import Phoenix.LiveViewTest
|
|
import Berrypod.AccountsFixtures
|
|
import Berrypod.ProductsFixtures
|
|
|
|
alias Berrypod.Accounts
|
|
alias Berrypod.Settings
|
|
|
|
setup do
|
|
user = user_fixture()
|
|
%{user: user}
|
|
end
|
|
|
|
describe "shop status toggle" do
|
|
setup %{conn: conn, user: user} do
|
|
conn = log_in_user(conn, user)
|
|
%{conn: conn}
|
|
end
|
|
|
|
test "shows offline status by default", %{conn: conn} do
|
|
{:ok, _view, html} = live(conn, ~p"/admin/settings")
|
|
|
|
assert html =~ "Offline"
|
|
assert html =~ "coming soon"
|
|
assert html =~ "Go live"
|
|
end
|
|
|
|
test "can go live", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/admin/settings")
|
|
|
|
html = render_click(view, "toggle_site_live")
|
|
|
|
assert html =~ "Shop is now live"
|
|
assert html =~ "Live"
|
|
assert html =~ "Take offline"
|
|
assert Settings.site_live?()
|
|
end
|
|
|
|
test "can take offline after going live", %{conn: conn} do
|
|
{:ok, _} = Settings.set_site_live(true)
|
|
{:ok, view, _html} = live(conn, ~p"/admin/settings")
|
|
|
|
html = render_click(view, "toggle_site_live")
|
|
|
|
assert html =~ "Shop taken offline"
|
|
assert html =~ "Offline"
|
|
assert html =~ "Go live"
|
|
refute Settings.site_live?()
|
|
end
|
|
end
|
|
|
|
describe "unauthenticated" do
|
|
test "redirects to login", %{conn: conn} do
|
|
{:error, redirect} = live(conn, ~p"/admin/settings")
|
|
assert {:redirect, %{to: path}} = redirect
|
|
assert path == ~p"/users/log-in"
|
|
end
|
|
end
|
|
|
|
describe "authenticated - not configured" do
|
|
setup %{conn: conn, user: user} do
|
|
conn = log_in_user(conn, user)
|
|
%{conn: conn}
|
|
end
|
|
|
|
test "renders setup form when Stripe is not configured", %{conn: conn} do
|
|
{:ok, _view, html} = live(conn, ~p"/admin/settings")
|
|
|
|
assert html =~ "Settings"
|
|
assert html =~ "Not connected"
|
|
assert html =~ "Connect Stripe"
|
|
assert html =~ "Stripe dashboard"
|
|
end
|
|
|
|
test "shows error for empty API key", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/admin/settings")
|
|
|
|
html =
|
|
view
|
|
|> form(~s(form[phx-submit="connect_stripe"]), %{stripe: %{api_key: ""}})
|
|
|> render_submit()
|
|
|
|
assert html =~ "Please enter your Stripe secret key"
|
|
end
|
|
end
|
|
|
|
describe "authenticated - connected (localhost)" do
|
|
setup %{conn: conn, user: user} do
|
|
# Pre-configure a Stripe API key
|
|
Settings.put_secret("stripe_api_key", "sk_test_simulated_key_12345")
|
|
conn = log_in_user(conn, user)
|
|
%{conn: conn}
|
|
end
|
|
|
|
test "renders dev mode view with CLI instructions", %{conn: conn} do
|
|
{:ok, _view, html} = live(conn, ~p"/admin/settings")
|
|
|
|
assert html =~ "Dev mode"
|
|
assert html =~ "sk_test_•••345"
|
|
assert html =~ "stripe listen"
|
|
assert html =~ "Webhook signing secret"
|
|
end
|
|
|
|
test "saves manual signing secret", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/admin/settings")
|
|
|
|
html =
|
|
view
|
|
|> form(~s(form[phx-submit="save_signing_secret"]), %{
|
|
webhook: %{signing_secret: "whsec_test_manual_456"}
|
|
})
|
|
|> render_submit()
|
|
|
|
assert has_element?(view, ".admin-inline-feedback-saved")
|
|
assert html =~ "whsec_te•••456"
|
|
end
|
|
|
|
test "shows error for empty signing secret", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/admin/settings")
|
|
|
|
html =
|
|
view
|
|
|> form(~s(form[phx-submit="save_signing_secret"]), %{webhook: %{signing_secret: ""}})
|
|
|> render_submit()
|
|
|
|
assert html =~ "Please enter a signing secret"
|
|
end
|
|
|
|
test "disconnect clears configuration", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/admin/settings")
|
|
|
|
html = render_click(view, "disconnect_stripe")
|
|
|
|
assert html =~ "Stripe disconnected"
|
|
assert html =~ "Not connected"
|
|
assert html =~ "Connect Stripe"
|
|
refute Settings.has_secret?("stripe_api_key")
|
|
end
|
|
end
|
|
|
|
describe "products section" do
|
|
setup %{conn: conn, user: user} do
|
|
conn = log_in_user(conn, user)
|
|
%{conn: conn}
|
|
end
|
|
|
|
test "shows connect button when no provider connected", %{conn: conn} do
|
|
{:ok, view, html} = live(conn, ~p"/admin/settings")
|
|
|
|
assert html =~ "Products"
|
|
assert html =~ "Not connected"
|
|
assert has_element?(view, ~s(a[href="/admin/providers"]), "Connect a provider")
|
|
end
|
|
|
|
test "shows connection info when provider connected", %{conn: conn} do
|
|
conn_record = provider_connection_fixture(%{name: "Test Shop"})
|
|
product_fixture(%{provider_connection: conn_record})
|
|
|
|
{:ok, _view, html} = live(conn, ~p"/admin/settings")
|
|
|
|
assert html =~ "Connected"
|
|
assert html =~ "Test Shop"
|
|
assert html =~ "Sync products"
|
|
end
|
|
end
|
|
|
|
describe "account section" do
|
|
setup %{conn: conn, user: user} do
|
|
conn = log_in_user(conn, user)
|
|
%{conn: conn, user: user}
|
|
end
|
|
|
|
test "renders email and password forms", %{conn: conn, user: user} do
|
|
{:ok, view, html} = live(conn, ~p"/admin/settings")
|
|
|
|
assert html =~ "Account"
|
|
assert html =~ user.email
|
|
assert has_element?(view, "#email_form")
|
|
assert has_element?(view, "#password_form")
|
|
end
|
|
|
|
test "validates email change", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/admin/settings")
|
|
|
|
result =
|
|
view
|
|
|> element("#email_form")
|
|
|> render_change(%{"user" => %{"email" => "with spaces"}})
|
|
|
|
assert result =~ "must have the @ sign and no spaces"
|
|
end
|
|
|
|
test "submits email change", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/admin/settings")
|
|
|
|
result =
|
|
view
|
|
|> form("#email_form", %{"user" => %{"email" => unique_user_email()}})
|
|
|> render_submit()
|
|
|
|
assert result =~ "A link to confirm your email"
|
|
end
|
|
|
|
test "validates password", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/admin/settings")
|
|
|
|
result =
|
|
view
|
|
|> element("#password_form")
|
|
|> render_change(%{
|
|
"user" => %{
|
|
"password" => "short",
|
|
"password_confirmation" => "mismatch"
|
|
}
|
|
})
|
|
|
|
assert result =~ "should be at least 12 character(s)"
|
|
end
|
|
|
|
test "submits valid password change", %{conn: conn, user: user} do
|
|
new_password = valid_user_password()
|
|
{:ok, view, _html} = live(conn, ~p"/admin/settings")
|
|
|
|
form =
|
|
form(view, "#password_form", %{
|
|
"user" => %{
|
|
"email" => user.email,
|
|
"password" => new_password,
|
|
"password_confirmation" => new_password
|
|
}
|
|
})
|
|
|
|
render_submit(form)
|
|
new_password_conn = follow_trigger_action(form, conn)
|
|
|
|
assert redirected_to(new_password_conn) == ~p"/admin/settings"
|
|
assert Accounts.get_user_by_email_and_password(user.email, new_password)
|
|
end
|
|
end
|
|
|
|
describe "from address" do
|
|
setup %{conn: conn, user: user} do
|
|
conn = log_in_user(conn, user)
|
|
%{conn: conn}
|
|
end
|
|
|
|
test "shows from address section", %{conn: conn} do
|
|
{:ok, _view, html} = live(conn, ~p"/admin/settings")
|
|
|
|
assert html =~ "From address"
|
|
assert html =~ "sender address"
|
|
end
|
|
|
|
test "saves from address", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/admin/settings")
|
|
|
|
html =
|
|
view
|
|
|> form("form[phx-submit=\"save_from_address\"]", %{from_address: "shop@example.com"})
|
|
|> render_submit()
|
|
|
|
assert has_element?(view, ".admin-inline-feedback-saved")
|
|
assert Settings.get_setting("email_from_address") == "shop@example.com"
|
|
end
|
|
end
|
|
|
|
describe "advanced section" do
|
|
setup %{conn: conn, user: user} do
|
|
conn = log_in_user(conn, user)
|
|
%{conn: conn}
|
|
end
|
|
|
|
test "shows links to system tools", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/admin/settings")
|
|
|
|
assert has_element?(view, ~s(a[href="/admin/dashboard"]), "System dashboard")
|
|
assert has_element?(view, ~s(a[href="/admin/errors"]), "Error tracker")
|
|
end
|
|
end
|
|
end
|