Skip to content

Commit 38063a4

Browse files
authored
Handle latest version fallback (#157)
1 parent 00fef0a commit 38063a4

2 files changed

Lines changed: 53 additions & 7 deletions

File tree

lib/diff_web/live/diff_live_view.ex

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ defmodule DiffWeb.DiffLiveView do
1616
mount_single_diff(socket, package, resolved_from, resolved_to)
1717

1818
{:error, reason} ->
19-
{:ok, assign(socket, error: "Package not found: #{reason}")}
19+
{:ok, assign(socket, error: latest_version_error(package, reason))}
2020
end
2121

2222
:error ->
@@ -117,13 +117,15 @@ defmodule DiffWeb.DiffLiveView do
117117
defp resolve_latest_version(package, from, to) when to == :latest or to == "latest" do
118118
case Diff.Package.Store.get_versions(package) do
119119
{:ok, versions} ->
120-
to =
121-
versions
122-
|> Enum.map(&Version.parse!/1)
123-
|> Enum.filter(&(&1.pre == []))
124-
|> Enum.max(Version)
120+
versions = Enum.map(versions, &Version.parse!/1)
125121

126-
{:ok, from, to_string(to)}
122+
case latest_version(versions) do
123+
nil ->
124+
{:error, :no_versions}
125+
126+
to ->
127+
{:ok, from, to_string(to)}
128+
end
127129

128130
{:error, :not_found} ->
129131
{:error, :not_found}
@@ -132,6 +134,22 @@ defmodule DiffWeb.DiffLiveView do
132134

133135
defp resolve_latest_version(_package, from, to), do: {:ok, from, to}
134136

137+
defp latest_version([]), do: nil
138+
139+
defp latest_version(versions) do
140+
stable_versions = Enum.filter(versions, &(&1.pre == []))
141+
142+
case stable_versions do
143+
[] -> Enum.max(versions, Version)
144+
stable_versions -> Enum.max(stable_versions, Version)
145+
end
146+
end
147+
148+
defp latest_version_error(package, :not_found), do: "Package not found: #{package}"
149+
150+
defp latest_version_error(package, :no_versions),
151+
do: "No versions found for package: #{package}"
152+
135153
def handle_event("load-more", _params, socket) do
136154
batch_size = 5
137155
{next_batch, _remaining} = Enum.split(socket.assigns.remaining_diffs, batch_size)

test/diff_web/integration_test.exs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,34 @@ defmodule DiffWeb.IntegrationTest do
4040
assert html =~ "Generating diffs"
4141
end
4242

43+
test "/diff with implicit latest handles packages without stable versions", %{conn: conn} do
44+
Diff.Package.StoreMock
45+
|> stub(:get_versions, fn "prerelease_only" ->
46+
{:ok, ["1.0.0-alpha.1", "1.0.0-rc.1", "1.0.0-rc.2"]}
47+
end)
48+
49+
Diff.StorageMock
50+
|> stub(:get_metadata, fn "prerelease_only", "0.1.0", "1.0.0-rc.2" ->
51+
{:error, :not_found}
52+
end)
53+
54+
Diff.HexMock
55+
|> stub(:diff, fn "prerelease_only", "0.1.0", "1.0.0-rc.2" -> :error end)
56+
57+
{:ok, _view, html} = live(conn, "/diff/prerelease_only/0.1.0..")
58+
59+
assert html =~ "Generating diffs"
60+
end
61+
62+
test "/diff with implicit latest handles packages with an empty version list", %{conn: conn} do
63+
Diff.Package.StoreMock
64+
|> stub(:get_versions, fn "empty" -> {:ok, []} end)
65+
66+
{:ok, _view, html} = live(conn, "/diff/empty/0.1.0..")
67+
68+
assert html =~ "No versions found for package: empty"
69+
end
70+
4371
test "/diff handles package not found", %{conn: conn} do
4472
Diff.Package.StoreMock
4573
|> stub(:get_versions, fn "nonexistent" -> {:error, :not_found} end)

0 commit comments

Comments
 (0)