From 2487855c7957dd674a00019fd8b82e00b8b4d071 Mon Sep 17 00:00:00 2001 From: Cam Cook Date: Thu, 22 May 2025 22:31:43 -0400 Subject: [PATCH 1/3] test(packages): factory test --- lib/aura/util/requester.ex | 2 +- .../model/aura/model/hex_package_test.exs | 14 ++++ test/support/factories/hex_package_factory.ex | 68 +++++++++++++++++++ test/support/factory.ex | 1 + 4 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 test/aura/model/aura/model/hex_package_test.exs create mode 100644 test/support/factories/hex_package_factory.ex diff --git a/lib/aura/util/requester.ex b/lib/aura/util/requester.ex index d390dff..f8919c7 100644 --- a/lib/aura/util/requester.ex +++ b/lib/aura/util/requester.ex @@ -67,7 +67,7 @@ defmodule Aura.Requester do version = config[:version] || "0.0.0" e_version = System.version() mix_env = Mix.env() - user_agent = "#{app}/#{version} (Elixir/#{e_version}) (OTP/#{otp_version()})(#{mix_env})" + user_agent = IO.inspect("#{app}/#{version} (Elixir/#{e_version}) (OTP/#{otp_version()}) (#{mix_env})") {"User-Agent", user_agent} end diff --git a/test/aura/model/aura/model/hex_package_test.exs b/test/aura/model/aura/model/hex_package_test.exs new file mode 100644 index 0000000..c7bd2c1 --- /dev/null +++ b/test/aura/model/aura/model/hex_package_test.exs @@ -0,0 +1,14 @@ +defmodule Aura.Model.HexPackageTest do + use ExUnit.Case + + import Aura.Factory + + alias Aura.Model.HexPackage + + doctest HexPackage + + test "build many" do + list = build_list(100, :hex_package) + assert Enum.count(list) == 100 + end +end diff --git a/test/support/factories/hex_package_factory.ex b/test/support/factories/hex_package_factory.ex new file mode 100644 index 0000000..cebbe89 --- /dev/null +++ b/test/support/factories/hex_package_factory.ex @@ -0,0 +1,68 @@ +defmodule Aura.Factory.HexPackageFactory do + @moduledoc false + + defmacro __using__(_opts) do + quote do + def hex_package_factory(attrs) do + inserted_at = Faker.DateTime.backward(40) + meta = build(:package_meta) + downloads = build(:package_downloads) + releases = build_list(5, :package_release) + + %Aura.Model.HexPackage{ + name: Faker.Internet.user_name(), + repository: Faker.Internet.user_name(), + private: Enum.random([true, false]), + meta: meta, + downloads: downloads, + releases: releases, + inserted_at: inserted_at, + url: Faker.Internet.url(), + html_url: Faker.Internet.url(), + docs_html_url: Faker.Internet.url(), + updated_at: Faker.DateTime.between(inserted_at, DateTime.now!("Etc/UTC")) + } + |> merge_attributes(attrs) + |> evaluate_lazy_attributes() + end + + def package_meta_factory(attrs) do + %Aura.Model.PackageMeta{ + maintainers: Enum.map(1..5, fn _ -> Faker.Internet.user_name() end), + links: Enum.map(1..5, fn _ -> Faker.Internet.url() end), + licenses: Enum.map(1..5, fn _ -> Faker.Internet.slug() end), + description: Faker.Lorem.sentence() + } + |> merge_attributes(attrs) + |> evaluate_lazy_attributes() + end + + def package_downloads_factory(attrs) do + day = Faker.random_between(10, 100) + week = day + Faker.random_between(10, 100) + all = week + Faker.random_between(10, 100) + + %Aura.Model.DownloadStats{ + all: all, + week: week, + day: day + } + |> merge_attributes(attrs) + |> evaluate_lazy_attributes() + end + + def package_release_factory(attrs) do + day = Faker.random_between(10, 100) + week = day + Faker.random_between(10, 100) + all = week + Faker.random_between(10, 100) + + %Aura.Model.Release{ + version: Faker.App.semver(), + url: Faker.Internet.url() + } + |> merge_attributes(attrs) + |> evaluate_lazy_attributes() + end + end + end +end diff --git a/test/support/factory.ex b/test/support/factory.ex index cf8b135..846a6ac 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -2,4 +2,5 @@ defmodule Aura.Factory do @moduledoc false use ExMachina use Aura.Factory.HexRepoFactory + use Aura.Factory.HexPackageFactory end From 4ec1b446d632f9a11ec18230a358f08081a75d5a Mon Sep 17 00:00:00 2001 From: Cam Cook Date: Fri, 23 May 2025 02:59:24 -0400 Subject: [PATCH 2/3] feat(releases): get_release --- lib/aura/model/hex_package.ex | 21 +------- lib/aura/model/hex_release.ex | 48 +++++++++++++++++++ lib/aura/releases.ex | 12 +++++ test/aura/releases_test.exs | 20 ++++++++ test/support/factories/hex_package_factory.ex | 6 +-- 5 files changed, 85 insertions(+), 22 deletions(-) create mode 100644 lib/aura/model/hex_release.ex create mode 100644 lib/aura/releases.ex create mode 100644 test/aura/releases_test.exs diff --git a/lib/aura/model/hex_package.ex b/lib/aura/model/hex_package.ex index 959150d..aff222b 100644 --- a/lib/aura/model/hex_package.ex +++ b/lib/aura/model/hex_package.ex @@ -5,8 +5,8 @@ defmodule Aura.Model.HexPackage do alias Aura.Model.DownloadStats alias Aura.Model.HexPackage + alias Aura.Model.HexRelease alias Aura.Model.PackageMeta - alias Aura.Model.Release DownloadStats @@ -36,7 +36,7 @@ defmodule Aura.Model.HexPackage do defp serialize(:meta, v), do: PackageMeta.build(v) defp serialize(:downloads, v), do: DownloadStats.build(v) - defp serialize(:releases, v), do: Enum.map(v, &Release.build/1) + defp serialize(:releases, v), do: Enum.map(v, &HexRelease.build/1) defp serialize(_k, v), do: v end @@ -47,7 +47,6 @@ defmodule Aura.Model.PackageMeta do import Aura.Model.Common defstruct [ - # :maintainers, :links, :licenses, @@ -75,19 +74,3 @@ defmodule Aura.Model.DownloadStats do struct(Aura.Model.DownloadStats, fields) end end - -defmodule Aura.Model.Release do - @moduledoc false - - import Aura.Model.Common - - defstruct [ - :version, - :url - ] - - def build(m) when is_map(m) do - fields = prepare(m) - struct(Aura.Model.Release, fields) - end -end diff --git a/lib/aura/model/hex_release.ex b/lib/aura/model/hex_release.ex new file mode 100644 index 0000000..bd592d0 --- /dev/null +++ b/lib/aura/model/hex_release.ex @@ -0,0 +1,48 @@ +defmodule Aura.Model.HexRelease do + @moduledoc false + + import Aura.Model.Common + + defstruct [ + :checksum, + :configs, + :docs_html_url, + :downloads, + :has_docs, + :html_url, + :inserted_at, + :meta, + :package_url, + :publisher, + :requirements, + :retirement, + :updated_at, + :version, + :url + ] + + def build(m) when is_map(m) do + fields = + m + |> prepare() + |> Enum.map(fn {k, v} -> {k, serialize(k, v)} end) + + struct(Aura.Model.HexRelease, fields) + end + + defp serialize(_k, nil), do: nil + defp serialize(:meta, v), do: prepare(v) + defp serialize(:publisher, v), do: prepare(v) + + defp serialize(:requirements, v) do + v + |> Map.values() + |> Enum.map(&prepare/1) + end + + defp serialize(:retirement, v) do + v |> prepare() |> Map.new() + end + + defp serialize(_k, v), do: v +end diff --git a/lib/aura/releases.ex b/lib/aura/releases.ex new file mode 100644 index 0000000..7f2e0f6 --- /dev/null +++ b/lib/aura/releases.ex @@ -0,0 +1,12 @@ +defmodule Aura.Releases do + @moduledoc false + + alias Aura.Model.HexRelease + alias Aura.Requester + + def get_release(package_name, version) do + with {:ok, %{body: body}} <- Requester.get("/packages/#{package_name}/releases/#{version}") do + {:ok, HexRelease.build(body)} + end + end +end diff --git a/test/aura/releases_test.exs b/test/aura/releases_test.exs new file mode 100644 index 0000000..92cd595 --- /dev/null +++ b/test/aura/releases_test.exs @@ -0,0 +1,20 @@ +defmodule Aura.ReleasesTest do + use ExUnit.Case + + alias Aura.Packages + alias Aura.Releases + + @moduletag :capture_log + + doctest Releases + + test "get_release" do + [package] = Enum.take(Packages.list_packages(), 1) + version = package.releases |> hd() |> Map.get(:version) + assert {:ok, release} = Releases.get_release(package.name, version) + assert release.checksum + + assert {:ok, release} = Releases.get_release("ex_ftp", "0.9.2") + assert release.retirement.message + end +end diff --git a/test/support/factories/hex_package_factory.ex b/test/support/factories/hex_package_factory.ex index cebbe89..5d5647c 100644 --- a/test/support/factories/hex_package_factory.ex +++ b/test/support/factories/hex_package_factory.ex @@ -7,7 +7,7 @@ defmodule Aura.Factory.HexPackageFactory do inserted_at = Faker.DateTime.backward(40) meta = build(:package_meta) downloads = build(:package_downloads) - releases = build_list(5, :package_release) + releases = build_list(5, :hex_release) %Aura.Model.HexPackage{ name: Faker.Internet.user_name(), @@ -51,12 +51,12 @@ defmodule Aura.Factory.HexPackageFactory do |> evaluate_lazy_attributes() end - def package_release_factory(attrs) do + def hex_release_factory(attrs) do day = Faker.random_between(10, 100) week = day + Faker.random_between(10, 100) all = week + Faker.random_between(10, 100) - %Aura.Model.Release{ + %Aura.Model.HexRelease{ version: Faker.App.semver(), url: Faker.Internet.url() } From 71113e867fb7eb7edcb7a0a446cde804c20cedbf Mon Sep 17 00:00:00 2001 From: Cam Cook Date: Fri, 23 May 2025 03:41:38 -0400 Subject: [PATCH 3/3] test(releases): factory test --- lib/aura/model/hex_release.ex | 12 ++-- lib/aura/util/requester.ex | 2 +- .../{aura/model => }/hex_package_test.exs | 0 test/aura/model/hex_release_test.exs | 15 +++++ .../model/{aura/model => }/hex_repo_test.exs | 0 test/aura/releases_test.exs | 2 +- test/support/factories/hex_package_factory.ex | 13 ---- test/support/factories/hex_release_factory.ex | 61 +++++++++++++++++++ test/support/factory.ex | 1 + 9 files changed, 86 insertions(+), 20 deletions(-) rename test/aura/model/{aura/model => }/hex_package_test.exs (100%) create mode 100644 test/aura/model/hex_release_test.exs rename test/aura/model/{aura/model => }/hex_repo_test.exs (100%) create mode 100644 test/support/factories/hex_release_factory.ex diff --git a/lib/aura/model/hex_release.ex b/lib/aura/model/hex_release.ex index bd592d0..4c9de8e 100644 --- a/lib/aura/model/hex_release.ex +++ b/lib/aura/model/hex_release.ex @@ -25,23 +25,25 @@ defmodule Aura.Model.HexRelease do fields = m |> prepare() - |> Enum.map(fn {k, v} -> {k, serialize(k, v)} end) + |> Map.new(fn {k, v} -> {k, serialize(k, v)} end) struct(Aura.Model.HexRelease, fields) end defp serialize(_k, nil), do: nil - defp serialize(:meta, v), do: prepare(v) - defp serialize(:publisher, v), do: prepare(v) + defp serialize(:meta, v), do: v |> prepare() |> Map.new() + defp serialize(:publisher, v), do: v |> prepare() |> Map.new() defp serialize(:requirements, v) do v |> Map.values() - |> Enum.map(&prepare/1) + |> Enum.map(fn m -> m |> prepare() |> Map.new() end) end defp serialize(:retirement, v) do - v |> prepare() |> Map.new() + v + |> prepare() + |> Map.new(fn {k, v} -> if k == :reason, do: {k, String.to_atom(v)}, else: {k, v} end) end defp serialize(_k, v), do: v diff --git a/lib/aura/util/requester.ex b/lib/aura/util/requester.ex index f8919c7..19a79bc 100644 --- a/lib/aura/util/requester.ex +++ b/lib/aura/util/requester.ex @@ -67,7 +67,7 @@ defmodule Aura.Requester do version = config[:version] || "0.0.0" e_version = System.version() mix_env = Mix.env() - user_agent = IO.inspect("#{app}/#{version} (Elixir/#{e_version}) (OTP/#{otp_version()}) (#{mix_env})") + user_agent = "#{app}/#{version} (Elixir/#{e_version}) (OTP/#{otp_version()}) (#{mix_env})" {"User-Agent", user_agent} end diff --git a/test/aura/model/aura/model/hex_package_test.exs b/test/aura/model/hex_package_test.exs similarity index 100% rename from test/aura/model/aura/model/hex_package_test.exs rename to test/aura/model/hex_package_test.exs diff --git a/test/aura/model/hex_release_test.exs b/test/aura/model/hex_release_test.exs new file mode 100644 index 0000000..c311138 --- /dev/null +++ b/test/aura/model/hex_release_test.exs @@ -0,0 +1,15 @@ +defmodule Aura.Model.HexReleaseTest do + use ExUnit.Case + + import Aura.Factory + + alias Aura.Model.HexRelease + + @moduletag :capture_log + doctest HexRelease + + test "build many" do + list = build_list(100, :hex_release) + assert Enum.count(list) == 100 + end +end diff --git a/test/aura/model/aura/model/hex_repo_test.exs b/test/aura/model/hex_repo_test.exs similarity index 100% rename from test/aura/model/aura/model/hex_repo_test.exs rename to test/aura/model/hex_repo_test.exs diff --git a/test/aura/releases_test.exs b/test/aura/releases_test.exs index 92cd595..74a7bd8 100644 --- a/test/aura/releases_test.exs +++ b/test/aura/releases_test.exs @@ -12,7 +12,7 @@ defmodule Aura.ReleasesTest do [package] = Enum.take(Packages.list_packages(), 1) version = package.releases |> hd() |> Map.get(:version) assert {:ok, release} = Releases.get_release(package.name, version) - assert release.checksum + assert release.publisher assert {:ok, release} = Releases.get_release("ex_ftp", "0.9.2") assert release.retirement.message diff --git a/test/support/factories/hex_package_factory.ex b/test/support/factories/hex_package_factory.ex index 5d5647c..03cff62 100644 --- a/test/support/factories/hex_package_factory.ex +++ b/test/support/factories/hex_package_factory.ex @@ -50,19 +50,6 @@ defmodule Aura.Factory.HexPackageFactory do |> merge_attributes(attrs) |> evaluate_lazy_attributes() end - - def hex_release_factory(attrs) do - day = Faker.random_between(10, 100) - week = day + Faker.random_between(10, 100) - all = week + Faker.random_between(10, 100) - - %Aura.Model.HexRelease{ - version: Faker.App.semver(), - url: Faker.Internet.url() - } - |> merge_attributes(attrs) - |> evaluate_lazy_attributes() - end end end end diff --git a/test/support/factories/hex_release_factory.ex b/test/support/factories/hex_release_factory.ex new file mode 100644 index 0000000..904ae7e --- /dev/null +++ b/test/support/factories/hex_release_factory.ex @@ -0,0 +1,61 @@ +defmodule Aura.Factory.HexReleaseFactory do + @moduledoc false + + defmacro __using__(_opts) do + quote do + def hex_release_factory(attrs) do + name = Faker.Internet.slug() + + requirements = + Enum.map(1..5, fn _ -> + %{optional: Enum.random([true, false]), app: Faker.Internet.slug(), requirement: "~> #{Faker.App.semver()}"} + end) + + meta = %{elixir: "~> 1.18", app: name, build_tools: ["mix"]} + + configs = + %{ + "erlang.mk" => "#{name} = hex 0.9.2", + "mix.exs" => "{:#{name}, \"~> 0.9.2\"}", + "rebar.config" => "{#{name}, \"0.9.2\"}" + } + + publisher = + Enum.map(1..5, fn _ -> + %{url: Faker.Internet.url(), email: Faker.Internet.email(), username: Faker.Internet.user_name()} + end) + + inserted_at = Faker.DateTime.backward(40) + has_docs = Enum.random([true, false]) + docs_html_url = if has_docs, do: Faker.Internet.url() + retired? = Enum.random([true, false]) + + retirement = + if retired?, + do: %{ + message: Faker.Lorem.sentence(), + reason: Enum.random([:other, :invalid, :security, :deprecated, :renamed]) + } + + %Aura.Model.HexRelease{ + configs: configs, + meta: meta, + checksum: Faker.Lorem.characters(65), + version: Faker.App.semver(), + url: Faker.Internet.url(), + docs_html_url: docs_html_url, + html_url: Faker.Internet.url(), + has_docs: has_docs, + package_url: Faker.Internet.url(), + downloads: Faker.random_between(10, 100), + publisher: publisher, + retirement: retirement, + inserted_at: inserted_at, + updated_at: Faker.DateTime.between(inserted_at, DateTime.now!("Etc/UTC")) + } + |> merge_attributes(attrs) + |> evaluate_lazy_attributes() + end + end + end +end diff --git a/test/support/factory.ex b/test/support/factory.ex index 846a6ac..b69d14a 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -3,4 +3,5 @@ defmodule Aura.Factory do use ExMachina use Aura.Factory.HexRepoFactory use Aura.Factory.HexPackageFactory + use Aura.Factory.HexReleaseFactory end