mirror of
https://github.com/wanderer-industries/wanderer
synced 2026-01-02 04:50:22 +00:00
403 lines
12 KiB
Elixir
403 lines
12 KiB
Elixir
defmodule WandererAppWeb.MapDuplicationAPIControllerSuccessTest do
|
|
use WandererAppWeb.IntegrationConnCase, async: false
|
|
|
|
import Mox
|
|
import WandererAppWeb.Factory
|
|
import Ash.Query
|
|
|
|
setup :verify_on_exit!
|
|
|
|
describe "successful map duplication operations" do
|
|
setup do
|
|
user = insert(:user)
|
|
character = insert(:character, %{user_id: user.id})
|
|
|
|
source_map =
|
|
insert(:map, %{
|
|
owner_id: character.id,
|
|
name: "Original Test Map",
|
|
description: "A detailed exploration map with systems and connections"
|
|
})
|
|
|
|
# Create an active subscription for the map if subscriptions are enabled
|
|
create_active_subscription_for_map(source_map.id)
|
|
|
|
# Create some systems and connections for the source map
|
|
system1 =
|
|
insert(:map_system, %{
|
|
map_id: source_map.id,
|
|
solar_system_id: 30_000_142,
|
|
name: "Jita",
|
|
position_x: 100,
|
|
position_y: 200,
|
|
status: 1
|
|
})
|
|
|
|
system2 =
|
|
insert(:map_system, %{
|
|
map_id: source_map.id,
|
|
solar_system_id: 30_000_144,
|
|
name: "Amarr",
|
|
position_x: 300,
|
|
position_y: 400,
|
|
status: 0
|
|
})
|
|
|
|
_connection =
|
|
insert(:map_connection, %{
|
|
map_id: source_map.id,
|
|
solar_system_source: system1.solar_system_id,
|
|
solar_system_target: system2.solar_system_id,
|
|
type: 1
|
|
})
|
|
|
|
# Create some signatures
|
|
_signature =
|
|
insert(:map_system_signature, %{
|
|
system_id: system1.id,
|
|
eve_id: "ABC-123",
|
|
name: "Test Wormhole",
|
|
type: "wormhole"
|
|
})
|
|
|
|
conn =
|
|
build_conn()
|
|
|> put_req_header(
|
|
"authorization",
|
|
"Bearer #{source_map.public_api_key || "test-api-key"}"
|
|
)
|
|
|> put_req_header("content-type", "application/json")
|
|
|> assign(:current_character, character)
|
|
|> assign(:current_user, user)
|
|
|> assign(:map, source_map)
|
|
|
|
%{
|
|
conn: conn,
|
|
user: user,
|
|
character: character,
|
|
source_map: source_map,
|
|
system1: system1,
|
|
system2: system2
|
|
}
|
|
end
|
|
|
|
test "successfully duplicates a map with all systems and connections", %{
|
|
conn: conn,
|
|
source_map: source_map
|
|
} do
|
|
duplication_params = %{
|
|
"name" => "Duplicated Map",
|
|
"description" => "A perfect copy of the original exploration map",
|
|
"copy_acls" => true,
|
|
"copy_user_settings" => true,
|
|
"copy_signatures" => false
|
|
}
|
|
|
|
conn = post(conn, ~p"/api/maps/#{source_map.slug}/duplicate", duplication_params)
|
|
|
|
assert %{
|
|
"data" => %{
|
|
"id" => new_id,
|
|
"name" => "Duplicated Map",
|
|
"description" => "A perfect copy of the original exploration map"
|
|
}
|
|
} = json_response(conn, 201)
|
|
|
|
assert new_id != source_map.id
|
|
|
|
# Verify the duplicated map exists
|
|
duplicated_map = WandererApp.Api.Map.by_id!(new_id)
|
|
assert duplicated_map.name == "Duplicated Map"
|
|
end
|
|
|
|
test "successfully duplicates with minimal parameters using defaults", %{
|
|
conn: conn,
|
|
source_map: source_map
|
|
} do
|
|
minimal_params = %{
|
|
"name" => "Simple Copy"
|
|
}
|
|
|
|
conn = post(conn, ~p"/api/maps/#{source_map.id}/duplicate", minimal_params)
|
|
|
|
assert %{
|
|
"data" => %{
|
|
"id" => new_id,
|
|
"name" => "Simple Copy"
|
|
}
|
|
} = json_response(conn, 201)
|
|
|
|
assert new_id != source_map.id
|
|
|
|
# Verify the duplicated map exists
|
|
duplicated_map = WandererApp.Api.Map.by_id!(new_id)
|
|
assert duplicated_map.name == "Simple Copy"
|
|
end
|
|
|
|
test "successfully duplicates using map slug instead of ID", %{
|
|
conn: conn,
|
|
source_map: source_map
|
|
} do
|
|
params = %{
|
|
"name" => "Slug-based Copy",
|
|
"description" => "Duplicated using slug identifier"
|
|
}
|
|
|
|
conn = post(conn, ~p"/api/maps/#{source_map.slug}/duplicate", params)
|
|
|
|
assert %{
|
|
"data" => %{
|
|
"id" => new_id,
|
|
"name" => "Slug-based Copy",
|
|
"description" => "Duplicated using slug identifier"
|
|
}
|
|
} = json_response(conn, 201)
|
|
|
|
assert new_id != source_map.id
|
|
end
|
|
|
|
test "successfully duplicates with selective copying options", %{
|
|
conn: conn,
|
|
source_map: source_map
|
|
} do
|
|
duplication_params = %{
|
|
"name" => "Selective Copy",
|
|
"copy_acls" => false,
|
|
"copy_user_settings" => false,
|
|
"copy_signatures" => true
|
|
}
|
|
|
|
conn = post(conn, ~p"/api/maps/#{source_map.slug}/duplicate", duplication_params)
|
|
|
|
assert %{
|
|
"data" => %{
|
|
"id" => new_id,
|
|
"name" => "Selective Copy"
|
|
}
|
|
} = json_response(conn, 201)
|
|
|
|
assert new_id != source_map.id
|
|
end
|
|
|
|
test "duplicated map contains copied systems", %{conn: conn, source_map: source_map} do
|
|
duplication_params = %{
|
|
"name" => "System Copy Test",
|
|
"copy_signatures" => false
|
|
}
|
|
|
|
conn = post(conn, ~p"/api/maps/#{source_map.slug}/duplicate", duplication_params)
|
|
|
|
assert %{
|
|
"data" => %{
|
|
"id" => new_map_id
|
|
}
|
|
} = json_response(conn, 201)
|
|
|
|
# Check that the new map has systems
|
|
{:ok, new_systems} = WandererApp.Api.MapSystem.read_all_by_map(%{map_id: new_map_id})
|
|
|
|
assert length(new_systems) >= 2
|
|
|
|
# Find the copied Jita system
|
|
jita_system = Enum.find(new_systems, &(&1.name == "Jita"))
|
|
assert jita_system != nil
|
|
assert jita_system.solar_system_id == 30_000_142
|
|
assert jita_system.position_x == 100
|
|
assert jita_system.status == 1
|
|
|
|
# Find the copied Amarr system
|
|
amarr_system = Enum.find(new_systems, &(&1.name == "Amarr"))
|
|
assert amarr_system != nil
|
|
assert amarr_system.solar_system_id == 30_000_144
|
|
assert amarr_system.position_x == 300.0
|
|
assert amarr_system.status == 0
|
|
end
|
|
|
|
test "duplicated map contains copied connections", %{conn: conn, source_map: source_map} do
|
|
duplication_params = %{
|
|
"name" => "Connection Copy Test"
|
|
}
|
|
|
|
conn = post(conn, ~p"/api/maps/#{source_map.slug}/duplicate", duplication_params)
|
|
|
|
assert %{
|
|
"data" => %{
|
|
"id" => new_map_id
|
|
}
|
|
} = json_response(conn, 201)
|
|
|
|
# Check that the new map has connections
|
|
{:ok, new_connections} = WandererApp.Api.MapConnection.read_by_map(%{map_id: new_map_id})
|
|
|
|
assert length(new_connections) >= 1
|
|
|
|
# Find the copied stargate connection
|
|
stargate_connection = Enum.find(new_connections, &(&1.type == 1))
|
|
assert stargate_connection != nil
|
|
assert stargate_connection.solar_system_source == 30_000_142
|
|
assert stargate_connection.solar_system_target == 30_000_144
|
|
end
|
|
end
|
|
|
|
describe "error handling for map duplication" do
|
|
setup do
|
|
user = insert(:user)
|
|
character = insert(:character, %{user_id: user.id})
|
|
unique_key = "test-api-key-#{System.unique_integer([:positive])}"
|
|
map = insert(:map, %{owner_id: character.id, public_api_key: unique_key})
|
|
|
|
conn =
|
|
build_conn()
|
|
|> put_req_header("authorization", "Bearer #{unique_key}")
|
|
|> put_req_header("content-type", "application/json")
|
|
|> assign(:current_character, character)
|
|
|> assign(:current_user, user)
|
|
|
|
%{conn: conn, user: user, character: character, map: map}
|
|
end
|
|
|
|
test "fails with missing required name parameter", %{
|
|
conn: conn,
|
|
user: user,
|
|
character: character
|
|
} do
|
|
unique_key = "test-api-key-#{System.unique_integer([:positive])}"
|
|
source_map = insert(:map, %{owner_id: character.id, public_api_key: unique_key})
|
|
|
|
# Create an active subscription for the source map
|
|
create_active_subscription_for_map(source_map.id)
|
|
|
|
invalid_params = %{
|
|
"description" => "Missing name field"
|
|
}
|
|
|
|
authenticated_conn =
|
|
conn
|
|
|> put_req_header("authorization", "Bearer #{source_map.public_api_key}")
|
|
|> assign(:map, source_map)
|
|
|
|
conn = post(authenticated_conn, ~p"/api/maps/#{source_map.id}/duplicate", invalid_params)
|
|
|
|
assert %{
|
|
"error" => error_message
|
|
} = json_response(conn, 400)
|
|
|
|
assert String.contains?(error_message, "Name is required")
|
|
end
|
|
|
|
test "fails when source map does not exist", %{conn: conn} do
|
|
non_existent_id = Ecto.UUID.generate()
|
|
|
|
params = %{
|
|
"name" => "Copy of Non-existent Map"
|
|
}
|
|
|
|
conn = post(conn, ~p"/api/maps/#{non_existent_id}/duplicate", params)
|
|
|
|
assert json_response(conn, 404)
|
|
end
|
|
|
|
test "fails when source map slug does not exist", %{conn: conn} do
|
|
non_existent_slug = "non-existent-map-slug"
|
|
|
|
params = %{
|
|
"name" => "Copy of Non-existent Map"
|
|
}
|
|
|
|
conn = post(conn, ~p"/api/maps/#{non_existent_slug}/duplicate", params)
|
|
|
|
assert json_response(conn, 404)
|
|
end
|
|
|
|
test "fails with invalid boolean parameters", %{conn: conn, user: user, character: character} do
|
|
unique_key = "test-api-key-#{System.unique_integer([:positive])}"
|
|
source_map = insert(:map, %{owner_id: character.id, public_api_key: unique_key})
|
|
create_active_subscription_for_map(source_map.id)
|
|
|
|
invalid_params = %{
|
|
"name" => "Invalid Boolean Test",
|
|
"copy_acls" => "not-a-boolean",
|
|
"copy_user_settings" => "invalid",
|
|
"copy_signatures" => "wrong"
|
|
}
|
|
|
|
authenticated_conn =
|
|
conn
|
|
|> put_req_header("authorization", "Bearer #{source_map.public_api_key}")
|
|
|> assign(:map, source_map)
|
|
|
|
conn = post(authenticated_conn, ~p"/api/maps/#{source_map.id}/duplicate", invalid_params)
|
|
|
|
# Should return an error response for invalid boolean values
|
|
assert conn.status in [400, 422]
|
|
end
|
|
|
|
test "handles very long map names", %{conn: conn, user: user, character: character} do
|
|
unique_key = "test-api-key-#{System.unique_integer([:positive])}"
|
|
source_map = insert(:map, %{owner_id: character.id, public_api_key: unique_key})
|
|
create_active_subscription_for_map(source_map.id)
|
|
|
|
# Very long name
|
|
long_name = String.duplicate("a", 300)
|
|
|
|
params = %{
|
|
"name" => long_name
|
|
}
|
|
|
|
authenticated_conn =
|
|
conn
|
|
|> put_req_header("authorization", "Bearer #{source_map.public_api_key}")
|
|
|> assign(:map, source_map)
|
|
|
|
conn = post(authenticated_conn, ~p"/api/maps/#{source_map.id}/duplicate", params)
|
|
|
|
# Should return an error response for name too long
|
|
assert conn.status in [400, 422]
|
|
end
|
|
end
|
|
|
|
describe "authorization for map duplication" do
|
|
test "fails when user is not authenticated" do
|
|
source_map = insert(:map, %{})
|
|
|
|
params = %{
|
|
"name" => "Unauthorized Copy"
|
|
}
|
|
|
|
conn = build_conn()
|
|
conn = post(conn, ~p"/api/maps/#{source_map.id}/duplicate", params)
|
|
|
|
# Should require authentication
|
|
assert conn.status in [401, 403]
|
|
end
|
|
|
|
test "succeeds when user has access to source map" do
|
|
user = insert(:user)
|
|
character = insert(:character, %{user_id: user.id})
|
|
source_map = insert(:map, %{owner_id: character.id, public_api_key: "test-api-key"})
|
|
|
|
# Create an active subscription for the map if subscriptions are enabled
|
|
create_active_subscription_for_map(source_map.id)
|
|
|
|
params = %{
|
|
"name" => "Authorized Copy"
|
|
}
|
|
|
|
conn =
|
|
build_conn()
|
|
|> put_req_header("authorization", "Bearer #{source_map.public_api_key}")
|
|
|> put_req_header("content-type", "application/json")
|
|
|> assign(:current_character, character)
|
|
|> assign(:current_user, user)
|
|
|> assign(:map, source_map)
|
|
|> post(~p"/api/maps/#{source_map.slug}/duplicate", params)
|
|
|
|
assert %{
|
|
"data" => %{
|
|
"name" => "Authorized Copy"
|
|
}
|
|
} = json_response(conn, 201)
|
|
end
|
|
end
|
|
end
|