defmodule Berrypod.Orders.AbandonedCartPruneWorkerTest do
  use Berrypod.DataCase, async: true

  alias Berrypod.Orders
  alias Berrypod.Orders.AbandonedCartPruneWorker

  defp create_cart(attrs \\ %{}) do
    defaults = %{
      customer_email: "test@example.com",
      stripe_session_id: "cs_#{System.unique_integer([:positive])}",
      expired_at: DateTime.utc_now() |> DateTime.truncate(:second)
    }

    {:ok, cart} = Orders.create_abandoned_cart(Map.merge(defaults, attrs))
    cart
  end

  defp backdate(cart, days) do
    Berrypod.Repo.update_all(
      Ecto.Query.from(a in Berrypod.Orders.AbandonedCart, where: a.id == ^cart.id),
      set: [inserted_at: DateTime.add(DateTime.utc_now(), -days, :day)]
    )
  end

  describe "perform/1" do
    test "deletes carts older than 30 days" do
      old_cart = create_cart()
      backdate(old_cart, 31)

      recent_cart = create_cart()

      assert :ok = AbandonedCartPruneWorker.perform(%Oban.Job{args: %{}})

      assert is_nil(Orders.get_abandoned_cart(old_cart.id))
      assert not is_nil(Orders.get_abandoned_cart(recent_cart.id))
    end

    test "keeps carts exactly at the 30-day boundary" do
      boundary_cart = create_cart()
      backdate(boundary_cart, 29)

      assert :ok = AbandonedCartPruneWorker.perform(%Oban.Job{args: %{}})

      assert not is_nil(Orders.get_abandoned_cart(boundary_cart.id))
    end

    test "is a no-op when there's nothing to prune" do
      assert :ok = AbandonedCartPruneWorker.perform(%Oban.Job{args: %{}})
    end
  end
end
