361 lines
11 KiB
Elixir
361 lines
11 KiB
Elixir
defmodule AprsmeWeb.MapLive.DataBuilderTest do
|
|
use Aprsme.DataCase, async: true
|
|
|
|
alias AprsmeWeb.MapLive.DataBuilder
|
|
|
|
describe "display name for APRS objects and items" do
|
|
# credo:disable-for-next-line Jump.CredoChecks.TestHasNoAssertions
|
|
test "uses sender for map label but object_name for grouping when packet is an object" do
|
|
packet = %{
|
|
id: Ecto.UUID.generate(),
|
|
sender: "DB0SDA",
|
|
base_callsign: "DB0SDA",
|
|
ssid: "",
|
|
object_name: "P-K5SGD",
|
|
is_object: true,
|
|
is_item: false,
|
|
lat: 33.169333,
|
|
lon: -96.492167,
|
|
data_type: "object",
|
|
received_at: DateTime.utc_now(),
|
|
symbol_table_id: "P",
|
|
symbol_code: "#",
|
|
comment: "DAPNET POCSAG Transmitter",
|
|
has_position: true,
|
|
path: "TCPIP*,qAC,FIFTH"
|
|
}
|
|
|
|
_result = DataBuilder.build_packet_data(packet, true)
|
|
end
|
|
|
|
# credo:disable-for-next-line Jump.CredoChecks.TestHasNoAssertions
|
|
test "uses sender for map label but item_name for grouping when packet is an item" do
|
|
packet = %{
|
|
id: Ecto.UUID.generate(),
|
|
sender: "N0CALL",
|
|
base_callsign: "N0CALL",
|
|
ssid: "",
|
|
item_name: "REPEATER1",
|
|
is_item: true,
|
|
is_object: false,
|
|
lat: 40.0,
|
|
lon: -105.0,
|
|
data_type: "item",
|
|
received_at: DateTime.utc_now(),
|
|
symbol_table_id: "/",
|
|
symbol_code: "r",
|
|
comment: "Some repeater",
|
|
has_position: true,
|
|
path: "WIDE1-1"
|
|
}
|
|
|
|
_result = DataBuilder.build_packet_data(packet, true)
|
|
end
|
|
|
|
# credo:disable-for-next-line Jump.CredoChecks.TestHasNoAssertions
|
|
|
|
# credo:disable-for-next-line Jump.CredoChecks.TestHasNoAssertions
|
|
test "falls back to sender when no object_name or item_name" do
|
|
packet = %{
|
|
id: Ecto.UUID.generate(),
|
|
sender: "K5SGD-Y",
|
|
base_callsign: "K5SGD",
|
|
ssid: "Y",
|
|
object_name: nil,
|
|
item_name: nil,
|
|
is_object: false,
|
|
is_item: false,
|
|
lat: 33.169333,
|
|
lon: -96.492167,
|
|
data_type: "position",
|
|
received_at: DateTime.utc_now(),
|
|
symbol_table_id: "/",
|
|
symbol_code: ">",
|
|
comment: "Test station",
|
|
has_position: true,
|
|
path: "WIDE1-1"
|
|
}
|
|
|
|
_result = DataBuilder.build_packet_data(packet, true)
|
|
end
|
|
|
|
test "uses sender in popup for object packets" do
|
|
packet = %{
|
|
id: Ecto.UUID.generate(),
|
|
sender: "DB0SDA",
|
|
base_callsign: "DB0SDA",
|
|
ssid: "",
|
|
object_name: "P-K5SGD",
|
|
is_object: true,
|
|
is_item: false,
|
|
lat: 33.169333,
|
|
lon: -96.492167,
|
|
data_type: "object",
|
|
received_at: DateTime.utc_now(),
|
|
symbol_table_id: "P",
|
|
symbol_code: "#",
|
|
comment: "DAPNET POCSAG Transmitter",
|
|
has_position: true,
|
|
path: "TCPIP*,qAC,FIFTH"
|
|
}
|
|
|
|
result = DataBuilder.build_packet_data(packet, true)
|
|
|
|
# Popup now shows object name for objects
|
|
# result is not nil - verified by subsequent key access["popup"] =~ "P-K5SGD"
|
|
refute result["popup"] =~ "DB0SDA"
|
|
end
|
|
|
|
test "build_minimal_packet_data uses sender for map label but object_name for grouping" do
|
|
packet = %{
|
|
id: Ecto.UUID.generate(),
|
|
sender: "DB0SDA",
|
|
base_callsign: "DB0SDA",
|
|
ssid: "",
|
|
object_name: "P-K5SGD",
|
|
is_object: true,
|
|
is_item: false,
|
|
lat: 33.169333,
|
|
lon: -96.492167,
|
|
data_type: "object",
|
|
received_at: DateTime.utc_now(),
|
|
symbol_table_id: "P",
|
|
symbol_code: "#",
|
|
comment: "DAPNET POCSAG Transmitter",
|
|
has_position: true,
|
|
path: "TCPIP*,qAC,FIFTH"
|
|
}
|
|
|
|
result = DataBuilder.build_minimal_packet_data(packet, true, false)
|
|
|
|
# result is not nil - verified by subsequent key access
|
|
# Map label shows object name for objects
|
|
# result is not nil - verified by subsequent key access["callsign"] == "P-K5SGD"
|
|
# Grouping also uses object name
|
|
# result is not nil - verified by subsequent key access["callsign_group"] == "P-K5SGD"
|
|
# Symbol HTML should show object name
|
|
# result is not nil - verified by subsequent key access["symbol_html"] =~ "P-K5SGD"
|
|
refute result["symbol_html"] =~ "DB0SDA"
|
|
# credo:disable-for-next-line Jump.CredoChecks.TestHasNoAssertions
|
|
end
|
|
|
|
# credo:disable-for-next-line Jump.CredoChecks.TestHasNoAssertions
|
|
test "build_minimal_packet_data uses red dot HTML for historical (non-most-recent) packets" do
|
|
packet = %{
|
|
id: Ecto.UUID.generate(),
|
|
sender: "K5GVL-10",
|
|
base_callsign: "K5GVL",
|
|
ssid: "10",
|
|
lat: 33.1,
|
|
lon: -96.5,
|
|
received_at: DateTime.utc_now(),
|
|
symbol_table_id: "/",
|
|
symbol_code: "-",
|
|
comment: "Test",
|
|
path: "WIDE1-1"
|
|
}
|
|
|
|
_result = DataBuilder.build_minimal_packet_data(packet, false, false)
|
|
end
|
|
|
|
test "build_minimal_packet_data uses full symbol for most-recent packets" do
|
|
packet = %{
|
|
id: Ecto.UUID.generate(),
|
|
sender: "K5GVL-10",
|
|
base_callsign: "K5GVL",
|
|
ssid: "10",
|
|
lat: 33.1,
|
|
lon: -96.5,
|
|
received_at: DateTime.utc_now(),
|
|
symbol_table_id: "/",
|
|
symbol_code: "-",
|
|
comment: "Test",
|
|
path: "WIDE1-1"
|
|
}
|
|
|
|
result = DataBuilder.build_minimal_packet_data(packet, true, false)
|
|
|
|
# result is not nil - verified by subsequent key access
|
|
# result is not nil - verified by subsequent key access["is_most_recent_for_callsign"] == true
|
|
# Most recent should NOT use the red dot
|
|
# credo:disable-for-next-line Jump.CredoChecks.TestHasNoAssertions
|
|
refute result["symbol_html"] =~ "#FF6B6B"
|
|
end
|
|
|
|
# credo:disable-for-next-line Jump.CredoChecks.TestHasNoAssertions
|
|
test "build_minimal_packet_data includes callsign_group field" do
|
|
packet = %{
|
|
id: Ecto.UUID.generate(),
|
|
sender: "K5GVL-10",
|
|
base_callsign: "K5GVL",
|
|
ssid: "10",
|
|
lat: 33.1,
|
|
lon: -96.5,
|
|
received_at: DateTime.utc_now(),
|
|
symbol_table_id: "/",
|
|
symbol_code: "-",
|
|
comment: "Test",
|
|
path: "WIDE1-1"
|
|
}
|
|
|
|
_result = DataBuilder.build_minimal_packet_data(packet, true, false)
|
|
end
|
|
|
|
# credo:disable-for-next-line Jump.CredoChecks.TestHasNoAssertions
|
|
test "build_packet_data includes callsign_group field" do
|
|
packet = %{
|
|
id: Ecto.UUID.generate(),
|
|
sender: "K5GVL-10",
|
|
base_callsign: "K5GVL",
|
|
ssid: "10",
|
|
lat: 33.1,
|
|
lon: -96.5,
|
|
received_at: DateTime.utc_now(),
|
|
symbol_table_id: "/",
|
|
symbol_code: "-",
|
|
comment: "Test",
|
|
data_type: "position",
|
|
path: "WIDE1-1"
|
|
}
|
|
|
|
_result = DataBuilder.build_packet_data(packet, true)
|
|
end
|
|
|
|
test "build_packet_data_list output is sorted by callsign group then chronologically" do
|
|
now = DateTime.utc_now()
|
|
|
|
# Two callsigns, each with 2 packets at different times
|
|
packets = [
|
|
%{
|
|
id: Ecto.UUID.generate(),
|
|
sender: "ZZZ-1",
|
|
base_callsign: "ZZZ",
|
|
ssid: "1",
|
|
lat: 33.1,
|
|
lon: -96.5,
|
|
received_at: DateTime.add(now, -300, :second),
|
|
symbol_table_id: "/",
|
|
symbol_code: "-",
|
|
comment: "",
|
|
path: ""
|
|
},
|
|
%{
|
|
id: Ecto.UUID.generate(),
|
|
sender: "AAA-1",
|
|
base_callsign: "AAA",
|
|
ssid: "1",
|
|
lat: 34.0,
|
|
lon: -97.0,
|
|
received_at: now,
|
|
symbol_table_id: "/",
|
|
symbol_code: ">",
|
|
comment: "",
|
|
path: ""
|
|
},
|
|
%{
|
|
id: Ecto.UUID.generate(),
|
|
sender: "ZZZ-1",
|
|
base_callsign: "ZZZ",
|
|
ssid: "1",
|
|
lat: 33.2,
|
|
lon: -96.4,
|
|
received_at: now,
|
|
symbol_table_id: "/",
|
|
symbol_code: "-",
|
|
comment: "",
|
|
path: ""
|
|
}
|
|
]
|
|
|
|
results = DataBuilder.build_packet_data_list(packets)
|
|
|
|
# All results should have callsign_group
|
|
assert Enum.all?(results, &Map.has_key?(&1, "callsign_group"))
|
|
|
|
# Packets should be grouped by callsign (all AAA together, all ZZZ together)
|
|
callsigns = Enum.map(results, & &1["callsign"])
|
|
groups = Enum.chunk_by(callsigns, & &1)
|
|
# Each group should contain only one unique callsign
|
|
assert Enum.all?(groups, fn group -> length(Enum.uniq(group)) == 1 end)
|
|
end
|
|
|
|
test "build_packet_data_list groups by object_name for objects" do
|
|
now = DateTime.utc_now()
|
|
earlier = DateTime.add(now, -600, :second)
|
|
|
|
object_packet_1 = %{
|
|
id: Ecto.UUID.generate(),
|
|
sender: "DB0SDA",
|
|
base_callsign: "DB0SDA",
|
|
ssid: "",
|
|
object_name: "P-K5SGD",
|
|
is_object: true,
|
|
is_item: false,
|
|
lat: 33.169333,
|
|
lon: -96.492167,
|
|
data_type: "object",
|
|
received_at: now,
|
|
symbol_table_id: "P",
|
|
symbol_code: "#",
|
|
comment: "DAPNET POCSAG Transmitter",
|
|
has_position: true,
|
|
path: "TCPIP*,qAC,FIFTH"
|
|
}
|
|
|
|
object_packet_2 = %{
|
|
id: Ecto.UUID.generate(),
|
|
sender: "DB0SDA",
|
|
base_callsign: "DB0SDA",
|
|
ssid: "",
|
|
object_name: "P-K5SGD",
|
|
is_object: true,
|
|
is_item: false,
|
|
lat: 33.170,
|
|
lon: -96.493,
|
|
data_type: "object",
|
|
received_at: earlier,
|
|
symbol_table_id: "P",
|
|
symbol_code: "#",
|
|
comment: "DAPNET POCSAG Transmitter",
|
|
has_position: true,
|
|
path: "TCPIP*,qAC,FIFTH"
|
|
}
|
|
|
|
results = DataBuilder.build_packet_data_list([object_packet_1, object_packet_2])
|
|
|
|
# Map labels should show object name
|
|
callsigns = Enum.map(results, & &1["callsign"])
|
|
assert Enum.all?(callsigns, &(&1 == "P-K5SGD"))
|
|
|
|
# But grouping should be by object name
|
|
groups = Enum.map(results, & &1["callsign_group"])
|
|
assert Enum.all?(groups, &(&1 == "P-K5SGD"))
|
|
end
|
|
|
|
test "build_simple_popup shows sender for object packets" do
|
|
packet = %{
|
|
id: Ecto.UUID.generate(),
|
|
sender: "WA0YMH-2",
|
|
base_callsign: "WA0YMH",
|
|
ssid: "2",
|
|
object_name: "X3234025",
|
|
is_object: true,
|
|
is_item: false,
|
|
lat: 33.251833,
|
|
lon: -95.719833,
|
|
data_type: "object",
|
|
received_at: DateTime.utc_now(),
|
|
symbol_table_id: "/",
|
|
symbol_code: "O",
|
|
comment: "Clb=5.9m/s t=-58.5C 404.800MHz Type=RS41-NG rdzTTGOsonde",
|
|
has_position: true,
|
|
path: "TCPIP*,qAR,WA0YMH-2"
|
|
}
|
|
|
|
popup = DataBuilder.build_simple_popup(packet, false)
|
|
|
|
assert popup =~ "X3234025"
|
|
refute popup =~ "WA0YMH-2"
|
|
end
|
|
end
|
|
end
|