Skip to content

Commit

Permalink
Merge pull request #517 from KindaMAD-hav/feat/referal_endpoint
Browse files Browse the repository at this point in the history
Feat/referal endpoint
  • Loading branch information
djeck1432 authored Jan 29, 2025
2 parents 8bf97f7 + cb897ac commit 610b2c0
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 0 deletions.
88 changes: 88 additions & 0 deletions web_app/api/referal.py
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)
90 changes: 90 additions & 0 deletions web_app/tests/test_create_referal_link.py
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


0 comments on commit 610b2c0

Please sign in to comment.