defmodule Microwaveprop.Weather.MrmsCacheTest do # async: false — MrmsCache is started at the application level and owns a # named ETS table. Tests mutate shared state and must not race. use ExUnit.Case, async: false alias Microwaveprop.Weather.MrmsCache @topic "mrms:cache" @pubsub Microwaveprop.PubSub setup do MrmsCache.clear() :ok end describe "fetch/0" do test "returns :miss when nothing is cached" do assert MrmsCache.fetch() == :miss end test "returns {:ok, valid_time, grid} after put/2" do valid_time = ~U[2026-04-12 19:24:00Z] grid = %{{32.0, -97.0} => 1.2, {32.125, -97.0} => 0.0} assert :ok = MrmsCache.put(valid_time, grid) assert {:ok, ^valid_time, ^grid} = MrmsCache.fetch() end test "put/2 overwrites the single current entry" do first_vt = ~U[2026-04-12 19:24:00Z] second_vt = ~U[2026-04-12 19:26:00Z] MrmsCache.put(first_vt, %{{32.0, -97.0} => 1.0}) MrmsCache.put(second_vt, %{{32.0, -97.0} => 2.0}) assert {:ok, ^second_vt, %{{32.0, -97.0} => 2.0}} = MrmsCache.fetch() end end describe "valid_time/0" do test "returns nil when cache is empty" do assert MrmsCache.valid_time() == nil end test "returns the cached valid_time when present" do vt = ~U[2026-04-12 19:24:00Z] MrmsCache.put(vt, %{{32.0, -97.0} => 5.4}) assert MrmsCache.valid_time() == vt end end describe "broadcast_put/2" do test "inserts locally and broadcasts on the mrms:cache topic" do Phoenix.PubSub.subscribe(@pubsub, @topic) vt = ~U[2026-04-12 19:28:00Z] grid = %{{32.0, -97.0} => 3.3} assert :ok = MrmsCache.broadcast_put(vt, grid) assert {:ok, ^vt, ^grid} = MrmsCache.fetch() # The cache subscribes to its own topic, so we should observe the # message via our own subscription too. assert_receive {:mrms_cache_refresh, ^vt, ^grid} end end describe "clear/0" do test "empties the cache" do MrmsCache.put(~U[2026-04-12 19:24:00Z], %{{32.0, -97.0} => 1.0}) assert {:ok, _, _} = MrmsCache.fetch() assert :ok = MrmsCache.clear() assert MrmsCache.fetch() == :miss assert MrmsCache.valid_time() == nil end end describe "peer broadcast handling" do test "applies refreshes received from peers on the PubSub topic" do # Simulate a peer node pushing a refresh. The cache GenServer is # subscribed to @topic in init/1; broadcasting directly exercises the # handle_info({:mrms_cache_refresh, ...}) clause. vt = ~U[2026-04-12 19:30:00Z] grid = %{{32.0, -97.0} => 7.7} Phoenix.PubSub.broadcast(@pubsub, @topic, {:mrms_cache_refresh, vt, grid}) # Round-trip through the MrmsCache GenServer mailbox: send it a sync # call so we know the previous broadcast has been processed. _ = :sys.get_state(MrmsCache) assert {:ok, ^vt, ^grid} = MrmsCache.fetch() end end end