aprs.me/test/aprsme_web/aprs_symbol_test.exs
Graham McIntire 1e32ce7051
Improve test coverage to 87% and point vendor/aprs submodule at codeberg
Coverage:
- Adds focused tests across 13 files covering previously-uncovered
  branches: Packet changeset normalisation (course, wind_direction,
  struct data_extended); Packets store_packet edge cases (nested
  position shapes, ssid handling, string-keyed raw_packet);
  DeviceIdentification HTTP success/404 via Req plug stub; ResendAdapter
  catch-all body, deliver_many, nil/binary formatters; ApiDocsLive
  packets with missing fields; AprsSymbol normalize helpers;
  BadPacketsLive refresh and postgres_notify; MobileChannel handle_info
  catch-all and postgres_packet path; PacketProcessor existing-marker
  movement detection; PacketReplay sanitize_value type clauses;
  InsertOptimizer GenServer lifecycle and negative-duration metric;
  PageController shutdown-handler integration; UrlParams delegated
  helpers.
- mix.exs: configure test_coverage with summary threshold of 87 and
  ignore_modules for test fixtures and macro-only template modules.

Bug fix:
- MapLive.Index handle_info: add a clause for the raw {:new_deployment,
  _} tuple. Phoenix.PubSub.broadcast delivers the raw payload to plain
  subscribers, but the existing handler only matched the %Broadcast{}
  fast-lane wrapper. DeploymentNotifier broadcasts via the raw path,
  which crashed the LiveView under test concurrency.

Submodule:
- Update .gitmodules vendor/aprs URL from
  https://github.com/aprsme/aprs.git to
  ssh://git@codeberg.org/gmcintire/aprs.git.
2026-05-05 15:18:28 -05:00

178 lines
6.6 KiB
Elixir

