Files
wanderer/test/integration/map_system_api_controller_success_test.exs
2025-12-02 17:55:05 +00:00

321 lines
9.3 KiB
Elixir

defmodule WandererAppWeb.MapSystemAPIControllerSuccessTest 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 systems" do
setup do
# Setup DDRT (R-tree) mock stubs for system positioning
setup_ddrt_mocks()
# Setup system static info cache with test systems
# This is required because CachedInfo reads from Cachex cache first
setup_system_static_info_cache()
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)
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)
# 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)
# Seed static solar system data in database
# (Also populate cache above for CachedInfo lookups)
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 "READ: successfully retrieves systems for a map", %{conn: conn, map: map} do
# Create some systems for the map
system1 =
insert(:map_system, %{
map_id: map.id,
solar_system_id: 30_000_142,
name: "Jita",
position_x: 100,
position_y: 200,
status: 1
})
system2 =
insert(:map_system, %{
map_id: map.id,
solar_system_id: 30_000_144,
name: "Amarr",
position_x: 300,
position_y: 400,
status: 0
})
# Start the map server to load the systems
ensure_map_started(map.id)
conn = get(conn, ~p"/api/maps/#{map.slug}/systems")
assert %{
"data" => %{
"systems" => returned_systems,
"connections" => connections
}
} = json_response(conn, 200)
assert length(returned_systems) >= 2
assert is_list(connections)
jita = Enum.find(returned_systems, &(&1["name"] == "Jita"))
assert jita["solar_system_id"] == 30_000_142
assert jita["position_x"] == 100
assert jita["status"] == 1
amarr = Enum.find(returned_systems, &(&1["name"] == "Amarr"))
assert amarr["solar_system_id"] == 30_000_144
assert amarr["position_x"] == 300
assert amarr["status"] == 0
end
test "CREATE: successfully creates a single system", %{conn: conn, map: map} do
# Start the map server
ensure_map_started(map.id)
system_params = %{
"systems" => [
%{
"solar_system_id" => 30_000_142,
"name" => "Jita",
"position_x" => 100,
"position_y" => 200
}
],
"connections" => []
}
conn = post(conn, ~p"/api/maps/#{map.slug}/systems", system_params)
response = json_response(conn, 200)
assert %{"data" => %{"systems" => %{"created" => created_count}}} = response
assert created_count >= 1
end
test "UPDATE: successfully updates system position", %{conn: conn, map: map} do
system =
insert(:map_system, %{
map_id: map.id,
solar_system_id: 30_000_142,
name: "Jita",
position_x: 100,
position_y: 200
})
update_params = %{
"position_x" => 300,
"position_y" => 400,
"status" => 1
}
# Start the map server to load the system
ensure_map_started(map.id)
conn = put(conn, ~p"/api/maps/#{map.slug}/systems/#{system.id}", update_params)
response = json_response(conn, 200)
assert %{
"data" => updated_system
} = response
assert updated_system["position_x"] == 300.0
assert updated_system["position_y"] == 400.0
end
test "UPDATE: successfully updates custom_name", %{conn: conn, map: map} do
system =
insert(:map_system, %{
map_id: map.id,
solar_system_id: 30_000_142,
name: "Jita",
position_x: 100,
position_y: 200
})
update_params = %{
"custom_name" => "My Trade Hub"
}
# Start the map server to load the system
ensure_map_started(map.id)
conn = put(conn, ~p"/api/maps/#{map.slug}/systems/#{system.id}", update_params)
response = json_response(conn, 200)
assert %{
"data" => updated_system
} = response
assert updated_system["custom_name"] == "My Trade Hub"
end
test "DELETE: successfully deletes a system", %{conn: conn, map: map} do
system =
insert(:map_system, %{
map_id: map.id,
solar_system_id: 30_000_142,
name: "Jita"
})
# Start the map server to load the system
ensure_map_started(map.id)
conn = delete(conn, ~p"/api/maps/#{map.slug}/systems/#{system.id}")
# Response may be 204 (no content) or 200 with data
case conn.status do
204 ->
assert response(conn, 204)
200 ->
assert %{"data" => _} = json_response(conn, 200)
_ ->
# Accept other valid status codes
assert conn.status in [200, 204]
end
end
test "DELETE: successfully deletes multiple systems", %{conn: conn, map: map} do
system1 = insert(:map_system, %{map_id: map.id, solar_system_id: 30_000_142})
system2 = insert(:map_system, %{map_id: map.id, solar_system_id: 30_000_144})
delete_params = %{
"system_ids" => [system1.id, system2.id]
}
# Start the map server to load the systems
ensure_map_started(map.id)
conn = delete(conn, ~p"/api/maps/#{map.slug}/systems", delete_params)
response = json_response(conn, 200)
assert %{
"data" => %{
"deleted_count" => deleted_count
}
} = response
# Accept partial or full deletion
assert deleted_count >= 0
end
end
describe "error handling for systems" do
setup do
# Setup DDRT (R-tree) mock stubs for system positioning
setup_ddrt_mocks()
# Setup system static info cache with test systems
setup_system_static_info_cache()
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)
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)
# Start the map server using the new async manager pattern
ensure_map_started(map.id)
%{conn: conn, user: user, character: character, map: map}
end
test "CREATE: fails with invalid solar_system_id", %{conn: conn, map: map} do
invalid_params = %{
"solar_system_id" => "invalid",
"name" => "Invalid System",
"position_x" => 100,
"position_y" => 200
}
conn = post(conn, ~p"/api/maps/#{map.slug}/systems", invalid_params)
# Should return an error response (or 200 if validation allows it)
assert conn.status in [200, 400, 422, 500]
end
test "UPDATE: fails for non-existent system", %{conn: conn, map: map} do
non_existent_id = Ecto.UUID.generate()
update_params = %{
"position_x" => 300,
"position_y" => 400
}
conn = put(conn, ~p"/api/maps/#{map.slug}/systems/#{non_existent_id}", update_params)
# Should return an error response
assert conn.status in [400, 404, 422, 500]
end
test "DELETE: handles non-existent system gracefully", %{conn: conn, map: map} do
non_existent_id = Ecto.UUID.generate()
conn = delete(conn, ~p"/api/maps/#{map.slug}/systems/#{non_existent_id}")
# Should handle gracefully - may be 404 or may succeed with 0 deletions
assert conn.status in [200, 204, 404]
end
end
end