-
Notifications
You must be signed in to change notification settings - Fork 140
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #517 from KindaMAD-hav/feat/referal_endpoint
Feat/referal endpoint
- Loading branch information
Showing
2 changed files
with
178 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
""" | ||
FastAPI app for generating referral links based on wallet IDs. | ||
Endpoint: | ||
- GET /api/create_referal_link: Creates a referral link with a random code for a user. | ||
Dependencies: | ||
- SQLAlchemy: For user lookup in the database. | ||
- FastAPI: For handling API requests. | ||
- random and string: For generating referral codes. | ||
Errors: | ||
- 404: If the user with the provided wallet ID does not exist. | ||
""" | ||
|
||
import random | ||
import string | ||
|
||
from fastapi import APIRouter, Depends, FastAPI, HTTPException, Query | ||
from sqlalchemy.orm import Session | ||
|
||
from web_app.db.database import Base, get_database | ||
from web_app.db.crud import UserDBConnector | ||
from pydantic import BaseModel | ||
|
||
app = FastAPI() | ||
router = APIRouter( | ||
prefix="/api", | ||
tags=["referral"], | ||
responses={404: {"description": "Not found"}}, | ||
) | ||
|
||
|
||
class ReferralResponse(BaseModel): | ||
""" | ||
Response model | ||
""" | ||
|
||
wallet_id: str | ||
referral_code: str | ||
|
||
|
||
def generate_random_string(length=16): | ||
""" | ||
Generate a random string of letters and digits with the given length. | ||
Args: | ||
length (int): Length of the string (default is 16). | ||
Returns: | ||
str: Randomly generated string. | ||
""" | ||
|
||
return "".join(random.choices(string.ascii_letters + string.digits, k=length)) | ||
|
||
|
||
@router.get("/create_referal_link") | ||
async def create_referal_link( | ||
wallet_id: str = Query(..., description="Wallet ID of the user"), | ||
db: Session = Depends(get_database), | ||
): | ||
""" | ||
Create a referral link for a user. | ||
Args: | ||
wallet_id (str): The wallet ID of the user | ||
Returns: | ||
dict: Wallet ID and the generated referral code | ||
Raises: | ||
HTTPException: If the user is not found in the database | ||
""" | ||
|
||
if not wallet_id: | ||
raise HTTPException(status_code=400, detail="Wallet ID cannot be empty") | ||
|
||
user = UserDBConnector.get_user_by_wallet_id(db, wallet_id) | ||
if not user: | ||
raise HTTPException( | ||
status_code=404, detail="User with the provided wallet_id does not exist" | ||
) | ||
|
||
referral_code = generate_random_string() | ||
return ReferralResponse(wallet_id=wallet_id, referral_code=referral_code) | ||
|
||
|
||
app.include_router(router) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
""" | ||
Unit tests for the FastAPI referral link creation endpoint. | ||
Tests include: | ||
- Successful creation of a referral link with a valid wallet ID. | ||
- Missing wallet ID in the request. | ||
- User not found in the database. | ||
Uses pytest, unittest.mock for mocking, and FastAPI's TestClient for testing the API. | ||
""" | ||
|
||
import pytest | ||
from fastapi.testclient import TestClient | ||
|
||
from web_app.db.crud import UserDBConnector | ||
from web_app.api.referal import app | ||
|
||
|
||
@pytest.fixture | ||
def client(): | ||
""" | ||
Returns a TestClient for the FastAPI app. | ||
""" | ||
return TestClient(app) | ||
|
||
|
||
@pytest.fixture | ||
def mock_get_user_by_wallet_id(mocker): | ||
""" | ||
Mocks the UserDBConnector's method for fetching a user by wallet_id. | ||
""" | ||
return mocker.patch.object(UserDBConnector, "get_user_by_wallet_id") | ||
|
||
|
||
def test_create_referral_link_for_existing_user(client, mock_get_user_by_wallet_id): | ||
"""Positive Test Case: Test referral link creation for an existing user""" | ||
mock_get_user_by_wallet_id.return_value = {"wallet_id": "valid_wallet_id"} | ||
response = client.get("/api/create_referal_link?wallet_id=valid_wallet_id") | ||
|
||
assert response.status_code == 200 | ||
assert "wallet_id" in response.json() | ||
assert "referral_code" in response.json() | ||
assert len(response.json()["referral_code"]) == 16 | ||
|
||
|
||
def test_create_referral_link_for_non_existent_user(client, mock_get_user_by_wallet_id): | ||
"""Negative Test Case: Test referral link creation for a non-existent user""" | ||
mock_get_user_by_wallet_id.return_value = None | ||
response = client.get("/api/create_referal_link?wallet_id=non_existent_wallet_id") | ||
|
||
assert response.status_code == 404 | ||
assert response.json() == { | ||
"detail": "User with the provided wallet_id does not exist" | ||
} | ||
|
||
|
||
def test_create_referral_link_with_empty_wallet_id(client): | ||
"""Negative Test Case: Test referral link creation with an empty wallet ID""" | ||
response = client.get("/api/create_referal_link?wallet_id=") | ||
|
||
assert response.status_code == 400 | ||
assert response.json() == {"detail": "Wallet ID cannot be empty"} | ||
|
||
|
||
def test_create_referral_link_with_malformed_wallet_id( | ||
client, mock_get_user_by_wallet_id | ||
): | ||
"""Test referral link creation with malformed wallet ID""" | ||
mock_get_user_by_wallet_id.return_value = None | ||
response = client.get("/api/create_referal_link?wallet_id=@@!invalidwallet") | ||
|
||
assert response.status_code == 404 | ||
assert response.json() == { | ||
"detail": "User with the provided wallet_id does not exist" | ||
} | ||
|
||
|
||
def test_create_referral_link_for_multiple_users(client, mock_get_user_by_wallet_id): | ||
"""Test referral link creation with a random referral code for multiple users""" | ||
mock_get_user_by_wallet_id.return_value = {"wallet_id": "valid_wallet_id"} | ||
response1 = client.get("/api/create_referal_link?wallet_id=valid_wallet_id") | ||
referral_code1 = response1.json()["referral_code"] | ||
response2 = client.get("/api/create_referal_link?wallet_id=valid_wallet_id") | ||
referral_code2 = response2.json()["referral_code"] | ||
|
||
assert response1.status_code == 200 | ||
assert response2.status_code == 200 | ||
assert referral_code1 != referral_code2 | ||
|
||
|