From ad95c8667f60d59f44837a76aa49f4a94a31c07d Mon Sep 17 00:00:00 2001 From: shri Date: Wed, 12 Feb 2025 16:26:23 +0100 Subject: [PATCH 1/4] Code cleanup --- .../domain/opportunities/controllers/opportunities.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/app/domain/opportunities/controllers/opportunities.py b/src/app/domain/opportunities/controllers/opportunities.py index f080f4f9..982389ef 100644 --- a/src/app/domain/opportunities/controllers/opportunities.py +++ b/src/app/domain/opportunities/controllers/opportunities.py @@ -81,17 +81,6 @@ async def list_opportunities( if opportunity.company and opportunity.company.url: opportunity.company.profile_pic_url = get_logo_dev_link(opportunity.company.url) - """ - # Get latest app details - if opportunity.company.ios_app_url: - ios_app_details = await get_ios_app_details(opportunity.company.ios_app_url) - opportunity.company.ios_app_details = AppDetails(**ios_app_details) - - if opportunity.company.android_app_url: - android_app_details = await get_android_app_details(opportunity.company.android_app_url) - opportunity.company.android_app_details = AppDetails(**android_app_details) - """ - return paginated_response @post( From ee31b8b927da958a3479fdfaf1730092f158d4e3 Mon Sep 17 00:00:00 2001 From: shri Date: Wed, 12 Feb 2025 17:34:38 +0100 Subject: [PATCH 2/4] Add API tests generated by Chapter --- .../validation/test_post_api-access-login.py | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 chapter_api_tests/0.2.0/validation/test_post_api-access-login.py diff --git a/chapter_api_tests/0.2.0/validation/test_post_api-access-login.py b/chapter_api_tests/0.2.0/validation/test_post_api-access-login.py new file mode 100644 index 00000000..dcd88db5 --- /dev/null +++ b/chapter_api_tests/0.2.0/validation/test_post_api-access-login.py @@ -0,0 +1,121 @@ +import os +import pytest +import httpx + +API_BASE_URL = os.getenv('API_BASE_URL') + + +@pytest.mark.asyncio +async def test_login_success(): + url = f'{API_BASE_URL}/api/access/login' + payload = {'username': 'testuser', 'password': 'testpass'} + response = await httpx.post(url, json=payload) + + assert response.status_code == 201 + assert response.headers['Content-Type'] == 'application/json' + data = response.json() + assert 'access_token' in data + assert 'token_type' in data + + +@pytest.mark.asyncio +async def test_login_missing_username(): + url = f'{API_BASE_URL}/api/access/login' + payload = {'password': 'testpass'} + response = await httpx.post(url, json=payload) + + assert response.status_code == 400 + data = response.json() + assert data['status_code'] == 400 + assert data['detail'] == 'Bad Request' + + +@pytest.mark.asyncio +async def test_login_missing_password(): + url = f'{API_BASE_URL}/api/access/login' + payload = {'username': 'testuser'} + response = await httpx.post(url, json=payload) + + assert response.status_code == 400 + data = response.json() + assert data['status_code'] == 400 + assert data['detail'] == 'Bad Request' + + +@pytest.mark.asyncio +async def test_login_invalid_credentials(): + url = f'{API_BASE_URL}/api/access/login' + payload = {'username': 'invaliduser', 'password': 'wrongpass'} + response = await httpx.post(url, json=payload) + + assert response.status_code == 400 + data = response.json() + assert data['status_code'] == 400 + assert data['detail'] == 'Bad Request' + + +@pytest.mark.asyncio +async def test_login_empty_payload(): + url = f'{API_BASE_URL}/api/access/login' + response = await httpx.post(url, json={}) + + assert response.status_code == 400 + data = response.json() + assert data['status_code'] == 400 + assert data['detail'] == 'Bad Request' + + +@pytest.mark.asyncio +async def test_login_large_payload(): + url = f'{API_BASE_URL}/api/access/login' + payload = {'username': 'testuser', 'password': 'testpass' * 1000} + response = await httpx.post(url, json=payload) + + assert response.status_code == 400 + data = response.json() + assert data['status_code'] == 400 + assert data['detail'] == 'Bad Request' + + +@pytest.mark.asyncio +async def test_login_unauthorized(): + url = f'{API_BASE_URL}/api/access/login' + payload = {'username': 'testuser', 'password': 'wrongpass'} + response = await httpx.post(url, json=payload) + + assert response.status_code == 400 + data = response.json() + assert data['status_code'] == 400 + assert data['detail'] == 'Bad Request' + + +@pytest.mark.asyncio +async def test_login_forbidden(): + url = f'{API_BASE_URL}/api/access/login' + payload = {'username': 'forbiddenuser', 'password': 'forbiddenpass'} + response = await httpx.post(url, json=payload) + + assert response.status_code == 400 + data = response.json() + assert data['status_code'] == 400 + assert data['detail'] == 'Bad Request' + + +@pytest.mark.asyncio +async def test_login_malformed_request(): + url = f'{API_BASE_URL}/api/access/login' + response = await httpx.post(url, data='malformed data') + + assert response.status_code == 400 + data = response.json() + assert data['status_code'] == 400 + assert data['detail'] == 'Bad Request' + + +@pytest.mark.asyncio +async def test_login_server_error(): + url = f'{API_BASE_URL}/api/access/login' + # Simulate server error by sending a request to an invalid endpoint + response = await httpx.post(url + '/invalid', json={'username': 'testuser', 'password': 'testpass'}) + + assert response.status_code == 500 From 503f113127b246c5d7ba551a4665cea2eea3cd92 Mon Sep 17 00:00:00 2001 From: shri Date: Wed, 12 Feb 2025 17:50:58 +0100 Subject: [PATCH 3/4] Add API tests generated by Chapter --- .../validation/test_post_api-access-login.py | 65 +++++++++---------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/chapter_api_tests/0.2.0/validation/test_post_api-access-login.py b/chapter_api_tests/0.2.0/validation/test_post_api-access-login.py index dcd88db5..a5f7c582 100644 --- a/chapter_api_tests/0.2.0/validation/test_post_api-access-login.py +++ b/chapter_api_tests/0.2.0/validation/test_post_api-access-login.py @@ -13,9 +13,8 @@ async def test_login_success(): assert response.status_code == 201 assert response.headers['Content-Type'] == 'application/json' - data = response.json() - assert 'access_token' in data - assert 'token_type' in data + assert 'access_token' in response.json() + assert 'token_type' in response.json() @pytest.mark.asyncio @@ -25,9 +24,8 @@ async def test_login_missing_username(): response = await httpx.post(url, json=payload) assert response.status_code == 400 - data = response.json() - assert data['status_code'] == 400 - assert data['detail'] == 'Bad Request' + assert response.json()['status_code'] == 400 + assert response.json()['detail'] == 'Bad Request' @pytest.mark.asyncio @@ -37,32 +35,41 @@ async def test_login_missing_password(): response = await httpx.post(url, json=payload) assert response.status_code == 400 - data = response.json() - assert data['status_code'] == 400 - assert data['detail'] == 'Bad Request' + assert response.json()['status_code'] == 400 + assert response.json()['detail'] == 'Bad Request' @pytest.mark.asyncio -async def test_login_invalid_credentials(): +async def test_login_empty_username(): url = f'{API_BASE_URL}/api/access/login' - payload = {'username': 'invaliduser', 'password': 'wrongpass'} + payload = {'username': '', 'password': 'testpass'} + response = await httpx.post(url, json=payload) + + assert response.status_code == 400 + assert response.json()['status_code'] == 400 + assert response.json()['detail'] == 'Bad Request' + + +@pytest.mark.asyncio +async def test_login_empty_password(): + url = f'{API_BASE_URL}/api/access/login' + payload = {'username': 'testuser', 'password': ''} response = await httpx.post(url, json=payload) assert response.status_code == 400 - data = response.json() - assert data['status_code'] == 400 - assert data['detail'] == 'Bad Request' + assert response.json()['status_code'] == 400 + assert response.json()['detail'] == 'Bad Request' @pytest.mark.asyncio -async def test_login_empty_payload(): +async def test_login_invalid_credentials(): url = f'{API_BASE_URL}/api/access/login' - response = await httpx.post(url, json={}) + payload = {'username': 'invaliduser', 'password': 'wrongpass'} + response = await httpx.post(url, json=payload) assert response.status_code == 400 - data = response.json() - assert data['status_code'] == 400 - assert data['detail'] == 'Bad Request' + assert response.json()['status_code'] == 400 + assert response.json()['detail'] == 'Bad Request' @pytest.mark.asyncio @@ -72,9 +79,8 @@ async def test_login_large_payload(): response = await httpx.post(url, json=payload) assert response.status_code == 400 - data = response.json() - assert data['status_code'] == 400 - assert data['detail'] == 'Bad Request' + assert response.json()['status_code'] == 400 + assert response.json()['detail'] == 'Bad Request' @pytest.mark.asyncio @@ -83,10 +89,7 @@ async def test_login_unauthorized(): payload = {'username': 'testuser', 'password': 'wrongpass'} response = await httpx.post(url, json=payload) - assert response.status_code == 400 - data = response.json() - assert data['status_code'] == 400 - assert data['detail'] == 'Bad Request' + assert response.status_code == 401 @pytest.mark.asyncio @@ -95,10 +98,7 @@ async def test_login_forbidden(): payload = {'username': 'forbiddenuser', 'password': 'forbiddenpass'} response = await httpx.post(url, json=payload) - assert response.status_code == 400 - data = response.json() - assert data['status_code'] == 400 - assert data['detail'] == 'Bad Request' + assert response.status_code == 403 @pytest.mark.asyncio @@ -107,9 +107,8 @@ async def test_login_malformed_request(): response = await httpx.post(url, data='malformed data') assert response.status_code == 400 - data = response.json() - assert data['status_code'] == 400 - assert data['detail'] == 'Bad Request' + assert response.json()['status_code'] == 400 + assert response.json()['detail'] == 'Bad Request' @pytest.mark.asyncio From 4d05f7218763e8cd04453a2c12eb3bbf9c6a857f Mon Sep 17 00:00:00 2001 From: shri Date: Thu, 13 Feb 2025 18:14:18 +0100 Subject: [PATCH 4/4] Minor code cleanup --- src/app/domain/companies/schemas.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/app/domain/companies/schemas.py b/src/app/domain/companies/schemas.py index b6676442..f9dd78bf 100644 --- a/src/app/domain/companies/schemas.py +++ b/src/app/domain/companies/schemas.py @@ -46,17 +46,6 @@ def __post_init__(self) -> None: if self.url: self.profile_pic_url = get_logo_dev_link(self.url) - # TODO: Fetch app details but the methods are async - """ - if self.ios_app_url: - ios_app_details = get_ios_app_details(self.ios_app_url) - self.ios_app_details = AppDetails(**ios_app_details) - - if self.android_app_url: - android_app_details = get_android_app_details(self.android_app_url) - self.android_app_details = AppDetails(**android_app_details) - """ - class CompanyCreate(CamelizedBaseStruct): """A company create schema."""