diff --git a/lib/berrypod_web/components/shop_components/cart.ex b/lib/berrypod_web/components/shop_components/cart.ex index 9db0c71..0200024 100644 --- a/lib/berrypod_web/components/shop_components/cart.ex +++ b/lib/berrypod_web/components/shop_components/cart.ex @@ -403,7 +403,8 @@ defmodule BerrypodWeb.ShopComponents.Cart do Delivery to <%= if @available_countries != [] and @mode != :preview do %> -
+ + +
<% else %> {Berrypod.Shipping.country_name(@country_code)} diff --git a/lib/berrypod_web/controllers/cart_controller.ex b/lib/berrypod_web/controllers/cart_controller.ex index b2c4dde..f50080e 100644 --- a/lib/berrypod_web/controllers/cart_controller.ex +++ b/lib/berrypod_web/controllers/cart_controller.ex @@ -74,6 +74,19 @@ defmodule BerrypodWeb.CartController do |> redirect(to: ~p"/cart") end + @doc """ + Updates delivery country via form POST (no-JS fallback). + """ + def update_country(conn, %{"country" => code}) when is_binary(code) and code != "" do + conn + |> put_session("country_code", code) + |> redirect(to: ~p"/cart") + end + + def update_country(conn, _params) do + redirect(conn, to: ~p"/cart") + end + defp parse_quantity(str) when is_binary(str) do case Integer.parse(str) do {qty, _} when qty > 0 -> qty diff --git a/lib/berrypod_web/router.ex b/lib/berrypod_web/router.ex index 9e99825..8320aff 100644 --- a/lib/berrypod_web/router.ex +++ b/lib/berrypod_web/router.ex @@ -97,6 +97,7 @@ defmodule BerrypodWeb.Router do post "/cart/add", CartController, :add post "/cart/remove", CartController, :remove post "/cart/update", CartController, :update_item + post "/cart/country", CartController, :update_country end # Health check (no auth, no theme loading — for load balancers and uptime monitors) diff --git a/test/berrypod_web/controllers/cart_controller_test.exs b/test/berrypod_web/controllers/cart_controller_test.exs index b6839d7..29b0730 100644 --- a/test/berrypod_web/controllers/cart_controller_test.exs +++ b/test/berrypod_web/controllers/cart_controller_test.exs @@ -108,4 +108,19 @@ defmodule BerrypodWeb.CartControllerTest do assert cart == [] end end + + describe "POST /cart/country" do + test "saves country to session and redirects to /cart", %{conn: conn} do + conn = post(conn, ~p"/cart/country", %{"country" => "DE"}) + + assert redirected_to(conn) == "/cart" + assert get_session(conn, "country_code") == "DE" + end + + test "handles missing country param", %{conn: conn} do + conn = post(conn, ~p"/cart/country", %{}) + + assert redirected_to(conn) == "/cart" + end + end end diff --git a/test/berrypod_web/live/shop/cart_test.exs b/test/berrypod_web/live/shop/cart_test.exs index 2361722..28f2374 100644 --- a/test/berrypod_web/live/shop/cart_test.exs +++ b/test/berrypod_web/live/shop/cart_test.exs @@ -106,6 +106,36 @@ defmodule BerrypodWeb.Shop.CartTest do end end + describe "no-JS fallback" do + setup [:create_cart_with_product] + + test "country selector form has action for no-JS submission", %{ + conn: conn, + variant: variant + } do + # Insert a shipping rate so the country selector renders + now = DateTime.utc_now() |> DateTime.truncate(:second) + pc = Berrypod.ProductsFixtures.provider_connection_fixture() + + Berrypod.Repo.insert_all(Berrypod.Shipping.ShippingRate, [ + [ + blueprint_id: 1, + print_provider_id: 1, + country_code: "GB", + first_item_cost: 399, + additional_item_cost: 100, + provider_connection_id: pc.id, + inserted_at: now, + updated_at: now + ] + ]) + + {:ok, view, _html} = conn |> conn_with_cart(variant.id) |> live(~p"/cart") + + assert has_element?(view, "form[action='/cart/country'][method='post']") + end + end + describe "Cart page title" do test "page title is Cart", %{conn: conn} do {:ok, _view, html} = live(conn, ~p"/cart")