feat(api): add exact-match name filter to list endpoints

This commit is contained in:
Mark Paronyan committed 2026-10-07 13:40:34 +03:00
1 parent 2fb7056cb9
commit 852dc5be0f
11 files changed
+167 -6

No files matched your search

@@ -68,6 +68,31 @@ class TestComputeRoutes:
assert response.status_code == status.HTTP_200_OK
assert len(response.json()) > 0
async def test_compute_list_filter_by_name(self, app: FastAPI, client: AsyncClient) -> None:
for name, port in (("compute-a", 85), ("compute-b", 86)):
params = {
"name": name,
"protocol": "http",
"host": "localhost",
"port": port,
"user": "julien",
"password": "secure",
}
response = await client.post(app.url_path_for("create_compute"), json=params)
assert response.status_code == status.HTTP_201_CREATED
response = await client.get(app.url_path_for("get_computes"), params={"name": "compute-a"})
assert response.status_code == status.HTTP_200_OK
assert [c["name"] for c in response.json()] == ["compute-a"]
response = await client.get(app.url_path_for("get_computes"), params={"name": "COMPUTE-A"})
assert response.status_code == status.HTTP_200_OK
assert response.json() == []
response = await client.get(app.url_path_for("get_computes"))
assert len(response.json()) >= 2
async def test_compute_get(self, app: FastAPI, client: AsyncClient, test_compute: Compute) -> None:
response = await client.get(app.url_path_for("get_compute", compute_id=test_compute.compute_id))
@@ -168,6 +168,21 @@ class TestImageRoutes:
assert response.status_code == status.HTTP_200_OK
assert len(response.json()) == 5 # 4 valid images uploaded before + 1 created
async def test_image_list_filter_by_name(self, app: FastAPI, client: AsyncClient, qcow2_image: str) -> None:
image_name = os.path.basename(qcow2_image)
response = await client.get(app.url_path_for("get_images"), params={"name": image_name})
assert response.status_code == status.HTTP_200_OK
assert [i["filename"] for i in response.json()] == [image_name]
response = await client.get(app.url_path_for("get_images"), params={"name": image_name.upper()})
assert response.status_code == status.HTTP_200_OK
assert response.json() == []
response = await client.get(app.url_path_for("get_images"), params={"name": image_name, "image_type": "iou"})
assert response.status_code == status.HTTP_200_OK
assert response.json() == []
async def test_image_get(self, app: FastAPI, client: AsyncClient, qcow2_image: str) -> None:
image_name = os.path.basename(qcow2_image)
+48
View File
@@ -156,6 +156,54 @@ class TestNodeRoutes:
else:
assert len(response.json()) == 0
@pytest.mark.parametrize(
"name, tags, expected_names",
(
(None, None, ["test", "test2"]),
("test", None, ["test"]),
("test2", None, ["test2"]),
("TEST", None, []),
("missing", None, []),
("test", ["tag1"], ["test"]),
("test", ["tag3"], []),
("test2", ["tag3", "tag4"], ["test2"]),
),
)
async def test_list_nodes_filter_by_name(
self,
app: FastAPI,
client: AsyncClient,
project: Project,
compute: Compute,
name: Optional[str],
tags: Optional[list],
expected_names: list,
) -> None:
response = MagicMock()
response.json = {"console": 2048}
compute.post = AsyncioMagicMock(return_value=response)
for node_name, node_tags in (("test", ["tag1", "tag2"]), ("test2", ["tag3", "tag4"])):
await client.post(
app.url_path_for("create_node", project_id=project.id),
json={
"name": node_name,
"node_type": "vpcs",
"compute_id": "example.com",
"tags": node_tags,
"properties": {"startup_script": "echo test"},
},
)
params = {}
if name is not None:
params["name"] = name
if tags is not None:
params["tags"] = tags
response = await client.get(app.url_path_for("get_nodes", project_id=project.id), params=params)
assert response.status_code == status.HTTP_200_OK
assert sorted(n["name"] for n in response.json()) == expected_names
async def test_get_node(self, app: FastAPI, client: AsyncClient, project: Project, compute: Compute) -> None:
response = MagicMock()
@@ -164,6 +164,26 @@ class TestControllerProjectRoutes:
projects = response.json()
assert projects[0]["name"] == "test"
async def test_list_projects_filter_by_name(
self, app: FastAPI, client: AsyncClient, controller: Controller
) -> None:
for name in ("test", "other"):
params = {"name": name, "project_id": str(uuid.uuid4())}
response = await client.post(app.url_path_for("create_project"), json=params)
assert response.status_code == status.HTTP_201_CREATED
response = await client.get(app.url_path_for("get_projects"), params={"name": "test"})
assert response.status_code == status.HTTP_200_OK
assert [p["name"] for p in response.json()] == ["test"]
response = await client.get(app.url_path_for("get_projects"), params={"name": "TEST"})
assert response.status_code == status.HTTP_200_OK
assert response.json() == []
response = await client.get(app.url_path_for("get_projects"))
assert len(response.json()) == 2
async def test_get_project(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
response = await client.get(app.url_path_for("get_project", project_id=project.id))
@@ -20,6 +20,7 @@ import os
import unittest.mock
import uuid
from pathlib import Path
from typing import Optional
import pytest
from fastapi import FastAPI, status
@@ -89,6 +90,27 @@ class TestTemplateRoutes:
else:
assert len(response.json()) == 0
@pytest.mark.parametrize(
"name, tags, expected_names",
(
("VPCS_TEST", None, ["VPCS_TEST"]),
("vpcs_test", None, []),
("missing", None, []),
("VPCS_TEST", ["tag1"], ["VPCS_TEST"]),
("VPCS_TEST", ["tag42"], []),
),
)
async def test_template_list_filter_by_name(
self, app: FastAPI, client: AsyncClient, name: str, tags: Optional[list], expected_names: list
) -> None:
params = {"name": name}
if tags is not None:
params["tags"] = tags
response = await client.get(app.url_path_for("get_templates"), params=params)
assert response.status_code == status.HTTP_200_OK
assert [t["name"] for t in response.json()] == expected_names
async def test_template_get(self, app: FastAPI, client: AsyncClient) -> None:
template_id = str(uuid.uuid4())