defmodule Microwaveprop.Workers.SpaceWeatherFetchWorkerTest do
  use Microwaveprop.DataCase, async: false
  use Oban.Testing, repo: Microwaveprop.Repo

  alias Microwaveprop.SpaceWeather
  alias Microwaveprop.SpaceWeather.GeomagneticObservation
  alias Microwaveprop.SpaceWeather.SolarFluxObservation
  alias Microwaveprop.SpaceWeather.SolarXrayObservation
  alias Microwaveprop.SpaceWeather.SwpcClient
  alias Microwaveprop.Workers.SpaceWeatherFetchWorker

  @kp File.read!("test/fixtures/swpc/kp_sample.json")
  @f107 File.read!("test/fixtures/swpc/f107_sample.json")
  @xrays File.read!("test/fixtures/swpc/xrays_sample.json")

  describe "perform/1" do
    test "pulls all three SWPC products and upserts them" do
      Req.Test.stub(SwpcClient, fn conn ->
        case conn.request_path do
          "/json/planetary_k_index_1m.json" -> Plug.Conn.resp(conn, 200, @kp)
          "/json/f107_cm_flux.json" -> Plug.Conn.resp(conn, 200, @f107)
          "/json/goes/primary/xrays-1-day.json" -> Plug.Conn.resp(conn, 200, @xrays)
        end
      end)

      assert :ok = perform_job(SpaceWeatherFetchWorker, %{})

      assert Repo.aggregate(GeomagneticObservation, :count, :id) == 10
      assert Repo.aggregate(SolarFluxObservation, :count, :id) == 10
      # Xray fixture has 12 records (6 timestamps × 2 bands); we only
      # store the 0.1-0.8nm band.
      assert Repo.aggregate(SolarXrayObservation, :count, :id) == 6

      assert SpaceWeather.latest_kp()
      assert SpaceWeather.latest_f107()
      assert SpaceWeather.latest_xray()
    end

    test "ingests the remaining products when one endpoint fails" do
      Req.Test.stub(SwpcClient, fn conn ->
        case conn.request_path do
          "/json/planetary_k_index_1m.json" -> Plug.Conn.resp(conn, 500, "boom")
          "/json/f107_cm_flux.json" -> Plug.Conn.resp(conn, 200, @f107)
          "/json/goes/primary/xrays-1-day.json" -> Plug.Conn.resp(conn, 200, @xrays)
        end
      end)

      assert :ok = perform_job(SpaceWeatherFetchWorker, %{})

      assert Repo.aggregate(GeomagneticObservation, :count, :id) == 0
      assert Repo.aggregate(SolarFluxObservation, :count, :id) == 10
      assert Repo.aggregate(SolarXrayObservation, :count, :id) == 6
    end
  end
end
