diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9b38853 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "python.testing.pytestArgs": [ + "tests" + ], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true +} \ No newline at end of file diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/routes/routes121.py b/routes/routes121.py index acdd384..8c6f274 100644 --- a/routes/routes121.py +++ b/routes/routes121.py @@ -10,7 +10,7 @@ router = APIRouter() @router.post("/kobo-to-121") -async def kobo_to_121(request: Request, dependencies=Depends(required_headers_121)): +async def kobo_to_121(request: Request, dependencies=Depends(required_headers_121), test_mode: bool = False): """Send a Kobo submission to 121.""" kobo_data = await request.json() @@ -78,8 +78,12 @@ async def kobo_to_121(request: Request, dependencies=Depends(required_headers_12 payload["referenceId"] = referenceId - access_token = login121(request.headers["url121"], request.headers["username121"], request.headers["password121"]) + # If test_mode is True, return the payload without posting it + if test_mode: + return JSONResponse(status_code=200, content={"payload": payload}) + # Continue with the POST if not in test mode + access_token = login121(request.headers["url121"], request.headers["username121"], request.headers["password121"]) # POST to 121 import endpoint import_response = requests.post( diff --git a/tests/.gitignore b/tests/.gitignore deleted file mode 100644 index c96a04f..0000000 --- a/tests/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/tests/kobo_data.json b/tests/kobo_data.json new file mode 100644 index 0000000..733b4d9 --- /dev/null +++ b/tests/kobo_data.json @@ -0,0 +1,67 @@ +{ + "_id": 4747784, + "formhub/uuid": "118047ed44ed4896b3e6c443736442c6", + "start": "2024-10-22T11:25:13.638+00:00", + "end": "2024-10-22T11:25:13.638+00:00", + "date": "2024-04-16", + "zrcsName": "adsf", + "wardName": "Sinazongwe", + "fullName": "asdf", + "birthYear": "1600", + "sex": "Female", + "deputyMain": "Beneficiary", + "selectionCriteria": "Disabled", + "phoneNumber": "0612345678", + "NRC": "12345", + "NRCpicture": "Orka-14_36_18.jpg", + "bankaccountnumber": "12345678", + "preferredLanguage": "en", + "maxPayments": "5", + "fspName": "Excel", + "validation": "TRUE", + "phase": "registrationValidation", + "location": "testLocation", + "ngo": "test NGO", + "language": "en", + "titlePortal": "Program Test", + "description": "example descr", + "startDate": "23/03/2024", + "endDate": "23/03/2024", + "currency": "EUR", + "distributionFrequency": "week", + "distributionDuration": "4", + "fixedTransferValue": "100", + "targetNrRegistrations": "10", + "tryWhatsAppFirst": "FALSE", + "phoneNumberPlaceholder": "32000000000", + "aboutProgram": "blabla", + "fullnameNamingConvention": "fullname", + "enableMaxPayments": "TRUE", + "__version__": "v3hjpKddSa5rv6QzNw86mP", + "meta/instanceID": "uuid:7e7b954f-83e6-406f-9335-368ae153f1aa", + "_xform_id_string": "aPYSXuXP6o9YS8zU39TkyL", + "_uuid": "7e7b954f-83easdfadsfasdfadsfad", + "_attachments": [ + { + "download_url": "https://kc.ifrc.org/media/original?media_file=user%2Fattachments%2F118047ed44ed4896b3e6c443736442c6%2F7e7b954f-83e6-406f-9335-368ae153f1aa%2FOrka-14_36_18.jpg", + "download_large_url": "https://kc.ifrc.org/media/large?media_file=user%2Fattachments%2F118047ed44ed4896b3e6c443736442c6%2F7e7b954f-83e6-406f-9335-368ae153f1aa%2FOrka-14_36_18.jpg", + "download_medium_url": "https://kc.ifrc.org/media/medium?media_file=user%2Fattachments%2F118047ed44ed4896b3e6c443736442c6%2F7e7b954f-83e6-406f-9335-368ae153f1aa%2FOrka-14_36_18.jpg", + "download_small_url": "https://kc.ifrc.org/media/small?media_file=user%2Fattachments%2F118047ed44ed4896b3e6c443736442c6%2F7e7b954f-83e6-406f-9335-368ae153f1aa%2FOrka-14_36_18.jpg", + "mimetype": "image/jpeg", + "filename": "user/attachments/118047ed44ed4896b3e6c443736442c6/7e7b954f-83e6-406f-9335-368ae153f1aa/Orka-14_36_18.jpg", + "instance": 4747784, + "xform": 13224, + "id": 1472086 + } + ], + "_status": "submitted_via_web", + "_geolocation": [ + null, + null + ], + "_submission_time": "2024-10-22T11:25:13", + "_tags": [], + "_notes": [], + "_validation_status": {}, + "_submitted_by": "xxxx" +} \ No newline at end of file diff --git a/tests/kobo_headers.json b/tests/kobo_headers.json new file mode 100644 index 0000000..9fd8964 --- /dev/null +++ b/tests/kobo_headers.json @@ -0,0 +1,33 @@ +{ + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate", + "Bankaccountnumber": "bankaccountnumber", + "Birthyear": "birthYear", + "Content-Length": "2445", + "Content-Type": "application/json", + "Date": "date", + "Deputymain": "deputyMain", + "Deputyname": "deputyName", + "Deputynrc": "deputyNRC", + "Fspname": "fspName", + "Fullname": "fullName", + "Host": "host.com", + "Maxpayments": "maxPayments", + "Nrc": "NRC", + "Nrcpicture": "NRCpicture", + "Password121": "xxxxxxxxxxxxxx", + "Phonenumber": "phoneNumber", + "Preferredlanguage": "preferredLanguage", + "Programid": "21", + "Selectioncriteria": "selectionCriteria", + "Sentry-Trace": "68084d18d6c5422ba491f595439b7863-9999e8c4e6e7c966-0", + "Sex": "sex", + "Url121": "https://pytest.121.global", + "User-Agent": "KoboToolbox external service #hKDcTxuQ5VPipaZN53yLT7", + "Username121": "kobo-user@pytest.121.global", + "Wardname": "wardName", + "X-Forwarded-For": "18.194.217.16", + "X-Forwarded-Proto": "https", + "Zrcsname": "zrcsName" + } + \ No newline at end of file diff --git a/tests/test_health.py b/tests/test_health.py new file mode 100644 index 0000000..28a9712 --- /dev/null +++ b/tests/test_health.py @@ -0,0 +1,14 @@ +import sys +import os +from fastapi.testclient import TestClient + +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) + +from main import app + +client = TestClient(app) + +def test_health(): + response = client.get("/health") + assert response.status_code == 200 + assert response.json() == {"kobo-connect": 200,"kobo.ifrc.org": 200} diff --git a/tests/test_koboto121.py b/tests/test_koboto121.py new file mode 100644 index 0000000..ec37521 --- /dev/null +++ b/tests/test_koboto121.py @@ -0,0 +1,59 @@ +import sys +import os +import json +from fastapi.testclient import TestClient + +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) + +from main import app + +client = TestClient(app) + +with open(os.path.join(os.path.dirname(__file__), 'kobo_data.json'), 'r') as file: + kobo_data = json.load(file) + +with open(os.path.join(os.path.dirname(__file__), 'kobo_headers.json'), 'r') as file: + kobo_headers = json.load(file) + +def test_kobo_to_121_payload(): + + response = client.post( + "/kobo-to-121?test_mode=true", + headers=kobo_headers, + json=kobo_data + ) + + response_data = response.json() + + assert response.status_code == 200 + assert "payload" in response_data + + payload = response_data["payload"] + + assert payload["bankaccountnumber"] == "12345678" + assert payload["birthYear"] == "1600" + assert payload["date"] == "2024-04-16" + assert payload["deputyMain"] == "Beneficiary" + assert payload["fspName"] == "Excel" + assert payload["fullName"] == "asdf" + assert payload["maxPayments"] == 5 + assert payload["NRC"] == "12345" + assert payload["NRCpicture"] == "https://kc.ifrc.org/media/large?media_file=user%2Fattachments%2F118047ed44ed4896b3e6c443736442c6%2F7e7b954f-83e6-406f-9335-368ae153f1aa%2FOrka-14_36_18.jpg" + assert payload["phoneNumber"] == "0612345678" + assert payload["preferredLanguage"] == "en" + assert payload["selectionCriteria"] == "Disabled" + assert payload["sex"] == "Female" + assert payload["wardName"] == "Sinazongwe" + assert payload["zrcsName"] == "adsf" + assert payload["referenceId"] == "7e7b954f-83easdfadsfasdfadsfad" + +def test_kobo_to_121_skipconnect(): + payload = kobo_data.copy() + payload["skipconnect"] = "1" + headers = kobo_headers.copy() + headers["skipconnect"] = "skipconnect" + + response = client.post("/kobo-to-121", headers= headers, json=payload) + + assert response.status_code == 200 + assert response.json() == {"message": "Skipping connection to 121"}