From afc319e66ce4db4a38211c8d0e93c855ecef7b71 Mon Sep 17 00:00:00 2001 From: utibe solomon Date: Sat, 24 Aug 2024 02:31:22 +0100 Subject: [PATCH] feat added get all payments with user_id --- api/v1/routes/payment.py | 39 +++++++++++++-- .../test_get_payments_for_current_user.py | 10 ++-- tests/v1/payment/test_payment.py | 49 +++++++++++++++++-- 3 files changed, 85 insertions(+), 13 deletions(-) diff --git a/api/v1/routes/payment.py b/api/v1/routes/payment.py index ea22ca03c..5a5e1a357 100644 --- a/api/v1/routes/payment.py +++ b/api/v1/routes/payment.py @@ -1,7 +1,7 @@ from fastapi import Depends, APIRouter, status, Query, HTTPException from sqlalchemy.orm import Session from typing import Annotated - +from fastapi.encoders import jsonable_encoder from api.utils.success_response import success_response from api.v1.schemas.payment import PaymentListResponse, PaymentResponse from api.v1.services.payment import PaymentService @@ -9,8 +9,9 @@ from api.db.database import get_db from api.v1.models import User -payment = APIRouter(prefix="/payments", tags=["Payments"]) +payment = APIRouter(prefix="/transactions", tags=["Transactions"]) +payment_service = PaymentService() @payment.get( "/current-user", status_code=status.HTTP_200_OK, response_model=PaymentListResponse @@ -28,7 +29,7 @@ def get_payments_for_current_user( - limit: Number of payment per page (default: 10, minimum: 1) - page: Page number (starts from 1) """ - payment_service = PaymentService() + # FETCH all payments for current user payments = payment_service.fetch_by_user( @@ -78,14 +79,42 @@ def get_payments_for_current_user( data=data, ) +@payment.get("/user/{user_id}", response_model=success_response, status_code=status.HTTP_200_OK) +def get_user_payments_by_id( + user_id : str, + current_user : Annotated[User , Depends(user_service.get_current_user)], + db : Annotated[Session, Depends(get_db)], + page_size: Annotated[int, Query(ge=1, description="Number of payments per page")] = 10, + page_number: Annotated[int, Query(ge=1, description="Page number (starts from 1)")] = 1 + ): + """Functions that handles get all transactions for a user by id with endpoint + + Args: + user_id (str): Identifier of the user + current_user (Annotated[User , Depends): Dependency to get the current User + page_size (Annotated[int, Query, optional): The total amount of instances to be returned per page. Defaults to 1, description="Number of payments per page")]=10. + page_number (Annotated[int, Query, optional): page number to be viewed. Defaults to 1, description="Page number (starts from 1)")]=1. + + + """ + payments = payment_service.fetch_by_user( + db=db, + user_id=user_id, + limit=page_size, + page=page_number + ) + return success_response( + status_code=status.HTTP_200_OK, + message='Payments retrieved', + data=[jsonable_encoder(payment) for payment in payments] + ) + @payment.get("/{payment_id}", response_model=PaymentResponse) async def get_payment(payment_id: str, db: Session = Depends(get_db)): ''' Endpoint to retrieve a payment by its ID. ''' - - payment_service = PaymentService() payment = payment_service.get_payment_by_id(db, payment_id) return payment diff --git a/tests/v1/payment/test_get_payments_for_current_user.py b/tests/v1/payment/test_get_payments_for_current_user.py index f27f8083c..d49716135 100644 --- a/tests/v1/payment/test_get_payments_for_current_user.py +++ b/tests/v1/payment/test_get_payments_for_current_user.py @@ -74,7 +74,7 @@ def test_get_payments_successfully( # Make request params = {'page': 1, 'limit': 10} headers = {'Authorization': f'Bearer {access_token_user}'} - response = client.get("/api/v1/payments/current-user", params=params, headers=headers) + response = client.get("/api/v1/transactions/current-user", params=params, headers=headers) resp_d = response.json() @@ -107,7 +107,7 @@ def test_get_payments_successfully( # Make request, with limit set to 2, to get 3 pages params = {'page': 1, 'limit': 2} headers = {'Authorization': f'Bearer {access_token_user}'} - response = client.get("/api/v1/payments/current-user", params=params, headers=headers) + response = client.get("/api/v1/transactions/current-user", params=params, headers=headers) resp_d = response.json() @@ -139,14 +139,14 @@ def test_for_unauthenticated_get_payments( # Make request || WRONG Authorization headers = {'Authorization': f'Bearer {random_access_token}'} - response = client.get("/api/v1/payments/current-user", params=params, headers=headers) + response = client.get("/api/v1/transactions/current-user", params=params, headers=headers) assert response.status_code == 401 assert response.json()['message'] == "Could not validate credentials" assert not response.json().get('data') # Make request || NO Authorization - response = client.get("/api/v1/payments/current-user", params=params) + response = client.get("/api/v1/transactions/current-user", params=params) assert response.status_code == 401 assert response.json()['message'] == "Not authenticated" @@ -170,7 +170,7 @@ def test_for_no_payments_for_user( # Make request params = {'page': 1, 'limit': 10} headers = {'Authorization': f'Bearer {access_token_user}'} - response = client.get("/api/v1/payments/current-user", params=params, headers=headers) + response = client.get("/api/v1/transactions/current-user", params=params, headers=headers) assert response.status_code == 404 assert response.json()['message'] == "Payments not found for user" diff --git a/tests/v1/payment/test_payment.py b/tests/v1/payment/test_payment.py index 23564badf..a89ada120 100644 --- a/tests/v1/payment/test_payment.py +++ b/tests/v1/payment/test_payment.py @@ -3,10 +3,15 @@ from datetime import datetime from fastapi.testclient import TestClient from main import app +from unittest.mock import MagicMock +from api.v1.services.user import user_service from api.v1.services.payment import PaymentService from api.v1.schemas.payment import PaymentResponse from api.utils.db_validators import check_model_existence - +from api.db.database import get_db +from uuid_extensions import uuid7 +from datetime import timezone +from api.v1.models.user import User client = TestClient(app) mock_payment = { @@ -21,16 +26,54 @@ "updated_at": datetime(2024, 7, 28, 12, 31, 36, 650997) } +@pytest.fixture +def db_session_mock(): + db = MagicMock() + yield db + +@pytest.fixture(autouse=True) +def override_get_db(db_session_mock): + def get_db_override(): + yield db_session_mock + + app.dependency_overrides[get_db] = get_db_override + yield + # Clean up after the test by removing the override + app.dependency_overrides = {} + + +mock_user = User( + id=str(uuid7()), + email="dummyuser1@gmail.com", + password=user_service.hash_password("Testpassword@123"), + first_name="Mr", + last_name="Dummy", + is_active=True, + is_superadmin=False, + created_at=datetime.now(timezone.utc), + updated_at=datetime.now(timezone.utc), + ) + + def test_get_payment(mocker): mocker.patch.object(PaymentService, 'get_payment_by_id', return_value=mock_payment) - response = client.get(f"/api/v1/payments/{mock_payment['id']}") + response = client.get(f"/api/v1/transactions/{mock_payment['id']}") assert response.status_code == 200 # assert response.json() == PaymentResponse(**mock_payment).model_dump() def test_get_payment_not_found(mocker): mocker.patch.object(PaymentService, 'get_payment_by_id', side_effect=HTTPException(status_code=404, detail='Payment does not exist')) - response = client.get("/api/v1/payments/non_existent_id") + response = client.get("/api/v1/transactions/non_existent_id") assert response.status_code == 404 +def test_get_payments_by_user_id(db_session_mock): + app.dependency_overrides[user_service.get_current_user] = lambda : mock_user + db_session_mock.get.return_value = mock_user + db_session_mock.query().all.return_value = [mock_payment] + response = client.get(f'/api/v1/transactions/user/{mock_user.id}') + assert response.status_code == 200 + + +