feat(accounts): derive 10-char home_grid from explicit lat/lon
This commit is contained in:
parent
9796f06ba2
commit
9bfd345e8d
2 changed files with 50 additions and 3 deletions
|
|
@ -220,9 +220,10 @@ defmodule Microwaveprop.Accounts.User do
|
||||||
|
|
||||||
Accepts either a Maidenhead grid or an explicit lat/lon. When only the
|
Accepts either a Maidenhead grid or an explicit lat/lon. When only the
|
||||||
grid is given, lat/lon are derived from its centre; when only lat/lon
|
grid is given, lat/lon are derived from its centre; when only lat/lon
|
||||||
are given, the grid is left untouched. An empty `home_grid` paired
|
are given, a 10-character grid is computed from the coordinate pair so
|
||||||
with explicit nil lat/lon clears all home fields (used by the "clear
|
callers always end up with both fields populated. An empty `home_grid`
|
||||||
home" affordance on /rover).
|
paired with explicit nil lat/lon clears all home fields (used by the
|
||||||
|
"clear home" affordance on /rover).
|
||||||
"""
|
"""
|
||||||
@spec change_home_qth(t() | Ecto.Changeset.t(), map()) :: Ecto.Changeset.t()
|
@spec change_home_qth(t() | Ecto.Changeset.t(), map()) :: Ecto.Changeset.t()
|
||||||
def change_home_qth(user, attrs) do
|
def change_home_qth(user, attrs) do
|
||||||
|
|
@ -231,6 +232,7 @@ defmodule Microwaveprop.Accounts.User do
|
||||||
|> normalize_home_grid()
|
|> normalize_home_grid()
|
||||||
|> validate_home_grid_format()
|
|> validate_home_grid_format()
|
||||||
|> derive_home_latlon_from_grid()
|
|> derive_home_latlon_from_grid()
|
||||||
|
|> derive_home_grid_from_latlon()
|
||||||
|> validate_home_latlon_range()
|
|> validate_home_latlon_range()
|
||||||
|> require_home_qth_pair()
|
|> require_home_qth_pair()
|
||||||
end
|
end
|
||||||
|
|
@ -294,6 +296,30 @@ defmodule Microwaveprop.Accounts.User do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# If lat/lon were provided without a grid, encode a 10-char Maidenhead
|
||||||
|
# grid from the coordinates so the UI always has a human-readable label
|
||||||
|
# to render and downstream callers can rely on `home_grid` being set
|
||||||
|
# whenever the QTH is set. Skipped on invalid changesets (lat/lon range
|
||||||
|
# check has not run yet) and when both fields aren't numeric.
|
||||||
|
defp derive_home_grid_from_latlon(changeset) do
|
||||||
|
lat = get_field(changeset, :home_lat)
|
||||||
|
lon = get_field(changeset, :home_lon)
|
||||||
|
|
||||||
|
cond do
|
||||||
|
not changeset.valid? ->
|
||||||
|
changeset
|
||||||
|
|
||||||
|
not (is_number(lat) and is_number(lon)) ->
|
||||||
|
changeset
|
||||||
|
|
||||||
|
get_field(changeset, :home_grid) not in [nil, ""] ->
|
||||||
|
changeset
|
||||||
|
|
||||||
|
true ->
|
||||||
|
put_change(changeset, :home_grid, Maidenhead.from_latlon(lat * 1.0, lon * 1.0, 10))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp validate_home_latlon_range(changeset) do
|
defp validate_home_latlon_range(changeset) do
|
||||||
changeset
|
changeset
|
||||||
|> validate_number(:home_lat, greater_than_or_equal_to: -90.0, less_than_or_equal_to: 90.0)
|
|> validate_number(:home_lat, greater_than_or_equal_to: -90.0, less_than_or_equal_to: 90.0)
|
||||||
|
|
|
||||||
|
|
@ -461,6 +461,27 @@ defmodule Microwaveprop.Accounts.UserTest do
|
||||||
assert Ecto.Changeset.get_change(changeset, :home_lon) == -96.7
|
assert Ecto.Changeset.get_change(changeset, :home_lon) == -96.7
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "derives a 10-char home_grid when lat/lon are given without one" do
|
||||||
|
changeset = User.change_home_qth(%User{}, %{"home_lat" => 33.10, "home_lon" => -96.625})
|
||||||
|
assert changeset.valid?
|
||||||
|
grid = Ecto.Changeset.get_change(changeset, :home_grid)
|
||||||
|
assert is_binary(grid)
|
||||||
|
assert String.length(grid) == 10
|
||||||
|
assert String.starts_with?(grid, "EM13qc")
|
||||||
|
end
|
||||||
|
|
||||||
|
test "preserves an explicit grid when both grid and lat/lon are provided" do
|
||||||
|
changeset =
|
||||||
|
User.change_home_qth(%User{}, %{
|
||||||
|
"home_grid" => "EM13qc",
|
||||||
|
"home_lat" => 33.10,
|
||||||
|
"home_lon" => -96.625
|
||||||
|
})
|
||||||
|
|
||||||
|
assert changeset.valid?
|
||||||
|
assert Ecto.Changeset.get_change(changeset, :home_grid) == "EM13qc"
|
||||||
|
end
|
||||||
|
|
||||||
test "rejects invalid grids" do
|
test "rejects invalid grids" do
|
||||||
changeset = User.change_home_qth(%User{}, %{"home_grid" => "ZZ99zz"})
|
changeset = User.change_home_qth(%User{}, %{"home_grid" => "ZZ99zz"})
|
||||||
refute changeset.valid?
|
refute changeset.valid?
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue