defmodule Microwaveprop.Radio.EnrichmentStatusTest do use Microwaveprop.DataCase, async: true alias Microwaveprop.Radio.Contact alias Microwaveprop.Radio.EnrichmentStatus describe "states/0" do test "returns all valid states" do assert EnrichmentStatus.states() == [:pending, :queued, :processing, :complete, :failed, :unavailable] end end describe "fields/0" do test "returns all status fields" do assert EnrichmentStatus.fields() == [:hrrr_status, :weather_status, :terrain_status, :iemre_status] end end describe "valid_transition?/2" do test "pending can transition to queued" do assert EnrichmentStatus.valid_transition?(:pending, :queued) end test "pending can transition to unavailable" do assert EnrichmentStatus.valid_transition?(:pending, :unavailable) end test "pending cannot transition to complete" do refute EnrichmentStatus.valid_transition?(:pending, :complete) end test "queued can transition to processing" do assert EnrichmentStatus.valid_transition?(:queued, :processing) end test "queued can transition to failed" do assert EnrichmentStatus.valid_transition?(:queued, :failed) end test "queued cannot transition to complete" do refute EnrichmentStatus.valid_transition?(:queued, :complete) end test "processing can transition to complete" do assert EnrichmentStatus.valid_transition?(:processing, :complete) end test "processing can transition to failed" do assert EnrichmentStatus.valid_transition?(:processing, :failed) end test "processing cannot transition to pending" do refute EnrichmentStatus.valid_transition?(:processing, :pending) end test "failed can transition to queued (retry)" do assert EnrichmentStatus.valid_transition?(:failed, :queued) end test "failed cannot transition to complete" do refute EnrichmentStatus.valid_transition?(:failed, :complete) end test "unavailable can transition to queued (retry)" do assert EnrichmentStatus.valid_transition?(:unavailable, :queued) end test "complete can transition to pending (reset)" do assert EnrichmentStatus.valid_transition?(:complete, :pending) end test "complete cannot transition to queued" do refute EnrichmentStatus.valid_transition?(:complete, :queued) end end describe "transition/3" do test "applies valid transition to changeset" do changeset = %Contact{} |> Ecto.Changeset.change(%{hrrr_status: :pending}) |> EnrichmentStatus.transition(:hrrr_status, :queued) assert Ecto.Changeset.get_change(changeset, :hrrr_status) == :queued assert changeset.valid? end test "adds error for invalid transition" do changeset = %Contact{} |> Ecto.Changeset.change(%{hrrr_status: :pending}) |> EnrichmentStatus.transition(:hrrr_status, :complete) assert {:hrrr_status, {"invalid transition from pending to complete", []}} in changeset.errors end test "works for all status fields" do for field <- EnrichmentStatus.fields() do changeset = %Contact{} |> Ecto.Changeset.change(%{field => :pending}) |> EnrichmentStatus.transition(field, :queued) assert Ecto.Changeset.get_change(changeset, field) == :queued end end end describe "force_status/3" do test "sets status without transition validation" do changeset = %Contact{} |> Ecto.Changeset.change(%{hrrr_status: :pending}) |> EnrichmentStatus.force_status(:hrrr_status, :complete) assert Ecto.Changeset.get_change(changeset, :hrrr_status) == :complete assert changeset.valid? end test "allows normally invalid transitions" do changeset = %Contact{} |> Ecto.Changeset.change(%{weather_status: :pending}) |> EnrichmentStatus.force_status(:weather_status, :failed) assert Ecto.Changeset.get_change(changeset, :weather_status) == :failed assert changeset.valid? end end end