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
|
||||
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
|
||||
with explicit nil lat/lon clears all home fields (used by the "clear
|
||||
home" affordance on /rover).
|
||||
are given, a 10-character grid is computed from the coordinate pair so
|
||||
callers always end up with both fields populated. An empty `home_grid`
|
||||
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()
|
||||
def change_home_qth(user, attrs) do
|
||||
|
|
@ -231,6 +232,7 @@ defmodule Microwaveprop.Accounts.User do
|
|||
|> normalize_home_grid()
|
||||
|> validate_home_grid_format()
|
||||
|> derive_home_latlon_from_grid()
|
||||
|> derive_home_grid_from_latlon()
|
||||
|> validate_home_latlon_range()
|
||||
|> require_home_qth_pair()
|
||||
end
|
||||
|
|
@ -294,6 +296,30 @@ defmodule Microwaveprop.Accounts.User do
|
|||
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
|
||||
changeset
|
||||
|> 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
|
||||
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
|
||||
changeset = User.change_home_qth(%User{}, %{"home_grid" => "ZZ99zz"})
|
||||
refute changeset.valid?
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue