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