restructure LiveView directories: admin/, shop/, auth/

Consolidates admin_live/, theme_live/, provider_live/ into admin/
(with theme/ and providers/ subdirs). Renames shop_live/ to shop/
and user_live/ to auth/. Updates all module names, router refs,
test files, CSS source paths, and dialyzer ignore.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jamey
2026-02-12 00:16:32 +00:00
parent e64bf40a71
commit deea04885f
38 changed files with 56 additions and 56 deletions

View File

@@ -0,0 +1,190 @@
defmodule SimpleshopThemeWeb.Admin.OrdersTest do
use SimpleshopThemeWeb.ConnCase, async: false
import Phoenix.LiveViewTest
import SimpleshopTheme.AccountsFixtures
import SimpleshopTheme.OrdersFixtures
setup do
user = user_fixture()
%{user: user}
end
describe "unauthenticated" do
test "redirects to login", %{conn: conn} do
{:error, redirect} = live(conn, ~p"/admin/orders")
assert {:redirect, %{to: path}} = redirect
assert path == ~p"/users/log-in"
end
end
describe "order list" do
setup %{conn: conn, user: user} do
conn = log_in_user(conn, user)
%{conn: conn}
end
test "renders empty state when no orders", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/admin/orders")
assert html =~ "No orders yet"
assert html =~ "Orders"
end
test "renders orders table", %{conn: conn} do
order = order_fixture(payment_status: "paid", customer_email: "test@shop.com")
{:ok, _view, html} = live(conn, ~p"/admin/orders")
assert html =~ order.order_number
assert html =~ "test@shop.com"
assert html =~ "paid"
end
test "filters by status", %{conn: conn} do
paid = order_fixture(payment_status: "paid")
_pending = order_fixture()
{:ok, view, _html} = live(conn, ~p"/admin/orders")
html = render_click(view, "filter", %{"status" => "paid"})
assert html =~ paid.order_number
end
test "navigates to order detail", %{conn: conn} do
order = order_fixture(payment_status: "paid")
{:ok, _view, html} = live(conn, ~p"/admin/orders")
assert html =~ ~p"/admin/orders/#{order}"
end
end
describe "order detail" do
setup %{conn: conn, user: user} do
conn = log_in_user(conn, user)
%{conn: conn}
end
test "renders order details", %{conn: conn} do
order = order_fixture(payment_status: "paid", customer_email: "buyer@example.com")
{:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}")
assert html =~ order.order_number
assert html =~ "buyer@example.com"
assert html =~ "paid"
assert html =~ "Order details"
end
test "shows line items", %{conn: conn} do
order = order_fixture(product_name: "Cool T-shirt", variant_title: "Blue / XL")
{:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}")
assert html =~ "Cool T-shirt"
assert html =~ "Blue / XL"
end
test "shows shipping address", %{conn: conn} do
order = order_fixture(payment_status: "paid")
{:ok, updated_order} =
SimpleshopTheme.Orders.update_order(order, %{
shipping_address: %{
"name" => "Jane Doe",
"line1" => "42 Test Street",
"city" => "London",
"postal_code" => "SW1A 1AA",
"country" => "GB"
}
})
{:ok, _view, html} = live(conn, ~p"/admin/orders/#{updated_order}")
assert html =~ "Jane Doe"
assert html =~ "42 Test Street"
assert html =~ "London"
assert html =~ "SW1A 1AA"
end
test "redirects when order not found", %{conn: conn} do
fake_id = Ecto.UUID.generate()
{:error, {:live_redirect, %{to: "/admin/orders"}}} =
live(conn, ~p"/admin/orders/#{fake_id}")
end
test "shows fulfilment card", %{conn: conn} do
order = order_fixture(payment_status: "paid")
{:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}")
assert html =~ "Fulfilment"
assert html =~ "unfulfilled"
end
test "shows submit button for paid unfulfilled orders", %{conn: conn} do
order = order_fixture(payment_status: "paid")
{:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}")
assert html =~ "Submit to provider"
end
test "shows retry button for failed fulfilment", %{conn: conn} do
order = order_fixture(payment_status: "paid")
{:ok, order} =
SimpleshopTheme.Orders.update_fulfilment(order, %{fulfilment_status: "failed"})
{:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}")
assert html =~ "Retry submission"
end
test "shows refresh button for submitted orders", %{conn: conn} do
{order, _v, _p, _c} =
SimpleshopTheme.OrdersFixtures.submitted_order_fixture()
{:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}")
assert html =~ "Refresh status"
end
test "shows tracking info when available", %{conn: conn} do
{order, _v, _p, _c} =
SimpleshopTheme.OrdersFixtures.submitted_order_fixture()
{:ok, order} =
SimpleshopTheme.Orders.update_fulfilment(order, %{
fulfilment_status: "shipped",
tracking_number: "TRACK123",
tracking_url: "https://track.example.com/TRACK123",
shipped_at: DateTime.utc_now() |> DateTime.truncate(:second)
})
{:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}")
assert html =~ "TRACK123"
assert html =~ "https://track.example.com/TRACK123"
end
end
describe "order list fulfilment column" do
setup %{conn: conn, user: user} do
conn = log_in_user(conn, user)
%{conn: conn}
end
test "shows fulfilment badge in table", %{conn: conn} do
order_fixture(payment_status: "paid")
{:ok, _view, html} = live(conn, ~p"/admin/orders")
assert html =~ "Fulfilment"
assert html =~ "unfulfilled"
end
end
end

