mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-04 14:31:13 +02:00
refactor: ruff autofixes
This commit is contained in:
455 files changed
+12322
-14762
No files matched your search
@@ -35,202 +35,157 @@ pytestmark = pytest.mark.asyncio
|
||||
|
||||
|
||||
class TestControllerProjectRoutes:
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def project(self, app: FastAPI, client: AsyncClient, controller: Controller) -> Project:
|
||||
|
||||
|
||||
project_id = str(uuid.uuid4())
|
||||
params = {"name": "test", "project_id": project_id}
|
||||
await client.post(app.url_path_for("create_project"), json=params)
|
||||
return controller.get_project(project_id)
|
||||
|
||||
|
||||
|
||||
async def test_create_project_with_path(
|
||||
self,
|
||||
app: FastAPI,
|
||||
client: AsyncClient,
|
||||
controller: Controller,
|
||||
config
|
||||
self, app: FastAPI, client: AsyncClient, controller: Controller, config
|
||||
) -> None:
|
||||
|
||||
params = {"name": "test", "path": str(config.settings.Server.projects_path), "project_id": "00010203-0405-0607-0809-0a0b0c0d0e0f"}
|
||||
|
||||
params = {
|
||||
"name": "test",
|
||||
"path": str(config.settings.Server.projects_path),
|
||||
"project_id": "00010203-0405-0607-0809-0a0b0c0d0e0f",
|
||||
}
|
||||
response = await client.post(app.url_path_for("create_project"), json=params)
|
||||
# The projects directory itself must never become a project directory
|
||||
assert response.status_code == status.HTTP_403_FORBIDDEN
|
||||
|
||||
params = {"name": "test", "path": os.path.join(str(config.settings.Server.projects_path), "custom"), "project_id": "00010203-0405-0607-0809-0a0b0c0d0e0f"}
|
||||
params = {
|
||||
"name": "test",
|
||||
"path": os.path.join(str(config.settings.Server.projects_path), "custom"),
|
||||
"project_id": "00010203-0405-0607-0809-0a0b0c0d0e0f",
|
||||
}
|
||||
response = await client.post(app.url_path_for("create_project"), json=params)
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
assert response.json()["name"] == "test"
|
||||
assert response.json()["project_id"] == "00010203-0405-0607-0809-0a0b0c0d0e0f"
|
||||
assert response.json()["status"] == "opened"
|
||||
|
||||
|
||||
async def test_create_project_without_dir(
|
||||
self,
|
||||
app: FastAPI,
|
||||
client: AsyncClient,
|
||||
controller: Controller
|
||||
) -> None:
|
||||
|
||||
|
||||
async def test_create_project_without_dir(self, app: FastAPI, client: AsyncClient, controller: Controller) -> None:
|
||||
|
||||
params = {"name": "test", "project_id": "10010203-0405-0607-0809-0a0b0c0d0e0f"}
|
||||
response = await client.post(app.url_path_for("create_project"), json=params)
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
assert response.json()["project_id"] == "10010203-0405-0607-0809-0a0b0c0d0e0f"
|
||||
assert response.json()["name"] == "test"
|
||||
|
||||
|
||||
async def test_create_project_with_uuid(
|
||||
self,
|
||||
app: FastAPI,
|
||||
client: AsyncClient,
|
||||
controller: Controller
|
||||
) -> None:
|
||||
|
||||
|
||||
async def test_create_project_with_uuid(self, app: FastAPI, client: AsyncClient, controller: Controller) -> None:
|
||||
|
||||
params = {"name": "test", "project_id": "30010203-0405-0607-0809-0a0b0c0d0e0f"}
|
||||
response = await client.post(app.url_path_for("create_project"), json=params)
|
||||
assert response.status_code == 201
|
||||
assert response.json()["project_id"] == "30010203-0405-0607-0809-0a0b0c0d0e0f"
|
||||
assert response.json()["name"] == "test"
|
||||
|
||||
|
||||
|
||||
async def test_create_project_with_variables(
|
||||
self,
|
||||
app: FastAPI,
|
||||
client: AsyncClient,
|
||||
controller: Controller
|
||||
self, app: FastAPI, client: AsyncClient, controller: Controller
|
||||
) -> None:
|
||||
|
||||
variables = [
|
||||
{"name": "TEST1"},
|
||||
{"name": "TEST2", "value": "value1"}
|
||||
]
|
||||
|
||||
variables = [{"name": "TEST1"}, {"name": "TEST2", "value": "value1"}]
|
||||
params = {"name": "test", "project_id": "30010203-0405-0607-0809-0a0b0c0d0e0f", "variables": variables}
|
||||
response = await client.post(app.url_path_for("create_project"), json=params)
|
||||
assert response.status_code == 201
|
||||
assert response.json()["variables"] == [
|
||||
{"name": "TEST1"},
|
||||
{"name": "TEST2", "value": "value1"}
|
||||
]
|
||||
|
||||
assert response.json()["variables"] == [{"name": "TEST1"}, {"name": "TEST2", "value": "value1"}]
|
||||
|
||||
async def test_create_project_with_supplier(
|
||||
self,
|
||||
app: FastAPI,
|
||||
client: AsyncClient,
|
||||
controller: Controller
|
||||
self, app: FastAPI, client: AsyncClient, controller: Controller
|
||||
) -> None:
|
||||
|
||||
supplier = {
|
||||
'logo': 'logo.png',
|
||||
'url': 'http://example.com/'
|
||||
}
|
||||
|
||||
supplier = {"logo": "logo.png", "url": "http://example.com/"}
|
||||
params = {"name": "test", "project_id": "30010203-0405-0607-0809-0a0b0c0d0e0f", "supplier": supplier}
|
||||
response = await client.post(app.url_path_for("create_project"), json=params)
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
assert response.json()["supplier"] == supplier
|
||||
|
||||
|
||||
|
||||
async def test_update_project(self, app: FastAPI, client: AsyncClient, controller: Controller) -> None:
|
||||
|
||||
|
||||
params = {"name": "test", "project_id": "10010203-0405-0607-0809-0a0b0c0d0e0f"}
|
||||
response = await client.post(app.url_path_for("create_project"), json=params)
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
assert response.json()["project_id"] == "10010203-0405-0607-0809-0a0b0c0d0e0f"
|
||||
assert response.json()["name"] == "test"
|
||||
|
||||
|
||||
params = {"name": "test2"}
|
||||
response = await client.put(app.url_path_for("update_project", project_id="10010203-0405-0607-0809-0a0b0c0d0e0f"),
|
||||
json=params)
|
||||
response = await client.put(
|
||||
app.url_path_for("update_project", project_id="10010203-0405-0607-0809-0a0b0c0d0e0f"), json=params
|
||||
)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.json()["name"] == "test2"
|
||||
|
||||
|
||||
|
||||
async def test_update_project_with_variables(
|
||||
self,
|
||||
app: FastAPI,
|
||||
client: AsyncClient,
|
||||
controller: Controller
|
||||
self, app: FastAPI, client: AsyncClient, controller: Controller
|
||||
) -> None:
|
||||
|
||||
variables = [
|
||||
{"name": "TEST1"},
|
||||
{"name": "TEST2", "value": "value1"}
|
||||
]
|
||||
|
||||
variables = [{"name": "TEST1"}, {"name": "TEST2", "value": "value1"}]
|
||||
params = {"name": "test", "project_id": "10010203-0405-0607-0809-0a0b0c0d0e0f", "variables": variables}
|
||||
response = await client.post(app.url_path_for("create_project"), json=params)
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
|
||||
|
||||
params = {"name": "test2"}
|
||||
response = await client.put(app.url_path_for("update_project", project_id="10010203-0405-0607-0809-0a0b0c0d0e0f"),
|
||||
json=params)
|
||||
response = await client.put(
|
||||
app.url_path_for("update_project", project_id="10010203-0405-0607-0809-0a0b0c0d0e0f"), json=params
|
||||
)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.json()["variables"] == variables
|
||||
|
||||
|
||||
|
||||
async def test_list_projects(self, app: FastAPI, client: AsyncClient, controller: Controller) -> None:
|
||||
|
||||
|
||||
params = {"name": "test", "project_id": "00010203-0405-0607-0809-0a0b0c0d0e0f"}
|
||||
await client.post(app.url_path_for("create_project"), json=params)
|
||||
response = await client.get(app.url_path_for("get_projects"))
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
projects = response.json()
|
||||
assert projects[0]["name"] == "test"
|
||||
|
||||
|
||||
|
||||
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))
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.json()["name"] == "test"
|
||||
|
||||
|
||||
|
||||
async def test_delete_project(
|
||||
self,
|
||||
app: FastAPI,
|
||||
client: AsyncClient,
|
||||
project: Project,
|
||||
controller: Controller
|
||||
self, app: FastAPI, client: AsyncClient, project: Project, controller: Controller
|
||||
) -> None:
|
||||
|
||||
|
||||
with asyncio_patch("gns3server.controller.project.Project.delete", return_value=True) as mock:
|
||||
response = await client.delete(app.url_path_for("delete_project", project_id=project.id))
|
||||
assert response.status_code == status.HTTP_204_NO_CONTENT
|
||||
assert mock.called
|
||||
assert project not in controller.projects
|
||||
|
||||
|
||||
|
||||
async def test_delete_project_invalid_uuid(self, app: FastAPI, client: AsyncClient) -> None:
|
||||
|
||||
|
||||
response = await client.delete(app.url_path_for("delete_project", project_id=str(uuid.uuid4())))
|
||||
assert response.status_code == status.HTTP_404_NOT_FOUND
|
||||
|
||||
|
||||
|
||||
async def test_close_project(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
|
||||
|
||||
|
||||
with asyncio_patch("gns3server.controller.project.Project.close", return_value=True) as mock:
|
||||
response = await client.post(app.url_path_for("close_project", project_id=project.id))
|
||||
assert response.status_code == status.HTTP_204_NO_CONTENT
|
||||
assert mock.called
|
||||
|
||||
|
||||
|
||||
async def test_open_project(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
|
||||
|
||||
|
||||
with asyncio_patch("gns3server.controller.project.Project.open", return_value=True) as mock:
|
||||
response = await client.post(app.url_path_for("open_project", project_id=project.id))
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
assert mock.called
|
||||
|
||||
|
||||
|
||||
async def test_load_project(self, app: FastAPI, client: AsyncClient, project: Project, config) -> None:
|
||||
|
||||
|
||||
with asyncio_patch("gns3server.controller.Controller.load_project", return_value=project) as mock:
|
||||
response = await client.post(app.url_path_for("load_project"), json={"path": "/tmp/test.gns3"})
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
mock.assert_called_with("/tmp/test.gns3")
|
||||
assert response.json()["project_id"] == project.id
|
||||
|
||||
|
||||
|
||||
# @pytest.mark.asyncio
|
||||
# async def test_notification(controller_api, http_client, project, controller):
|
||||
#
|
||||
@@ -250,8 +205,7 @@ class TestControllerProjectRoutes:
|
||||
#
|
||||
# response = await controller_api.get("/projects/{project_id}/notifications".format(project_id=uuid.uuid4()))
|
||||
# assert response.status_code == 404
|
||||
|
||||
|
||||
|
||||
# @pytest.mark.asyncio
|
||||
# async def test_notification_ws(controller_api, http_client, controller, project):
|
||||
#
|
||||
@@ -269,179 +223,155 @@ class TestControllerProjectRoutes:
|
||||
# await ws.close()
|
||||
#
|
||||
# assert project.status_code == "opened"
|
||||
|
||||
|
||||
async def test_export_with_images(
|
||||
self,
|
||||
app: FastAPI,
|
||||
client: AsyncClient,
|
||||
tmpdir,
|
||||
project: Project
|
||||
) -> None:
|
||||
|
||||
|
||||
async def test_export_with_images(self, app: FastAPI, client: AsyncClient, tmpdir, project: Project) -> None:
|
||||
|
||||
project.dump = MagicMock()
|
||||
os.makedirs(project.path, exist_ok=True)
|
||||
with open(os.path.join(project.path, 'a'), 'w+') as f:
|
||||
f.write('hello')
|
||||
|
||||
with open(os.path.join(project.path, "a"), "w+") as f:
|
||||
f.write("hello")
|
||||
|
||||
os.makedirs(str(tmpdir / "IOS"))
|
||||
with open(str(tmpdir / "IOS" / "test.image"), "w+") as f:
|
||||
f.write("AAA")
|
||||
|
||||
topology = {
|
||||
"topology": {
|
||||
"nodes": [
|
||||
{
|
||||
"properties": {
|
||||
"image": "test.image"
|
||||
},
|
||||
"node_type": "dynamips"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
with open(os.path.join(project.path, "test.gns3"), 'w+') as f:
|
||||
|
||||
topology = {"topology": {"nodes": [{"properties": {"image": "test.image"}, "node_type": "dynamips"}]}}
|
||||
with open(os.path.join(project.path, "test.gns3"), "w+") as f:
|
||||
json.dump(topology, f)
|
||||
|
||||
|
||||
with patch("gns3server.compute.Dynamips.get_images_directory", return_value=str(tmpdir / "IOS")):
|
||||
response = await client.get(app.url_path_for("export_project", project_id=project.id),
|
||||
params={"include_images": "yes"})
|
||||
response = await client.get(
|
||||
app.url_path_for("export_project", project_id=project.id), params={"include_images": "yes"}
|
||||
)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.headers['CONTENT-TYPE'] == 'application/gns3project'
|
||||
assert response.headers['CONTENT-DISPOSITION'] == 'attachment; filename="{name}.gns3project"; filename*=UTF-8\'\'{name}.gns3project'.format(name=project.name)
|
||||
|
||||
with open(str(tmpdir / 'project.zip'), 'wb+') as f:
|
||||
assert response.headers["CONTENT-TYPE"] == "application/gns3project"
|
||||
assert response.headers[
|
||||
"CONTENT-DISPOSITION"
|
||||
] == "attachment; filename=\"{name}.gns3project\"; filename*=UTF-8''{name}.gns3project".format(
|
||||
name=project.name
|
||||
)
|
||||
|
||||
with open(str(tmpdir / "project.zip"), "wb+") as f:
|
||||
f.write(response.content)
|
||||
|
||||
with zipfile_zstd.ZipFile(str(tmpdir / 'project.zip')) as myzip:
|
||||
|
||||
with zipfile_zstd.ZipFile(str(tmpdir / "project.zip")) as myzip:
|
||||
with myzip.open("a") as myfile:
|
||||
content = myfile.read()
|
||||
assert content == b"hello"
|
||||
myzip.getinfo("images/IOS/test.image")
|
||||
|
||||
|
||||
|
||||
async def test_export_without_images(self, app: FastAPI, client: AsyncClient, tmpdir, project: Project) -> None:
|
||||
|
||||
|
||||
project.dump = MagicMock()
|
||||
os.makedirs(project.path, exist_ok=True)
|
||||
with open(os.path.join(project.path, 'a'), 'w+') as f:
|
||||
f.write('hello')
|
||||
|
||||
with open(os.path.join(project.path, "a"), "w+") as f:
|
||||
f.write("hello")
|
||||
|
||||
os.makedirs(str(tmpdir / "IOS"))
|
||||
with open(str(tmpdir / "IOS" / "test.image"), "w+") as f:
|
||||
f.write("AAA")
|
||||
|
||||
topology = {
|
||||
"topology": {
|
||||
"nodes": [
|
||||
{
|
||||
"properties": {
|
||||
"image": "test.image"
|
||||
},
|
||||
"node_type": "dynamips"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
with open(os.path.join(project.path, "test.gns3"), 'w+') as f:
|
||||
|
||||
topology = {"topology": {"nodes": [{"properties": {"image": "test.image"}, "node_type": "dynamips"}]}}
|
||||
with open(os.path.join(project.path, "test.gns3"), "w+") as f:
|
||||
json.dump(topology, f)
|
||||
|
||||
with patch("gns3server.compute.Dynamips.get_images_directory", return_value=str(tmpdir / "IOS"),):
|
||||
response = await client.get(app.url_path_for("export_project", project_id=project.id),
|
||||
params={"include_images": "0"})
|
||||
|
||||
with patch(
|
||||
"gns3server.compute.Dynamips.get_images_directory",
|
||||
return_value=str(tmpdir / "IOS"),
|
||||
):
|
||||
response = await client.get(
|
||||
app.url_path_for("export_project", project_id=project.id), params={"include_images": "0"}
|
||||
)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.headers['CONTENT-TYPE'] == 'application/gns3project'
|
||||
assert response.headers['CONTENT-DISPOSITION'] == 'attachment; filename="{name}.gns3project"; filename*=UTF-8\'\'{name}.gns3project'.format(name=project.name)
|
||||
with open(str(tmpdir / 'project.zip'), 'wb+') as f:
|
||||
assert response.headers["CONTENT-TYPE"] == "application/gns3project"
|
||||
assert response.headers[
|
||||
"CONTENT-DISPOSITION"
|
||||
] == "attachment; filename=\"{name}.gns3project\"; filename*=UTF-8''{name}.gns3project".format(
|
||||
name=project.name
|
||||
)
|
||||
with open(str(tmpdir / "project.zip"), "wb+") as f:
|
||||
f.write(response.content)
|
||||
|
||||
with zipfile_zstd.ZipFile(str(tmpdir / 'project.zip')) as myzip:
|
||||
|
||||
with zipfile_zstd.ZipFile(str(tmpdir / "project.zip")) as myzip:
|
||||
with myzip.open("a") as myfile:
|
||||
content = myfile.read()
|
||||
assert content == b"hello"
|
||||
# Image should not exported
|
||||
with pytest.raises(KeyError):
|
||||
myzip.getinfo("images/IOS/test.image")
|
||||
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"compression, compression_level, status_code",
|
||||
(
|
||||
("none", None, status.HTTP_200_OK),
|
||||
("none", 4, status.HTTP_400_BAD_REQUEST),
|
||||
("zip", None, status.HTTP_200_OK),
|
||||
("zip", 1, status.HTTP_200_OK),
|
||||
("zip", 12, status.HTTP_400_BAD_REQUEST),
|
||||
("bzip2", None, status.HTTP_200_OK),
|
||||
("bzip2", 1, status.HTTP_200_OK),
|
||||
("bzip2", 13, status.HTTP_400_BAD_REQUEST),
|
||||
("lzma", None, status.HTTP_200_OK),
|
||||
("lzma", 1, status.HTTP_400_BAD_REQUEST),
|
||||
("zstd", None, status.HTTP_200_OK),
|
||||
("zstd", 12, status.HTTP_200_OK),
|
||||
("zstd", 23, status.HTTP_400_BAD_REQUEST),
|
||||
)
|
||||
("none", None, status.HTTP_200_OK),
|
||||
("none", 4, status.HTTP_400_BAD_REQUEST),
|
||||
("zip", None, status.HTTP_200_OK),
|
||||
("zip", 1, status.HTTP_200_OK),
|
||||
("zip", 12, status.HTTP_400_BAD_REQUEST),
|
||||
("bzip2", None, status.HTTP_200_OK),
|
||||
("bzip2", 1, status.HTTP_200_OK),
|
||||
("bzip2", 13, status.HTTP_400_BAD_REQUEST),
|
||||
("lzma", None, status.HTTP_200_OK),
|
||||
("lzma", 1, status.HTTP_400_BAD_REQUEST),
|
||||
("zstd", None, status.HTTP_200_OK),
|
||||
("zstd", 12, status.HTTP_200_OK),
|
||||
("zstd", 23, status.HTTP_400_BAD_REQUEST),
|
||||
),
|
||||
)
|
||||
async def test_export_compression(
|
||||
self,
|
||||
app: FastAPI,
|
||||
client: AsyncClient,
|
||||
tmpdir,
|
||||
project: Project,
|
||||
compression: str,
|
||||
compression_level: int,
|
||||
status_code: int
|
||||
self,
|
||||
app: FastAPI,
|
||||
client: AsyncClient,
|
||||
tmpdir,
|
||||
project: Project,
|
||||
compression: str,
|
||||
compression_level: int,
|
||||
status_code: int,
|
||||
) -> None:
|
||||
|
||||
|
||||
project.dump = MagicMock()
|
||||
os.makedirs(project.path, exist_ok=True)
|
||||
|
||||
topology = {
|
||||
"topology": {
|
||||
"nodes": [
|
||||
{
|
||||
"node_type": "qemu"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
with open(os.path.join(project.path, "test.gns3"), 'w+') as f:
|
||||
|
||||
topology = {"topology": {"nodes": [{"node_type": "qemu"}]}}
|
||||
with open(os.path.join(project.path, "test.gns3"), "w+") as f:
|
||||
json.dump(topology, f)
|
||||
|
||||
|
||||
params = {"compression": compression}
|
||||
if compression_level:
|
||||
params["compression_level"] = compression_level
|
||||
response = await client.get(app.url_path_for("export_project", project_id=project.id), params=params)
|
||||
assert response.status_code == status_code
|
||||
|
||||
|
||||
if response.status_code == status.HTTP_200_OK:
|
||||
assert response.headers['CONTENT-TYPE'] == 'application/gns3project'
|
||||
assert response.headers['CONTENT-DISPOSITION'] == 'attachment; filename="{name}.gns3project"; filename*=UTF-8\'\'{name}.gns3project'.format(name=project.name)
|
||||
with open(str(tmpdir / 'project.zip'), 'wb+') as f:
|
||||
assert response.headers["CONTENT-TYPE"] == "application/gns3project"
|
||||
assert response.headers[
|
||||
"CONTENT-DISPOSITION"
|
||||
] == "attachment; filename=\"{name}.gns3project\"; filename*=UTF-8''{name}.gns3project".format(
|
||||
name=project.name
|
||||
)
|
||||
with open(str(tmpdir / "project.zip"), "wb+") as f:
|
||||
f.write(response.content)
|
||||
|
||||
with zipfile_zstd.ZipFile(str(tmpdir / 'project.zip')) as myzip:
|
||||
|
||||
with zipfile_zstd.ZipFile(str(tmpdir / "project.zip")) as myzip:
|
||||
with myzip.open("project.gns3") as myfile:
|
||||
myfile.read()
|
||||
|
||||
|
||||
|
||||
async def test_get_file(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
|
||||
|
||||
|
||||
os.makedirs(project.path, exist_ok=True)
|
||||
with open(os.path.join(project.path, 'hello'), 'w+') as f:
|
||||
f.write('world')
|
||||
|
||||
with open(os.path.join(project.path, "hello"), "w+") as f:
|
||||
f.write("world")
|
||||
|
||||
response = await client.get(app.url_path_for("get_file", project_id=project.id, file_path="hello"))
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.content == b"world"
|
||||
|
||||
|
||||
response = await client.get(app.url_path_for("get_file", project_id=project.id, file_path="false"))
|
||||
assert response.status_code == status.HTTP_404_NOT_FOUND
|
||||
|
||||
|
||||
response = await client.get(app.url_path_for("get_file", project_id=project.id, file_path="../hello"))
|
||||
assert response.status_code == status.HTTP_404_NOT_FOUND
|
||||
|
||||
|
||||
async def test_get_project_gns3_file(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
|
||||
|
||||
response = await client.get(app.url_path_for("get_project_gns3_file", project_id=project.id))
|
||||
@@ -451,7 +381,6 @@ class TestControllerProjectRoutes:
|
||||
assert topology["name"] == "test"
|
||||
assert "topology" in topology
|
||||
|
||||
|
||||
async def test_get_project_gns3_file_raw_content(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
|
||||
|
||||
# the endpoint must serve the raw file content, without the project being opened
|
||||
@@ -470,145 +399,142 @@ class TestControllerProjectRoutes:
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.json() == topology
|
||||
|
||||
|
||||
async def test_get_project_gns3_file_project_not_found(self, app: FastAPI, client: AsyncClient) -> None:
|
||||
|
||||
response = await client.get(app.url_path_for("get_project_gns3_file", project_id=str(uuid.uuid4())))
|
||||
assert response.status_code == status.HTTP_404_NOT_FOUND
|
||||
|
||||
|
||||
async def test_get_file_forbidden_location(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
|
||||
|
||||
|
||||
file_path = "foo/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd"
|
||||
response = await client.get(app.url_path_for("get_file", project_id=project.id, file_path=file_path))
|
||||
assert response.status_code == status.HTTP_403_FORBIDDEN
|
||||
|
||||
|
||||
|
||||
async def test_write_file(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
|
||||
|
||||
response = await client.post(app.url_path_for("write_file", project_id=project.id, file_path="hello"),
|
||||
content=b"world")
|
||||
|
||||
response = await client.post(
|
||||
app.url_path_for("write_file", project_id=project.id, file_path="hello"), content=b"world"
|
||||
)
|
||||
assert response.status_code == status.HTTP_204_NO_CONTENT
|
||||
|
||||
|
||||
with open(os.path.join(project.path, "hello")) as f:
|
||||
assert f.read() == "world"
|
||||
|
||||
|
||||
response = await client.post(app.url_path_for("write_file", project_id=project.id, file_path="../hello"))
|
||||
assert response.status_code == status.HTTP_404_NOT_FOUND
|
||||
|
||||
|
||||
|
||||
async def test_write_file_forbidden_location(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
|
||||
|
||||
|
||||
file_path = "%2e%2e/hello"
|
||||
response = await client.post(app.url_path_for("write_file", project_id=project.id, file_path=file_path),
|
||||
content=b"world")
|
||||
response = await client.post(
|
||||
app.url_path_for("write_file", project_id=project.id, file_path=file_path), content=b"world"
|
||||
)
|
||||
assert response.status_code == status.HTTP_403_FORBIDDEN
|
||||
|
||||
|
||||
|
||||
async def test_write_and_get_file_with_leading_slashes_in_filename(
|
||||
self,
|
||||
app: FastAPI,
|
||||
client: AsyncClient,
|
||||
project: Project) -> None:
|
||||
|
||||
response = await client.post(app.url_path_for("write_file", project_id=project.id, file_path="//hello"),
|
||||
content=b"world")
|
||||
self, app: FastAPI, client: AsyncClient, project: Project
|
||||
) -> None:
|
||||
|
||||
response = await client.post(
|
||||
app.url_path_for("write_file", project_id=project.id, file_path="//hello"), content=b"world"
|
||||
)
|
||||
assert response.status_code == status.HTTP_403_FORBIDDEN
|
||||
|
||||
|
||||
response = await client.get(app.url_path_for("get_file", project_id=project.id, file_path="//hello"))
|
||||
assert response.status_code == status.HTTP_403_FORBIDDEN
|
||||
|
||||
|
||||
|
||||
async def test_import(self, app: FastAPI, client: AsyncClient, tmpdir, controller: Controller) -> None:
|
||||
|
||||
with zipfile_zstd.ZipFile(str(tmpdir / "test.zip"), 'w') as myzip:
|
||||
myzip.writestr("project.gns3", b'{"project_id": "c6992992-ac72-47dc-833b-54aa334bcd05", "version": "2.0.0", "name": "test"}')
|
||||
|
||||
with zipfile_zstd.ZipFile(str(tmpdir / "test.zip"), "w") as myzip:
|
||||
myzip.writestr(
|
||||
"project.gns3",
|
||||
b'{"project_id": "c6992992-ac72-47dc-833b-54aa334bcd05", "version": "2.0.0", "name": "test"}',
|
||||
)
|
||||
myzip.writestr("demo", b"hello")
|
||||
|
||||
|
||||
project_id = str(uuid.uuid4())
|
||||
with open(str(tmpdir / "test.zip"), "rb") as f:
|
||||
response = await client.post(app.url_path_for("import_project", project_id=project_id), content=f.read())
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
|
||||
|
||||
project = controller.get_project(project_id)
|
||||
with open(os.path.join(project.path, "demo")) as f:
|
||||
content = f.read()
|
||||
assert content == "hello"
|
||||
|
||||
|
||||
|
||||
async def test_import_with_project_name(
|
||||
self,
|
||||
app: FastAPI,
|
||||
client: AsyncClient,
|
||||
tmpdir,
|
||||
controller: Controller
|
||||
self, app: FastAPI, client: AsyncClient, tmpdir, controller: Controller
|
||||
) -> None:
|
||||
|
||||
with zipfile_zstd.ZipFile(str(tmpdir / "test.zip"), 'w') as myzip:
|
||||
myzip.writestr("project.gns3", b'{"project_id": "c6992992-ac72-47dc-833b-54aa334bcd05", "version": "2.0.0", "name": "test"}')
|
||||
|
||||
with zipfile_zstd.ZipFile(str(tmpdir / "test.zip"), "w") as myzip:
|
||||
myzip.writestr(
|
||||
"project.gns3",
|
||||
b'{"project_id": "c6992992-ac72-47dc-833b-54aa334bcd05", "version": "2.0.0", "name": "test"}',
|
||||
)
|
||||
myzip.writestr("demo", b"hello")
|
||||
|
||||
|
||||
project_id = str(uuid.uuid4())
|
||||
with open(str(tmpdir / "test.zip"), "rb") as f:
|
||||
response = await client.post(
|
||||
app.url_path_for("import_project", project_id=project_id),
|
||||
content=f.read(),
|
||||
params={"name": "my-imported-project-name"}
|
||||
params={"name": "my-imported-project-name"},
|
||||
)
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
project = controller.get_project(project_id)
|
||||
assert project.name == "my-imported-project-name"
|
||||
|
||||
|
||||
|
||||
async def test_duplicate(self, app: FastAPI, client: AsyncClient, project: Project) -> None:
|
||||
|
||||
response = await client.post(app.url_path_for("duplicate_project", project_id=project.id), json={"name": "hello"})
|
||||
|
||||
response = await client.post(
|
||||
app.url_path_for("duplicate_project", project_id=project.id), json={"name": "hello"}
|
||||
)
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
assert response.json()["name"] == "hello"
|
||||
|
||||
|
||||
|
||||
async def test_lock_unlock(self, app: FastAPI, client: AsyncClient, project: Project, compute: Compute) -> None:
|
||||
|
||||
|
||||
# add a drawing and node to the project
|
||||
params = {
|
||||
"svg": '<svg height="210" width="500"><line x1="0" y1="0" x2="200" y2="200" style="stroke:rgb(255,0,0);stroke-width:2" /></svg>',
|
||||
"x": 10,
|
||||
"y": 20,
|
||||
"z": 0
|
||||
"z": 0,
|
||||
}
|
||||
|
||||
|
||||
response = await client.post(app.url_path_for("create_drawing", project_id=project.id), json=params)
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
|
||||
|
||||
response = MagicMock()
|
||||
response.json = {"console": 2048}
|
||||
compute.post = AsyncioMagicMock(return_value=response)
|
||||
|
||||
response = await client.post(app.url_path_for("create_node", project_id=project.id), json={
|
||||
"name": "test",
|
||||
"node_type": "vpcs",
|
||||
"compute_id": "example.com",
|
||||
"properties": {
|
||||
"startup_script": "echo test"
|
||||
}
|
||||
})
|
||||
|
||||
response = await client.post(
|
||||
app.url_path_for("create_node", project_id=project.id),
|
||||
json={
|
||||
"name": "test",
|
||||
"node_type": "vpcs",
|
||||
"compute_id": "example.com",
|
||||
"properties": {"startup_script": "echo test"},
|
||||
},
|
||||
)
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
|
||||
|
||||
response = await client.post(app.url_path_for("lock_project", project_id=project.id))
|
||||
assert response.status_code == status.HTTP_204_NO_CONTENT
|
||||
|
||||
|
||||
for drawing in project.drawings.values():
|
||||
assert drawing.locked is True
|
||||
for node in project.nodes.values():
|
||||
assert node.locked is True
|
||||
|
||||
|
||||
response = await client.get(app.url_path_for("locked_project", project_id=project.id))
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.json() is True
|
||||
|
||||
|
||||
response = await client.post(app.url_path_for("unlock_project", project_id=project.id))
|
||||
assert response.status_code == status.HTTP_204_NO_CONTENT
|
||||
|
||||
|
||||
for drawing in project.drawings.values():
|
||||
assert drawing.locked is False
|
||||
for node in project.nodes.values():
|
||||
|
||||
Reference in new issue
Block a user