From fb389101376adbff0c2d3209b826c2db74d05ed5 Mon Sep 17 00:00:00 2001
From: Joao P Dubas <joao.dubas+gitea@gmail.com>
Date: Mon, 7 Oct 2024 19:27:27 +0000
Subject: [PATCH] test(growth): add test for happy download paths

---
 config/test.exs                          |   3 +
 test/growth/indicators/download_test.exs | 297 +++++++++++++++++++++++
 2 files changed, 300 insertions(+)
 create mode 100644 test/growth/indicators/download_test.exs

diff --git a/config/test.exs b/config/test.exs
index 4b124fa..e838b98 100644
--- a/config/test.exs
+++ b/config/test.exs
@@ -1,5 +1,8 @@
 import Config
 
+config :wabanex, Growth.Indicators.Download,
+  who_req_options: [plug: {Req.Test, Growth.Indicators.Download.WHO}]
+
 config :wabanex, Wabanex.Repo,
   database: "wabanex_test#{System.get_env("MIX_TEST_PARTITION")}",
   pool: Ecto.Adapters.SQL.Sandbox
diff --git a/test/growth/indicators/download_test.exs b/test/growth/indicators/download_test.exs
new file mode 100644
index 0000000..3bb4ba9
--- /dev/null
+++ b/test/growth/indicators/download_test.exs
@@ -0,0 +1,297 @@
+defmodule Growth.Indicators.DownloadTest do
+  @moduledoc false
+
+  use ExUnit.Case, async: true
+
+  alias Elixlsx.Sheet
+  alias Elixlsx.Workbook
+
+  alias Growth.Indicators.Download
+
+  setup do
+    mock_who_request()
+  end
+
+  describe "process/3" do
+    test "fetch excel from url and convert it to a list of lists" do
+      gender = :female
+      category = :age_tables
+
+      url =
+        "https://cdn.who.int/media/docs/default-source/child-growth/child-growth-standards/indicators/length-height-for-age/lhfa_girls_0-to-13-weeks_zscores.xlsx"
+
+      content = Download.process(gender, category, url)
+
+      expected_content =
+        [
+          ~w(source category gender age_unit age l m s sd3neg sd2neg sd1neg sd0 sd1 sd2 sd3),
+          [
+            url,
+            category,
+            gender,
+            "week",
+            Decimal.new("0"),
+            Decimal.new("1"),
+            Decimal.new("49.1477"),
+            Decimal.new("0.0379"),
+            Decimal.new("43.6"),
+            Decimal.new("45.4"),
+            Decimal.new("47.3"),
+            Decimal.new("49.1"),
+            Decimal.new("51"),
+            Decimal.new("52.9"),
+            Decimal.new("54.7")
+          ]
+        ]
+
+      assert expected_content == content
+    end
+  end
+
+  describe "process_gender/1" do
+    test "merge multiple contents into a single one" do
+      category = :age_tables
+      gender = :female
+
+      urls =
+        [
+          "https://cdn.who.int/media/docs/default-source/child-growth/child-growth-standards/indicators/length-height-for-age/lhfa_girls_0-to-13-weeks_zscores.xlsx",
+          "https://cdn.who.int/media/docs/default-source/child-growth/child-growth-standards/indicators/length-height-for-age/lhfa_girls_0-to-2-years_zscores.xlsx"
+        ]
+
+      content = Download.process_gender({gender, category, urls})
+
+      expected_content =
+        [
+          ~w(source category gender age_unit age l m s sd3neg sd2neg sd1neg sd0 sd1 sd2 sd3),
+          [
+            List.first(urls),
+            category,
+            gender,
+            "week",
+            Decimal.new("0"),
+            Decimal.new("1"),
+            Decimal.new("49.1477"),
+            Decimal.new("0.0379"),
+            Decimal.new("43.6"),
+            Decimal.new("45.4"),
+            Decimal.new("47.3"),
+            Decimal.new("49.1"),
+            Decimal.new("51"),
+            Decimal.new("52.9"),
+            Decimal.new("54.7")
+          ],
+          [
+            List.last(urls),
+            category,
+            gender,
+            "month",
+            Decimal.new("0"),
+            Decimal.new("1"),
+            Decimal.new("49.1477"),
+            Decimal.new("0.0379"),
+            Decimal.new("43.6"),
+            Decimal.new("45.4"),
+            Decimal.new("47.3"),
+            Decimal.new("49.1"),
+            Decimal.new("51"),
+            Decimal.new("52.9"),
+            Decimal.new("54.7")
+          ]
+        ]
+
+      assert expected_content == content
+    end
+  end
+
+  describe "process_genders/1" do
+    test "merge multiple genders and contents into a single one" do
+      female_urls = %{
+        age_tables: ~w(
+          https://cdn.who.int/media/docs/default-source/child-growth/child-growth-standards/indicators/length-height-for-age/lhfa_girls_0-to-13-weeks_zscores.xlsx
+          https://cdn.who.int/media/docs/default-source/child-growth/child-growth-standards/indicators/length-height-for-age/lhfa_girls_0-to-2-years_zscores.xlsx
+        ),
+        expanded_tables: ~w(
+          https://cdn.who.int/media/docs/default-source/child-growth/child-growth-standards/indicators/length-height-for-age/expandable-tables/lhfa-girls-zscore-expanded-tables.xlsx
+        )
+      }
+
+      male_urls = %{
+        age_tables: ~w(
+          https://cdn.who.int/media/docs/default-source/child-growth/child-growth-standards/indicators/length-height-for-age/lhfa_boys_0-to-13-weeks_zscores.xlsx
+          https://cdn.who.int/media/docs/default-source/child-growth/child-growth-standards/indicators/length-height-for-age/lhfa_boys_0-to-2-years_zscores.xlsx
+        ),
+        expanded_tables: ~w(
+          https://cdn.who.int/media/docs/default-source/child-growth/child-growth-standards/indicators/length-height-for-age/expandable-tables/lhfa-boys-zscore-expanded-tables.xlsx
+        )
+      }
+
+      content = Download.process_genders(%{female: female_urls, male: male_urls})
+
+      expected_content =
+        [
+          ~w(source category gender age_unit age l m s sd3neg sd2neg sd1neg sd0 sd1 sd2 sd3),
+          [
+            female_urls |> Map.get(:age_tables) |> List.first(),
+            :age,
+            :female,
+            "week",
+            Decimal.new("0"),
+            Decimal.new("1"),
+            Decimal.new("49.1477"),
+            Decimal.new("0.0379"),
+            Decimal.new("43.6"),
+            Decimal.new("45.4"),
+            Decimal.new("47.3"),
+            Decimal.new("49.1"),
+            Decimal.new("51"),
+            Decimal.new("52.9"),
+            Decimal.new("54.7")
+          ],
+          [
+            female_urls |> Map.get(:age_tables) |> List.last(),
+            :age,
+            :female,
+            "month",
+            Decimal.new("0"),
+            Decimal.new("1"),
+            Decimal.new("49.1477"),
+            Decimal.new("0.0379"),
+            Decimal.new("43.6"),
+            Decimal.new("45.4"),
+            Decimal.new("47.3"),
+            Decimal.new("49.1"),
+            Decimal.new("51"),
+            Decimal.new("52.9"),
+            Decimal.new("54.7")
+          ],
+          [
+            male_urls |> Map.get(:age_tables) |> List.first(),
+            :age,
+            :male,
+            "week",
+            Decimal.new("0"),
+            Decimal.new("1"),
+            Decimal.new("49.8842"),
+            Decimal.new("0.03795"),
+            Decimal.new("44.2"),
+            Decimal.new("46.1"),
+            Decimal.new("48"),
+            Decimal.new("49.9"),
+            Decimal.new("51.8"),
+            Decimal.new("53.7"),
+            Decimal.new("55.6")
+          ],
+          [
+            male_urls |> Map.get(:age_tables) |> List.last(),
+            :age,
+            :male,
+            "month",
+            Decimal.new("0"),
+            Decimal.new("1"),
+            Decimal.new("49.8842"),
+            Decimal.new("0.03795"),
+            Decimal.new("44.2"),
+            Decimal.new("46.1"),
+            Decimal.new("48"),
+            Decimal.new("49.9"),
+            Decimal.new("51.8"),
+            Decimal.new("53.7"),
+            Decimal.new("55.6")
+          ],
+          [
+            female_urls |> Map.get(:expanded_tables) |> List.first(),
+            :expanded,
+            :female,
+            "day",
+            Decimal.new("0"),
+            Decimal.new("1"),
+            Decimal.new("49.1477"),
+            Decimal.new("0.0379"),
+            Decimal.new("43.56"),
+            Decimal.new("45.422"),
+            Decimal.new("47.285"),
+            Decimal.new("49.148"),
+            Decimal.new("51.01"),
+            Decimal.new("52.873"),
+            Decimal.new("54.736")
+          ],
+          [
+            male_urls |> Map.get(:expanded_tables) |> List.first(),
+            :expanded,
+            :male,
+            "day",
+            Decimal.new("0"),
+            Decimal.new("1"),
+            Decimal.new("49.8842"),
+            Decimal.new("0.03795"),
+            Decimal.new("44.205"),
+            Decimal.new("46.098"),
+            Decimal.new("47.991"),
+            Decimal.new("49.884"),
+            Decimal.new("51.777"),
+            Decimal.new("53.67"),
+            Decimal.new("55.564")
+          ]
+        ]
+
+      assert expected_content == content
+    end
+  end
+
+  defp mock_who_request do
+    Req.Test.stub(Growth.Indicators.Download.WHO, fn %Plug.Conn{path_info: path_info} = conn ->
+      filename = List.last(path_info)
+
+      rows =
+        case filename do
+          "lhfa_girls_0-to-13-weeks_zscores.xlsx" ->
+            [
+              ~w(Week L M S SD SD3neg SD2neg SD1neg SD0 SD1 SD2 SD3),
+              ~w(0 1 49.1477 0.0379 1.8627 43.6 45.4 47.3 49.1 51 52.9 54.7)
+            ]
+
+          "lhfa_girls_0-to-2-years_zscores.xlsx" ->
+            [
+              ~w(Month L M S SD SD3neg SD2neg SD1neg SD0 SD1 SD2 SD3),
+              ~w(0 1 49.1477 0.0379 1.8627 43.6 45.4 47.3 49.1 51 52.9 54.7)
+            ]
+
+          "lhfa-girls-zscore-expanded-tables.xlsx" ->
+            [
+              ~w(Day L M S SD4neg SD3neg SD2neg SD1neg SD0 SD1 SD2 SD3 SD4),
+              ~w(0 1 49.1477 0.0379 41.697 43.56 45.422 47.285 49.148 51.01 52.873 54.736 56.598)
+            ]
+
+          "lhfa_boys_0-to-13-weeks_zscores.xlsx" ->
+            [
+              ~w(Week L M S SD SD3neg SD2neg SD1neg SD0 SD1 SD2 SD3),
+              ~w(0 1 49.8842 0.03795 1.8931 44.2 46.1 48 49.9 51.8 53.7 55.6)
+            ]
+
+          "lhfa_boys_0-to-2-years_zscores.xlsx" ->
+            [
+              ~w(Month L M S SD SD3neg SD2neg SD1neg SD0 SD1 SD2 SD3),
+              ~w(0 1 49.8842 0.03795 1.8931 44.2 46.1 48 49.9 51.8 53.7 55.6)
+            ]
+
+          "lhfa-boys-zscore-expanded-tables.xlsx" ->
+            [
+              ~w(Day L M S SD4neg SD3neg SD2neg SD1neg SD0 SD1 SD2 SD3 SD4),
+              ~w(0 1 49.8842 0.03795 42.312 44.205 46.098 47.991 49.884 51.777 53.67 55.564 57.457)
+            ]
+        end
+
+      {:ok, {_charlist_content, content}} =
+        %Sheet{name: "zscore", rows: rows}
+        |> then(&%Workbook{sheets: [&1]})
+        |> Elixlsx.write_to_memory(filename)
+
+      conn
+      |> Plug.Conn.put_resp_content_type(
+        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
+      )
+      |> Plug.Conn.send_resp(200, content)
+    end)
+  end
+end