Add focused tests across many modules to push overall coverage from 75.45% to ~77%. New test files: - test/towerops/snmp/topology_test.exs - test/towerops/vault_test.exs - test/towerops/workers/check_worker_test.exs - test/towerops_web/graphql/resolvers/happy_path_test.exs - test/towerops_web/graphql/schema_test.exs - test/towerops_web/live/reports_live_test.exs Expanded existing tests for: Airos vendor, ProfileWatcher, StormDetector, LLDP, GpsSync, MikrotikBackupWorker, AdminController, MibController, MobileController, GeoipController, OnboardingLive, UserResetPasswordLive, SessionManager, Telemetry, CoverageLive.Show. Also fix a pre-existing dead test in ApplicationSettingTest where the schema default for value_type made the 'invalid without value_type' test unreachable.
122 lines
3.9 KiB
Elixir
122 lines
3.9 KiB
Elixir
defmodule ToweropsWeb.Api.V1.MibControllerTest 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")
|
|
|
|
%{conn: conn, user: user, organization: organization}
|
|
end
|
|
|
|
describe "index" do
|
|
test "returns forbidden for non-superuser", %{conn: conn} do
|
|
conn = get(conn, "/admin/api/mibs")
|
|
|
|
assert json_response(conn, 403)["error"] =~ "Superuser access required"
|
|
end
|
|
|
|
test "returns MIB listing for superuser", %{conn: conn, user: user} do
|
|
user |> Ecto.Changeset.change(%{is_superuser: true}) |> Towerops.Repo.update!()
|
|
|
|
conn = get(conn, "/admin/api/mibs")
|
|
|
|
assert json_response(conn, 200)
|
|
end
|
|
end
|
|
|
|
describe "upload" do
|
|
test "returns forbidden for non-superuser", %{conn: conn} do
|
|
conn = post(conn, "/admin/api/mibs", %{})
|
|
|
|
assert json_response(conn, 403)["error"] =~ "Superuser access required"
|
|
end
|
|
|
|
test "returns bad request when file is missing for superuser", %{conn: conn, user: user} do
|
|
user |> Ecto.Changeset.change(%{is_superuser: true}) |> Towerops.Repo.update!()
|
|
|
|
conn = post(conn, "/admin/api/mibs", %{})
|
|
|
|
assert json_response(conn, 400)["error"] =~ "Missing file"
|
|
end
|
|
end
|
|
|
|
describe "delete" do
|
|
test "returns forbidden for non-superuser", %{conn: conn} do
|
|
conn = delete(conn, "/admin/api/mibs/testvendor")
|
|
|
|
assert json_response(conn, 403)["error"] =~ "Superuser access required"
|
|
end
|
|
|
|
test "rejects path-traversal vendor names", %{conn: conn, user: user} do
|
|
user |> Ecto.Changeset.change(%{is_superuser: true}) |> Towerops.Repo.update!()
|
|
conn = delete(conn, "/admin/api/mibs/..%2Fetc")
|
|
|
|
# The router won't match `..%2Fetc` directly, but `%2E%2E` decodes to `..`
|
|
# which the controller's validate_vendor_name catches. We assert any 4xx body
|
|
# rather than exact body since the rejection happens at multiple layers.
|
|
assert conn.status >= 400
|
|
end
|
|
|
|
test "404s on a missing vendor", %{conn: conn, user: user} do
|
|
user |> Ecto.Changeset.change(%{is_superuser: true}) |> Towerops.Repo.update!()
|
|
conn = delete(conn, "/admin/api/mibs/nonexistentvendor")
|
|
|
|
# Will be 404 if the vendor dir is missing, or 500 if @mib_dir itself is missing
|
|
assert conn.status in [404, 500]
|
|
end
|
|
end
|
|
|
|
describe "upload (with vendor)" do
|
|
setup %{user: user, conn: conn} do
|
|
user |> Ecto.Changeset.change(%{is_superuser: true}) |> Towerops.Repo.update!()
|
|
%{conn: conn}
|
|
end
|
|
|
|
test "rejects invalid vendor names", %{conn: conn} do
|
|
upload = %Plug.Upload{
|
|
path: write_temp_file("HOST-RESOURCES-MIB", "TEST DEFINITIONS ::= BEGIN END"),
|
|
filename: "HOST.txt",
|
|
content_type: "text/plain"
|
|
}
|
|
|
|
conn = post(conn, "/admin/api/mibs", %{"file" => upload, "vendor" => "../etc"})
|
|
|
|
assert json_response(conn, 400)["error"] =~ "Invalid vendor name"
|
|
end
|
|
|
|
test "rejects vendor names with non-allowed characters", %{conn: conn} do
|
|
upload = %Plug.Upload{
|
|
path: write_temp_file("FAKE", "x"),
|
|
filename: "FAKE.txt",
|
|
content_type: "text/plain"
|
|
}
|
|
|
|
conn = post(conn, "/admin/api/mibs", %{"file" => upload, "vendor" => "weird vendor!"})
|
|
|
|
assert json_response(conn, 400)["error"] =~ "Invalid vendor name"
|
|
end
|
|
end
|
|
|
|
defp write_temp_file(prefix, contents) do
|
|
path = Path.join(System.tmp_dir!(), "#{prefix}-#{System.unique_integer([:positive])}")
|
|
File.write!(path, contents)
|
|
path
|
|
end
|
|
end
|