mirror of
https://github.com/wanderer-industries/wanderer
synced 2026-01-17 20:30:19 +00:00
306 lines
8.8 KiB
Elixir
306 lines
8.8 KiB
Elixir
defmodule WandererAppWeb.MapConnectionAPIControllerSuccessTest do
|
|
use WandererAppWeb.IntegrationConnCase, async: false
|
|
|
|
import Mox
|
|
|
|
setup :verify_on_exit!
|
|
import WandererAppWeb.Factory
|
|
import WandererApp.MapTestHelpers
|
|
|
|
setup :verify_on_exit!
|
|
|
|
describe "successful CRUD operations for map connections" do
|
|
setup do
|
|
# Setup DDRT (R-tree) mock stubs for system positioning
|
|
setup_ddrt_mocks()
|
|
|
|
user = insert(:user)
|
|
character = insert(:character, %{user_id: user.id})
|
|
map = insert(:map, %{owner_id: character.id})
|
|
|
|
# Create an active subscription for the map if subscriptions are enabled
|
|
create_active_subscription_for_map(map.id)
|
|
|
|
# Map server will be started in individual tests after data insertion
|
|
# Ensure it's stopped first to prevent state leakage from previous tests
|
|
ensure_map_stopped(map.id)
|
|
|
|
# Create systems that connections can reference
|
|
system1 =
|
|
insert(:map_system, %{
|
|
map_id: map.id,
|
|
solar_system_id: 30_000_142,
|
|
name: "Jita"
|
|
})
|
|
|
|
system2 =
|
|
insert(:map_system, %{
|
|
map_id: map.id,
|
|
solar_system_id: 30_000_144,
|
|
name: "Amarr"
|
|
})
|
|
|
|
conn =
|
|
build_conn()
|
|
|> put_req_header("authorization", "Bearer #{map.public_api_key || "test-api-key"}")
|
|
|> put_req_header("content-type", "application/json")
|
|
|> assign(:current_character, character)
|
|
|> assign(:current_user, user)
|
|
|> assign(:map_id, map.id)
|
|
|> assign(:map, map)
|
|
|> assign(:owner_character_id, character.eve_id)
|
|
|> assign(:owner_user_id, user.id)
|
|
|
|
%{
|
|
conn: conn,
|
|
user: user,
|
|
character: character,
|
|
map: map,
|
|
system1: system1,
|
|
system2: system2
|
|
}
|
|
end
|
|
|
|
test "READ: successfully retrieves all connections for a map", %{
|
|
conn: conn,
|
|
map: map,
|
|
system1: system1,
|
|
system2: system2
|
|
} do
|
|
# Create some connections for the map
|
|
connection1 =
|
|
insert(:map_connection, %{
|
|
map_id: map.id,
|
|
solar_system_source: system1.solar_system_id,
|
|
solar_system_target: system2.solar_system_id,
|
|
type: 0,
|
|
ship_size_type: 2
|
|
})
|
|
|
|
connection2 =
|
|
insert(:map_connection, %{
|
|
map_id: map.id,
|
|
solar_system_source: system2.solar_system_id,
|
|
solar_system_target: system1.solar_system_id,
|
|
type: 1,
|
|
ship_size_type: 1
|
|
})
|
|
|
|
# Allow time for connections to be created in database
|
|
Process.sleep(100)
|
|
|
|
# Start the map server to load the connections
|
|
ensure_map_started(map.id)
|
|
|
|
conn = get(conn, ~p"/api/maps/#{map.slug}/connections")
|
|
|
|
assert %{
|
|
"data" => returned_connections
|
|
} = json_response(conn, 200)
|
|
|
|
# At least one connection should be returned
|
|
assert length(returned_connections) >= 1
|
|
|
|
# Verify the connection has the expected structure and data
|
|
first_conn = List.first(returned_connections)
|
|
assert first_conn["solar_system_source"] != nil
|
|
assert first_conn["solar_system_target"] != nil
|
|
assert first_conn["type"] != nil
|
|
assert first_conn["ship_size_type"] != nil
|
|
# time_status will be default value since we can't set it during creation
|
|
assert first_conn["time_status"] == 0
|
|
end
|
|
|
|
test "UPDATE: successfully updates connection properties", %{
|
|
conn: conn,
|
|
map: map,
|
|
system1: system1,
|
|
system2: system2
|
|
} do
|
|
connection =
|
|
insert(:map_connection, %{
|
|
map_id: map.id,
|
|
solar_system_source: system1.solar_system_id,
|
|
solar_system_target: system2.solar_system_id,
|
|
type: 0,
|
|
ship_size_type: 0
|
|
})
|
|
|
|
# Allow time for connection to be created in database
|
|
Process.sleep(100)
|
|
|
|
# Start the map server to load the connection
|
|
ensure_map_started(map.id)
|
|
|
|
update_params = %{
|
|
"mass_status" => 2
|
|
}
|
|
|
|
conn = put(conn, ~p"/api/maps/#{map.slug}/connections/#{connection.id}", update_params)
|
|
|
|
response = json_response(conn, 200)
|
|
|
|
assert %{
|
|
"data" => updated_connection
|
|
} = response
|
|
|
|
assert updated_connection["mass_status"] == 2
|
|
# Verify other fields remain unchanged
|
|
assert updated_connection["ship_size_type"] == 0
|
|
assert updated_connection["time_status"] == 0
|
|
end
|
|
|
|
test "DELETE: successfully deletes a connection", %{
|
|
conn: conn,
|
|
map: map,
|
|
system1: system1,
|
|
system2: system2
|
|
} do
|
|
connection =
|
|
insert(:map_connection, %{
|
|
map_id: map.id,
|
|
solar_system_source: system1.solar_system_id,
|
|
solar_system_target: system2.solar_system_id,
|
|
type: 0,
|
|
ship_size_type: 2
|
|
})
|
|
|
|
# Allow time for connection to be created in database
|
|
Process.sleep(100)
|
|
|
|
# Start the map server to load the connection
|
|
ensure_map_started(map.id)
|
|
|
|
conn = delete(conn, ~p"/api/maps/#{map.slug}/connections/#{connection.id}")
|
|
|
|
# Response may be 204 (no content), 200 with data, or 404 (idempotent delete)
|
|
case conn.status do
|
|
204 ->
|
|
assert response(conn, 204)
|
|
|
|
200 ->
|
|
assert %{"data" => _} = json_response(conn, 200)
|
|
|
|
_ ->
|
|
# Accept other valid status codes (including 404 for idempotent delete)
|
|
assert conn.status in [200, 204, 404]
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "error handling for connections" do
|
|
setup do
|
|
# Setup DDRT (R-tree) mock stubs for system positioning
|
|
setup_ddrt_mocks()
|
|
|
|
user = insert(:user)
|
|
character = insert(:character, %{user_id: user.id})
|
|
map = insert(:map, %{owner_id: character.id})
|
|
|
|
# Create an active subscription for the map if subscriptions are enabled
|
|
create_active_subscription_for_map(map.id)
|
|
|
|
# Start the map server using the new async manager pattern
|
|
ensure_map_started(map.id)
|
|
|
|
conn =
|
|
build_conn()
|
|
|> put_req_header("authorization", "Bearer #{map.public_api_key || "test-api-key"}")
|
|
|> put_req_header("content-type", "application/json")
|
|
|> assign(:current_character, character)
|
|
|> assign(:current_user, user)
|
|
|> assign(:map_id, map.id)
|
|
|> assign(:map, map)
|
|
|> assign(:owner_character_id, character.eve_id)
|
|
|> assign(:owner_user_id, user.id)
|
|
|
|
ensure_map_stopped(map.id)
|
|
|
|
# Seed static solar system data
|
|
insert(:solar_system, %{
|
|
solar_system_id: 30_000_142,
|
|
solar_system_name: "Jita",
|
|
security: "0.9"
|
|
})
|
|
|
|
insert(:solar_system, %{
|
|
solar_system_id: 30_000_144,
|
|
solar_system_name: "Perimeter",
|
|
security: "0.9"
|
|
})
|
|
|
|
insert(:solar_system, %{
|
|
solar_system_id: 31_000_005,
|
|
solar_system_name: "Thera",
|
|
system_class: 12,
|
|
security: "-0.9"
|
|
})
|
|
|
|
{:ok, conn: conn, map: map, user: user, character: character}
|
|
end
|
|
|
|
test "CREATE: fails with missing required parameters", %{conn: conn, map: map} do
|
|
invalid_params = %{
|
|
"type" => 0
|
|
# Missing source and target system IDs
|
|
}
|
|
|
|
conn = post(conn, ~p"/api/maps/#{map.slug}/connections", invalid_params)
|
|
|
|
# Should return an error response
|
|
assert conn.status in [400, 422]
|
|
end
|
|
|
|
test "UPDATE: fails for non-existent connection", %{conn: conn, map: map} do
|
|
non_existent_id = Ecto.UUID.generate()
|
|
|
|
update_params = %{
|
|
"ship_size_type" => "large",
|
|
"time_status" => "critical"
|
|
}
|
|
|
|
conn = put(conn, ~p"/api/maps/#{map.slug}/connections/#{non_existent_id}", update_params)
|
|
|
|
# Should return an error response
|
|
assert conn.status in [404, 422, 500]
|
|
end
|
|
|
|
test "DELETE: handles non-existent connection gracefully", %{conn: conn, map: map} do
|
|
non_existent_id = Ecto.UUID.generate()
|
|
|
|
conn = delete(conn, ~p"/api/maps/#{map.slug}/connections/#{non_existent_id}")
|
|
|
|
# Should handle gracefully - may be 404 or may succeed
|
|
assert conn.status in [200, 204, 404]
|
|
end
|
|
|
|
test "READ: handles filtering with non-existent systems", %{conn: conn, map: map} do
|
|
params = %{
|
|
"solar_system_source" => "99999999",
|
|
"solar_system_target" => "99999998"
|
|
}
|
|
|
|
conn = get(conn, ~p"/api/maps/#{map.slug}/connections", params)
|
|
|
|
# Should return empty result or error
|
|
case conn.status do
|
|
200 ->
|
|
response = json_response(conn, 200)
|
|
# Should return empty data or null
|
|
case response["data"] do
|
|
nil -> :ok
|
|
[] -> :ok
|
|
%{} -> :ok
|
|
_ -> flunk("Expected empty or null data for non-existent systems")
|
|
end
|
|
|
|
404 ->
|
|
:ok
|
|
|
|
_ ->
|
|
assert conn.status in [200, 404]
|
|
end
|
|
end
|
|
end
|
|
end
|