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 html =~ "Webhook signing secret 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 "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