defmodule AprsmeWeb.AprsSymbolTest do
use ExUnit.Case, async: true
alias AprsmeWeb.AprsSymbol
describe "overlay symbol rendering" do
test "D& should show black diamond background from table 1" do
# Test the get_sprite_info for overlay symbol D&
sprite_info = AprsSymbol.get_sprite_info("D", "&")
# Should use table 1 for the diamond background (alternate table)
assert sprite_info.sprite_file == "/aprs-symbols/aprs-symbols-128-1@2x.png"
# Calculate expected position for & (ASCII 38)
# index = 38 - 33 = 5
# column = 5 % 16 = 5
# row = 5 / 16 = 0
# x = -5 * 128 = -640
# y = -0 * 128 = 0
# scaled: x/4 = -160, y/4 = 0
assert sprite_info.background_position == "-160.0px 0.0px"
end
test "N# should show green star background from table 1" do
# Test the get_sprite_info for overlay symbol N#
sprite_info = AprsSymbol.get_sprite_info("N", "#")
# Should use table 1 for the green star background
assert sprite_info.sprite_file == "/aprs-symbols/aprs-symbols-128-1@2x.png"
# Calculate expected position for # (ASCII 35)
# index = 35 - 33 = 2
# column = 2 % 16 = 2
# row = 2 / 16 = 0
# x = -2 * 128 = -256
# y = -0 * 128 = 0
# scaled: x/4 = -64, y/4 = 0
assert sprite_info.background_position == "-64.0px 0.0px"
end
test "overlay character sprite info for D" do
# Test getting the overlay character sprite for letter D
overlay_info = AprsSymbol.get_overlay_character_sprite_info("D")
# Should use table 2 for overlay characters
assert overlay_info.sprite_file == "/aprs-symbols/aprs-symbols-128-2@2x.png"
# Calculate expected position for D (ASCII 68)
# index = 68 - 33 = 35
# column = 35 % 16 = 3
# row = 35 / 16 = 2
# x = -3 * 128 = -384
# y = -2 * 128 = -256
# scaled: x/4 = -96, y/4 = -64
assert overlay_info.background_position == "-96.0px -64.0px"
end
test "overlay character sprite info for N" do
# Test getting the overlay character sprite for letter N
overlay_info = AprsSymbol.get_overlay_character_sprite_info("N")
# Should use table 2 for overlay characters
assert overlay_info.sprite_file == "/aprs-symbols/aprs-symbols-128-2@2x.png"
# Calculate expected position for N (ASCII 78)
# index = 78 - 33 = 45
# column = 45 % 16 = 13
# row = 45 / 16 = 2
# x = -13 * 128 = -1664
# y = -2 * 128 = -256
# scaled: x/4 = -416, y/4 = -64
assert overlay_info.background_position == "-416.0px -64.0px"
end
test "render_marker_html for overlay symbol D&" do
html = AprsSymbol.render_marker_html("D", "&", "W5MRC-15", 32)
# Should contain both background images (overlay first from table 2, base from table 1)
assert html =~
"background-image: url(/aprs-symbols/aprs-symbols-128-2@2x.png), url(/aprs-symbols/aprs-symbols-128-1@2x.png)"
# Should have both background positions (overlay first, then base)
assert html =~ "background-position: -96.0px -64.0px, -160.0px 0.0px"
# Should include the callsign
assert html =~ "W5MRC-15"
end
test "render_marker_html for overlay symbol N#" do
html = AprsSymbol.render_marker_html("N", "#", "TEST-1", 32)
# Should contain both background images (overlay first from table 2, base from table 1)
assert html =~
"background-image: url(/aprs-symbols/aprs-symbols-128-2@2x.png), url(/aprs-symbols/aprs-symbols-128-1@2x.png)"
# Should have both background positions (overlay first, then base)
assert html =~ "background-position: -416.0px -64.0px, -64.0px 0.0px"
# Should include the callsign
assert html =~ "TEST-1"
end
test "normal symbol /_" do
# Test a normal symbol from primary table
sprite_info = AprsSymbol.get_sprite_info("/", "_")
assert sprite_info.sprite_file == "/aprs-symbols/aprs-symbols-128-0@2x.png"
# Calculate expected position for _ (ASCII 95)
# index = 95 - 33 = 62
# column = 62 % 16 = 14
# row = 62 / 16 = 3
# x = -14 * 128 = -1792
# y = -3 * 128 = -384
# scaled: x/4 = -448, y/4 = -96
assert sprite_info.background_position == "-448.0px -96.0px"
end
test "alternate table symbol \\#" do
# Test a symbol from alternate table
sprite_info = AprsSymbol.get_sprite_info("\\", "#")
assert sprite_info.sprite_file == "/aprs-symbols/aprs-symbols-128-1@2x.png"
# Calculate expected position for # (ASCII 35)
# index = 35 - 33 = 2
# column = 2 % 16 = 2
# row = 2 / 16 = 0
# x = -2 * 128 = -256
# y = -0 * 128 = 0
# scaled: x/4 = -64, y/4 = 0
assert sprite_info.background_position == "-64.0px 0.0px"
end
test "get_overlay_base_table_id mapping" do
# Test the table mapping for overlay base symbols
# Green star in alternate table
assert AprsSymbol.get_overlay_base_table_id("#") == "1"
# Diamond in alternate table
assert AprsSymbol.get_overlay_base_table_id("&") == "1"
# Black square in alternate table
assert AprsSymbol.get_overlay_base_table_id("i") == "1"
# Arrow in alternate table
assert AprsSymbol.get_overlay_base_table_id(">") == "1"
# Arrow in alternate table
assert AprsSymbol.get_overlay_base_table_id("^") == "1"
# Default to alternate table
assert AprsSymbol.get_overlay_base_table_id("?") == "1"
end
end
describe "normalize helpers" do
test "normalize_symbol_table maps overlay characters to ']' table" do
# Single alphanumeric → overlay table
assert AprsSymbol.normalize_symbol_table("A") == "]"
assert AprsSymbol.normalize_symbol_table("9") == "]"
# Non-alphanumeric falls back to "/"
assert AprsSymbol.normalize_symbol_table("##") == "/"
# nil/non-binary fallback
assert AprsSymbol.normalize_symbol_table(nil) == "/"
assert AprsSymbol.normalize_symbol_table(123) == "/"
end
test "normalize_symbol_code defaults nil and empty string to '>'" do
assert AprsSymbol.normalize_symbol_code(nil) == ">"
assert AprsSymbol.normalize_symbol_code("") == ">"
assert AprsSymbol.normalize_symbol_code("_") == "_"
end
test "get_table_id supports primary, alternate, and overlay tables" do
assert AprsSymbol.get_table_id("/") == "0"
assert AprsSymbol.get_table_id("\\") == "1"
assert AprsSymbol.get_table_id("]") == "2"
# Fallback for unknown tables.
assert AprsSymbol.get_table_id("anything-else") == "0"
end
end
end