All checks were successful
deploy / deploy (push) Successful in 1m17s
Magic link flow on contact page: customer enters email, gets a time-limited signed link, clicks through to /orders showing all their paid orders and full detail pages with thumbnails and product links. - OrderLookupController generates/verifies Phoenix.Token signed links - Contact LiveView handles lookup_orders + reset_tracking events - Orders and OrderDetail LiveViews gated by session email - Order detail shows thumbnails, links to products still available - .themed-button gets base padding/font-weight so all usages are consistent - order-summary-card sticky scoped to .cart-grid (was leaking to orders list) - 27 new tests (1095 total) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
176 lines
5.6 KiB
Elixir
176 lines
5.6 KiB
Elixir
defmodule Berrypod.Orders.OrderNotifierTest do
|
|
use Berrypod.DataCase, async: false
|
|
|
|
import Swoosh.TestAssertions
|
|
import Berrypod.OrdersFixtures
|
|
|
|
alias Berrypod.Orders
|
|
alias Berrypod.Orders.OrderNotifier
|
|
|
|
describe "deliver_order_confirmation/1" do
|
|
test "sends confirmation with order details" do
|
|
order =
|
|
order_fixture(%{
|
|
customer_email: "buyer@example.com",
|
|
payment_status: "paid",
|
|
shipping_address: %{
|
|
"name" => "Jane Doe",
|
|
"line1" => "42 Test Street",
|
|
"city" => "London",
|
|
"postal_code" => "SW1A 1AA",
|
|
"country" => "GB"
|
|
}
|
|
})
|
|
|
|
assert {:ok, _email} = OrderNotifier.deliver_order_confirmation(order)
|
|
|
|
assert_email_sent(fn email ->
|
|
assert email.to == [{"", "buyer@example.com"}]
|
|
assert email.subject =~ "Order confirmed"
|
|
assert email.subject =~ order.order_number
|
|
assert email.text_body =~ order.order_number
|
|
assert email.text_body =~ "Test product"
|
|
assert email.text_body =~ "Jane Doe"
|
|
assert email.text_body =~ "42 Test Street"
|
|
assert email.text_body =~ "London"
|
|
end)
|
|
end
|
|
|
|
test "includes item quantities and prices" do
|
|
order =
|
|
order_fixture(%{
|
|
customer_email: "buyer@example.com",
|
|
payment_status: "paid",
|
|
quantity: 2,
|
|
unit_price: 1500
|
|
})
|
|
|
|
assert {:ok, _email} = OrderNotifier.deliver_order_confirmation(order)
|
|
|
|
assert_email_sent(fn email ->
|
|
assert email.text_body =~ "2x Test product"
|
|
end)
|
|
end
|
|
|
|
test "includes order total" do
|
|
order =
|
|
order_fixture(%{
|
|
customer_email: "buyer@example.com",
|
|
payment_status: "paid",
|
|
unit_price: 2500
|
|
})
|
|
|
|
assert {:ok, _email} = OrderNotifier.deliver_order_confirmation(order)
|
|
|
|
assert_email_sent(fn email ->
|
|
assert email.text_body =~ "Total:"
|
|
end)
|
|
end
|
|
|
|
test "skips when customer_email is nil" do
|
|
order = order_fixture(%{customer_email: nil})
|
|
|
|
# Override to nil since fixture sets a default
|
|
{:ok, order} = Orders.update_order(order, %{customer_email: nil})
|
|
|
|
assert {:ok, :no_email} = OrderNotifier.deliver_order_confirmation(order)
|
|
assert_no_email_sent()
|
|
end
|
|
|
|
test "skips when customer_email is empty string" do
|
|
order = order_fixture()
|
|
{:ok, order} = Orders.update_order(order, %{customer_email: ""})
|
|
|
|
assert {:ok, :no_email} = OrderNotifier.deliver_order_confirmation(order)
|
|
assert_no_email_sent()
|
|
end
|
|
|
|
test "handles missing shipping address" do
|
|
order = order_fixture(%{customer_email: "buyer@example.com", payment_status: "paid"})
|
|
|
|
assert {:ok, _email} = OrderNotifier.deliver_order_confirmation(order)
|
|
assert_email_sent(subject: "Order confirmed - #{order.order_number}")
|
|
end
|
|
end
|
|
|
|
describe "deliver_order_lookup/2" do
|
|
test "sends magic link email" do
|
|
link = "https://example.com/orders/verify/tok"
|
|
assert {:ok, _email} = OrderNotifier.deliver_order_lookup("buyer@example.com", link)
|
|
|
|
assert_email_sent(fn email ->
|
|
assert email.to == [{"", "buyer@example.com"}]
|
|
assert email.subject == "Your order lookup link"
|
|
assert email.text_body =~ link
|
|
assert email.text_body =~ "expires in 1 hour"
|
|
end)
|
|
end
|
|
end
|
|
|
|
describe "deliver_shipping_notification/1" do
|
|
test "sends notification with tracking info" do
|
|
{order, _v, _p, _c} = submitted_order_fixture(%{customer_email: "buyer@example.com"})
|
|
|
|
{:ok, order} =
|
|
Orders.update_fulfilment(order, %{
|
|
fulfilment_status: "shipped",
|
|
tracking_number: "1Z999AA1",
|
|
tracking_url: "https://ups.com/track/1Z999AA1",
|
|
shipped_at: DateTime.utc_now() |> DateTime.truncate(:second)
|
|
})
|
|
|
|
assert {:ok, _email} = OrderNotifier.deliver_shipping_notification(order)
|
|
|
|
assert_email_sent(fn email ->
|
|
assert email.to == [{"", "buyer@example.com"}]
|
|
assert email.subject =~ "Your order has shipped"
|
|
assert email.subject =~ order.order_number
|
|
assert email.text_body =~ "1Z999AA1"
|
|
assert email.text_body =~ "https://ups.com/track/1Z999AA1"
|
|
end)
|
|
end
|
|
|
|
test "handles missing tracking info gracefully" do
|
|
{order, _v, _p, _c} = submitted_order_fixture(%{customer_email: "buyer@example.com"})
|
|
|
|
{:ok, order} =
|
|
Orders.update_fulfilment(order, %{
|
|
fulfilment_status: "shipped",
|
|
shipped_at: DateTime.utc_now() |> DateTime.truncate(:second)
|
|
})
|
|
|
|
assert {:ok, _email} = OrderNotifier.deliver_shipping_notification(order)
|
|
|
|
assert_email_sent(fn email ->
|
|
assert email.text_body =~ "Tracking details will follow"
|
|
end)
|
|
end
|
|
|
|
test "includes tracking number without URL" do
|
|
{order, _v, _p, _c} = submitted_order_fixture(%{customer_email: "buyer@example.com"})
|
|
|
|
{:ok, order} =
|
|
Orders.update_fulfilment(order, %{
|
|
fulfilment_status: "shipped",
|
|
tracking_number: "RM123456789GB",
|
|
shipped_at: DateTime.utc_now() |> DateTime.truncate(:second)
|
|
})
|
|
|
|
assert {:ok, _email} = OrderNotifier.deliver_shipping_notification(order)
|
|
|
|
assert_email_sent(fn email ->
|
|
assert email.text_body =~ "RM123456789GB"
|
|
assert not (email.text_body =~ "Tracking details will follow")
|
|
end)
|
|
end
|
|
|
|
test "skips when customer_email is nil" do
|
|
{order, _v, _p, _c} = submitted_order_fixture()
|
|
{:ok, order} = Orders.update_order(order, %{customer_email: nil})
|
|
|
|
assert {:ok, :no_email} = OrderNotifier.deliver_shipping_notification(order)
|
|
assert_no_email_sent()
|
|
end
|
|
end
|
|
end
|