From d15a406022d428403e82e244da14da5004e9f49e Mon Sep 17 00:00:00 2001 From: Jo Walsh Date: Thu, 12 Sep 2024 08:38:03 +0100 Subject: [PATCH] add a bucket listing GET method and a test --- README.md | 2 +- src/os_api/api.py | 12 ++++++++++++ tests/conftest.py | 3 ++- tests/test_api.py | 47 ++++++++++++++++++++++++++++++++--------------- 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index d1ae902..b712550 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ pip install -e .[docs] To work on tests: ``` -pip install -e .[tests] +pip install -e .[test] ``` To run the linter and githook: diff --git a/src/os_api/api.py b/src/os_api/api.py index 9c37e05..dd98c48 100644 --- a/src/os_api/api.py +++ b/src/os_api/api.py @@ -89,6 +89,18 @@ async def main() -> RedirectResponse: return RedirectResponse(url="/docs") +@app.get("/list-buckets/") +async def list_buckets() -> JSONResponse: + "Endpoint to create a new bucket in the server." + s3 = boto3_client() + bucket_names = [n["Name"] for n in s3.list_buckets()["Buckets"]] + try: + return JSONResponse(status_code=200, content=bucket_names) + except Exception as err: + logging.info(err) + return JSONResponse(status_code=500, content=f"Error while listing buckets: {str(err)}") + + @app.post("/create-bucket/", tags=["Data"]) async def create_bucket(bucket_name: str = Query("", description="")) -> JSONResponse: "Endpoint to create a new bucket in the server." diff --git a/tests/conftest.py b/tests/conftest.py index 149425c..cb5485f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,7 @@ import os import pytest + @pytest.fixture def fixture_dir(): """ @@ -14,4 +15,4 @@ def text_file(fixture_dir): """ Sample text file """ - return open(os.path.join(fixture_dir, "1_test.txt"), 'rb') \ No newline at end of file + return open(os.path.join(fixture_dir, "1_test.txt"), "rb") diff --git a/tests/test_api.py b/tests/test_api.py index 99a1bf1..dd7e76f 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -6,6 +6,7 @@ At level of "do endpoints exist, and resolve" """ + import os from os_api.api import app, s3_endpoint import pytest @@ -14,10 +15,12 @@ from fastapi.testclient import TestClient from moto import mock_aws import logging + logging.basicConfig(level=logging.INFO) from moto.server import ThreadedMotoServer + @pytest.fixture(scope="module") def moto_server(): """Fixture to run a mocked AWS server for testing.""" @@ -25,50 +28,64 @@ def moto_server(): server = ThreadedMotoServer(port=0) server.start() host, port = server.get_host_and_port() - os.environ['AWS_URL_ENDPOINT'] = f"http://{host}:{port}" + os.environ["AWS_URL_ENDPOINT"] = f"http://{host}:{port}" yield f"http://{host}:{port}" server.stop() + # Without both the dependency override _and_ the environment variable set in the fixture, # the endpoint URL doesn't get set for the API properly - wish i fully understood why! - JW app.dependency_overrides[s3_endpoint] = moto_server client = TestClient(app) + def test_read_main(): response = client.get("/") assert response.status_code == 200 def test_create_bucket(moto_server): - params = {'bucket_name': 'test_bucket'} - response = client.post('/create-bucket/', params=params) + params = {"bucket_name": "test_bucket"} + response = client.post("/create-bucket/", params=params) assert response.status_code == 200 def test_generate_presigned_url(moto_server): - params = {'filename': 'demo.txt', - 'file_type': 'text/plain', - 'bucket_name': 'test_bucket'} - response = client.post('/generate-presigned-url/', data=params) + params = { + "filename": "demo.txt", + "file_type": "text/plain", + "bucket_name": "test_bucket", + } + response = client.post("/generate-presigned-url/", data=params) assert response.status_code == 200 def test_upload(text_file): - data = {'bucket_name': 'test_bucket'} - response = client.post('/create-bucket/', params=data) - response = client.post('/upload/', data=data, files=[('files', text_file)]) + data = {"bucket_name": "test_bucket"} + response = client.post("/create-bucket/", params=data) + response = client.post("/upload/", data=data, files=[("files", text_file)]) assert response.status_code == 200 def test_check_file_exist(text_file): - data = {'bucket_name': 'test_bucket'} - response = client.post('/create-bucket/', params=data) - response = client.post('/upload/', data=data, files=[('files', text_file)]) - data['filename'] = "1_test.txt" - response = client.post('/check-file-exist/', data=data) + data = {"bucket_name": "test_bucket"} + response = client.post("/create-bucket/", params=data) + response = client.post("/upload/", data=data, files=[("files", text_file)]) + data["filename"] = "1_test.txt" + response = client.post("/check-file-exist/", data=data) assert response.status_code == 200 +def test_list_buckets(): + buckets = ["hello", "world"] + for b in buckets: + client.post("/create-bucket/", params={"bucket_name": b}) + res = client.get("/list-buckets/") + bucket_list = res.json() + for b in buckets: + assert b in bucket_list + + def test_import_api_module(): import os_api.api