diff --git a/tests/api/v1/software/software-header-2.swu b/tests/api/v1/software/software-header-2.swu new file mode 100644 index 00000000..4fa6112b Binary files /dev/null and b/tests/api/v1/software/software-header-2.swu differ diff --git a/tests/api/v1/software/test_routes.py b/tests/api/v1/software/test_routes.py index 5eb686e8..41bcbbc1 100644 --- a/tests/api/v1/software/test_routes.py +++ b/tests/api/v1/software/test_routes.py @@ -1,6 +1,8 @@ import pytest from anyio import Path, open_file +from goosebit.db.models import Rollout + @pytest.mark.asyncio async def test_create_software_local(async_client, test_data): @@ -16,6 +18,21 @@ async def test_create_software_local(async_client, test_data): assert software["id"] == 4 +@pytest.mark.asyncio +async def test_create_software_local_twice(async_client, test_data): + resolved = await Path(__file__).resolve() + path = resolved.parent / "software-header.swu" + with open(path, "rb") as file: + files = {"file": file} + response = await async_client.post(f"/api/v1/software", files=files) + assert response.status_code == 200 + + with open(path, "rb") as file: + files = {"file": file} + response = await async_client.post(f"/api/v1/software", files=files) + assert response.status_code == 409 + + @pytest.mark.asyncio async def test_create_software_remote(async_client, httpserver, test_data): resolved = await Path(__file__).resolve() @@ -31,3 +48,64 @@ async def test_create_software_remote(async_client, httpserver, test_data): assert response.status_code == 200 software = response.json() assert software["id"] == 4 + + +@pytest.mark.asyncio +async def test_create_software_remote_twice_same_content_different_url(async_client, httpserver, test_data): + response = await _upload_software(async_client, httpserver, "software-header.swu", "/software-header.swu") + assert response.status_code == 200 + + response = await _upload_software(async_client, httpserver, "software-header.swu", "/software-header-2.swu") + assert response.status_code == 409 + + +@pytest.mark.asyncio +async def test_create_software_remote_twice_different_content_different_url(async_client, httpserver, test_data): + response = await _upload_software(async_client, httpserver, "software-header.swu", "/software-header.swu") + assert response.status_code == 200 + software = response.json() + software_id = software["id"] + + response = await _upload_software(async_client, httpserver, "software-header-2.swu", "/software-header-2.swu") + assert response.status_code == 200 + software = response.json() + assert software_id != software["id"], "added second software" + + +@pytest.mark.asyncio +async def test_create_software_remote_twice_different_content_same_url(async_client, httpserver, test_data): + response = await _upload_software(async_client, httpserver, "software-header.swu", "/software-header.swu") + assert response.status_code == 200 + software = response.json() + software_id = software["id"] + + response = await _upload_software(async_client, httpserver, "software-header-2.swu", "/software-header.swu") + assert response.status_code == 200 + software = response.json() + assert software_id != software["id"], "added second software" + + +@pytest.mark.asyncio +async def test_create_software_remote_twice_different_content_same_url_referenced_by_rollout( + async_client, httpserver, test_data +): + response = await _upload_software(async_client, httpserver, "software-header.swu", "/software-header.swu") + assert response.status_code == 200 + software = response.json() + software_id = software["id"] + + await Rollout.create(name=f"Test rollout", software_id=software_id) + + response = await _upload_software(async_client, httpserver, "software-header-2.swu", "/software-header.swu") + assert response.status_code == 409 + + +async def _upload_software(async_client, httpserver, software_file, download_url): + resolved = await Path(__file__).resolve() + path = resolved.parent / software_file + with open(path, "rb") as file: + byte_array = file.read() + httpserver.expect_request(download_url).respond_with_data(byte_array) + software_url = httpserver.url_for(download_url) + response = await async_client.post(f"/api/v1/software", data={"url": software_url}) + return response