defmodule ToweropsWeb.Api.V1.GeoipControllerTest do use ToweropsWeb.ConnCase, async: true import Towerops.AccountsFixtures import Towerops.OrganizationsFixtures alias Towerops.ApiTokens setup do user = user_fixture() organization = organization_fixture(user.id) {:ok, {_token, raw_token}} = ApiTokens.create_api_token(%{ organization_id: organization.id, user_id: user.id, name: "Test Token" }) conn = build_conn() |> put_req_header("authorization", "Bearer #{raw_token}") |> put_req_header("accept", "application/json") |> put_req_header("content-type", "application/json") %{conn: conn, user: user, organization: organization} end describe "import_database" do test "returns forbidden for non-superuser", %{conn: conn} do conn = post(conn, "/admin/api/geoip/import", %{ "batch_type" => "locations", "data" => [] }) assert json_response(conn, 403)["error"] =~ "Superuser access required" end test "imports locations batch for superuser", %{conn: conn, user: user} do user |> Ecto.Changeset.change(%{is_superuser: true}) |> Towerops.Repo.update!() conn = post(conn, "/admin/api/geoip/import", %{ "batch_type" => "locations", "data" => [], "truncate" => false }) assert json_response(conn, 200)["status"] == "ok" end test "returns error for invalid batch type", %{conn: conn, user: user} do user |> Ecto.Changeset.change(%{is_superuser: true}) |> Towerops.Repo.update!() conn = post(conn, "/admin/api/geoip/import", %{ "batch_type" => "invalid", "data" => [] }) assert json_response(conn, 500)["error"] =~ "Invalid batch_type" end test "returns 400 when missing parameters", %{conn: conn, user: user} do user |> Ecto.Changeset.change(%{is_superuser: true}) |> Towerops.Repo.update!() conn = post(conn, "/admin/api/geoip/import", %{}) assert json_response(conn, 400)["error"] =~ "Missing required parameters" end test "imports locations data successfully", %{conn: conn, user: user} do user |> Ecto.Changeset.change(%{is_superuser: true}) |> Towerops.Repo.update!() conn = post(conn, "/admin/api/geoip/import", %{ "batch_type" => "locations", "data" => [ %{ "geoname_id" => 5_128_581, "country_code" => "US", "country_name" => "United States", "city_name" => "New York", "subdivision_1_name" => "New York", "subdivision_2_name" => "New York", "latitude" => 40.7128, "longitude" => -74.006 } ], "truncate" => true }) assert json_response(conn, 200)["status"] == "ok" end test "imports blocks data successfully", %{conn: conn, user: user} do user |> Ecto.Changeset.change(%{is_superuser: true}) |> Towerops.Repo.update!() # Insert location first so the FK constraint is satisfied {:ok, _} = conn |> post("/admin/api/geoip/import", %{ "batch_type" => "locations", "data" => [ %{ "geoname_id" => 5_128_581, "country_code" => "US", "country_name" => "United States", "city_name" => "New York", "subdivision_1_name" => "New York", "subdivision_2_name" => "New York", "latitude" => 40.7128, "longitude" => -74.006 }, %{ "geoname_id" => 6_252_001, "country_code" => "US", "country_name" => "United States", "city_name" => nil, "subdivision_1_name" => nil, "subdivision_2_name" => nil, "latitude" => nil, "longitude" => nil } ] }) |> json_response(200) |> then(&{:ok, &1}) conn = post(conn, "/admin/api/geoip/import", %{ "batch_type" => "blocks", "data" => [ %{ "network" => "10.0.0.0/24", "start_ip_int" => 167_772_160, "end_ip_int" => 167_772_415, "geoname_id" => 5_128_581, "registered_country_geoname_id" => 6_252_001 } ], "truncate" => true }) assert json_response(conn, 200)["status"] == "ok" end end end