View File

@@ -0,0 +1,138 @@
defmodule SimpleshopThemeWeb.Admin.SettingsTest do
use SimpleshopThemeWeb.ConnCase, async: false
import Phoenix.LiveViewTest
import SimpleshopTheme.AccountsFixtures
alias SimpleshopTheme.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("form", %{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("form", %{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("form", %{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
end

View File

@@ -0,0 +1,216 @@
defmodule SimpleshopThemeWeb.Admin.ThemeTest do
use SimpleshopThemeWeb.ConnCase, async: false
import Phoenix.LiveViewTest
import SimpleshopTheme.AccountsFixtures
alias SimpleshopTheme.Settings
setup do
user = user_fixture()
%{user: user}
end
describe "Index (unauthenticated)" do
test "redirects to login when not authenticated", %{conn: conn} do
{:error, redirect} = live(conn, ~p"/admin/theme")
assert {:redirect, %{to: path}} = redirect
assert path == ~p"/users/log-in"
end
end
describe "Index (authenticated)" do
setup %{conn: conn, user: user} do
conn = log_in_user(conn, user)
%{conn: conn}
end
test "renders theme editor page", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/admin/theme")
assert html =~ "Theme Studio"
assert html =~ "preset"
end
test "displays all 8 presets", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/admin/theme")
assert html =~ "gallery"
assert html =~ "studio"
assert html =~ "boutique"
assert html =~ "bold"
assert html =~ "playful"
assert html =~ "minimal"
assert html =~ "night"
assert html =~ "classic"
end
test "displays current theme settings", %{conn: conn} do
{:ok, _settings} = Settings.apply_preset(:gallery)
{:ok, _view, html} = live(conn, ~p"/admin/theme")
assert html =~ "warm"
assert html =~ "editorial"
assert html =~ "soft"
assert html =~ "spacious"
end
test "displays generated CSS in preview", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/admin/theme")
# CSS generator outputs accent colors and layout variables for shop pages
assert html =~ ".themed {"
assert html =~ "--t-accent-h:"
end
test "applies preset and updates preview", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/theme")
html =
view
|> element("button", "gallery")
|> render_click()
theme_settings = Settings.get_theme_settings()
assert theme_settings.mood == "warm"
assert theme_settings.typography == "editorial"
assert html =~ "warm"
assert html =~ "editorial"
end
test "switches preview page", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/theme")
html =
view
|> element("button", "Collection")
|> render_click()
assert html =~ "All Products"
end
test "theme settings are saved when applying a preset", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/theme")
# Apply a preset
view
|> element("button", "gallery")
|> render_click()
# Verify settings were persisted
theme_settings = Settings.get_theme_settings()
assert theme_settings.mood == "warm"
assert theme_settings.typography == "editorial"
end
test "all preview page buttons are present", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/admin/theme")
assert html =~ "Home"
assert html =~ "Collection"
assert html =~ "Product"
assert html =~ "Cart"
assert html =~ "About"
assert html =~ "Contact"
assert html =~ "404"
end
test "mood customization buttons work", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/theme")
# Click the "dark" mood button
html =
view
|> element("button[phx-value-setting_value='dark']")
|> render_click()
# Verify the setting was updated
theme_settings = Settings.get_theme_settings()
assert theme_settings.mood == "dark"
assert html =~ "dark"
end
test "shape customization buttons work", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/theme")
# Click the "round" shape button
view
|> element("button[phx-value-setting_value='round']")
|> render_click()
# Verify the setting was updated
theme_settings = Settings.get_theme_settings()
assert theme_settings.shape == "round"
end
test "density customization buttons work", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/theme")
# Click the "compact" density button
view
|> element("button[phx-value-setting_value='compact']")
|> render_click()
# Verify the setting was updated
theme_settings = Settings.get_theme_settings()
assert theme_settings.density == "compact"
end
test "grid columns customization buttons work", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/theme")
# Click the "2 columns" grid columns button
view
|> element("button", "2 columns")
|> render_click()
# Verify the setting was updated
theme_settings = Settings.get_theme_settings()
assert theme_settings.grid_columns == "2"
end
test "typography customization buttons work", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/theme")
# Click the "modern" typography button
view
|> element("button[phx-value-setting_value='modern']")
|> render_click()
# Verify the setting was updated
theme_settings = Settings.get_theme_settings()
assert theme_settings.typography == "modern"
end
test "header layout customization buttons work", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/admin/theme")
# Click the "centered" header layout button
view
|> element("button[phx-value-setting_value='centered']")
|> render_click()
# Verify the setting was updated
theme_settings = Settings.get_theme_settings()
assert theme_settings.header_layout == "centered"
end
test "CSS regenerates when settings change", %{conn: conn} do
{:ok, view, html} = live(conn, ~p"/admin/theme")
# Capture initial CSS
initial_css = html
# Change a setting
new_html =
view
|> element("button[phx-value-setting_value='dark']")
|> render_click()
# Verify CSS has changed
refute initial_css == new_html
assert new_html =~ "--t-accent-h:"
end
end
end