From 2761b0901a59a0129c8f808f5a5ed74313e47f38 Mon Sep 17 00:00:00 2001 From: utibe solomon Date: Tue, 13 Aug 2024 20:25:31 +0100 Subject: [PATCH 1/6] feat : Added get all Invitations endpoint --- api/v1/routes/organisation.py | 15 ++++++- api/v1/services/invite.py | 7 ++-- .../v1/invitation/test_get_all_invitations.py | 42 +++++++++++++++++++ 3 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 tests/v1/invitation/test_get_all_invitations.py diff --git a/api/v1/routes/organisation.py b/api/v1/routes/organisation.py index ec66b3939..842a241ac 100644 --- a/api/v1/routes/organisation.py +++ b/api/v1/routes/organisation.py @@ -3,7 +3,7 @@ from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from sqlalchemy.orm import Session - +from api.v1.services import invite from api.utils.success_response import success_response from api.v1.models.user import User from api.v1.schemas.organisation import ( @@ -127,3 +127,16 @@ async def delete_organisation( status_code=status.HTTP_200_OK, message="Organisation with ID {org_id} deleted successfully", ) + +@organisation.get("/invites", status_code=200) +def get_organization_invites( + db : Session = Depends(get_db), + current_user : User = Depends(user_service.get_current_super_admin), +) : + invitations = invite.InviteService.fetch_all(db) + + return success_response( + status_code=status.HTTP_200_OK, + message='Invites fetched succesfully', + data=[jsonable_encoder(invitation) for invitation in invitations] + ) diff --git a/api/v1/services/invite.py b/api/v1/services/invite.py index b78546f45..f50407619 100644 --- a/api/v1/services/invite.py +++ b/api/v1/services/invite.py @@ -212,9 +212,10 @@ def delete_all(session: Session): def fetch(self): pass - def fetch_all(self): - pass - + @staticmethod + def fetch_all(session : Session): + all_invites = session.query(Invitation).all() + return all_invites def update(self): pass diff --git a/tests/v1/invitation/test_get_all_invitations.py b/tests/v1/invitation/test_get_all_invitations.py new file mode 100644 index 000000000..4dfbb0592 --- /dev/null +++ b/tests/v1/invitation/test_get_all_invitations.py @@ -0,0 +1,42 @@ +from unittest.mock import patch, MagicMock +import pytest +from fastapi.testclient import TestClient +from datetime import datetime, timedelta, timezone +from uuid_extensions import uuid7 +from api.v1.models.invitation import Invitation +from api.v1.services.user import user_service, UserService +from main import app +from api.db.database import get_db +from api.v1.models.user import User + +client = TestClient(app) +@pytest.fixture +def mock_db_session(): + with patch("api.db.database.get_db", autospec=True) as mock_get_db: + mock_db = MagicMock() + app.dependency_overrides[get_db] = lambda: mock_db + yield mock_db + app.dependency_overrides = {} + +def test_get_all_invitations(mock_db_session): + + invitations = [Invitation(user_id=str(uuid7()), is_valid = True , organisation_id = str(uuid7()), id=str(uuid7()))] + + mock_db_session.query().all.return_value = invitations + + app.dependency_overrides[user_service.get_current_super_admin] = lambda : User( + id=str(uuid7()), + email="testuser@gmail.com", + password="hashed_password", + first_name='Test', + last_name='User', + is_active=True, + created_at=datetime.now(timezone.utc), + updated_at=datetime.now(timezone.utc), + is_superadmin = True + ) + + res = client.get('/api/v1/organisations/invites') + + assert res.status_code == 200 + From 4c31090912b5655cf458a356e16dcb106886d561 Mon Sep 17 00:00:00 2001 From: utibe solomon Date: Tue, 13 Aug 2024 20:32:54 +0100 Subject: [PATCH 2/6] feat : Added get all invitations endpoint --- tests/v1/invitation/test_get_all_invitations.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/v1/invitation/test_get_all_invitations.py b/tests/v1/invitation/test_get_all_invitations.py index 4dfbb0592..bdbd7111a 100644 --- a/tests/v1/invitation/test_get_all_invitations.py +++ b/tests/v1/invitation/test_get_all_invitations.py @@ -36,7 +36,7 @@ def test_get_all_invitations(mock_db_session): is_superadmin = True ) - res = client.get('/api/v1/organisations/invites') + response = client.get('/api/v1/organisations/invites') - assert res.status_code == 200 + assert response.status_code == 200 From c92e55c3ad537e8845db501cabda360acb6915af Mon Sep 17 00:00:00 2001 From: utibe solomon Date: Wed, 14 Aug 2024 01:22:55 +0100 Subject: [PATCH 3/6] Feat added invitations endpoint --- api/v1/routes/organisation.py | 3 ++- api/v1/services/invite.py | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/api/v1/routes/organisation.py b/api/v1/routes/organisation.py index 842a241ac..c0568908a 100644 --- a/api/v1/routes/organisation.py +++ b/api/v1/routes/organisation.py @@ -134,9 +134,10 @@ def get_organization_invites( current_user : User = Depends(user_service.get_current_super_admin), ) : invitations = invite.InviteService.fetch_all(db) + return success_response( status_code=status.HTTP_200_OK, message='Invites fetched succesfully', - data=[jsonable_encoder(invitation) for invitation in invitations] + data=[jsonable_encoder(invitation, exclude=['user_id','organisation_id']) for invitation in invitations] ) diff --git a/api/v1/services/invite.py b/api/v1/services/invite.py index f50407619..bb445b9bb 100644 --- a/api/v1/services/invite.py +++ b/api/v1/services/invite.py @@ -1,7 +1,7 @@ import logging from datetime import datetime, timedelta from pytz import utc -from sqlalchemy.orm import Session +from sqlalchemy.orm import Session,joinedload from sqlalchemy import insert from fastapi import HTTPException, Request, Depends, status from collections import OrderedDict @@ -9,6 +9,7 @@ from api.v1.models.invitation import Invitation from api.v1.models.organisation import Organisation from api.v1.models.user import User +from api.v1.services.user import user_service from sqlalchemy.exc import IntegrityError from api.v1.models.permissions.role import Role from api.v1.schemas.permissions.roles import RoleCreate @@ -214,7 +215,10 @@ def fetch(self): @staticmethod def fetch_all(session : Session): - all_invites = session.query(Invitation).all() + all_invites = session.query(Invitation).options(joinedload(Invitation.organisation)).all() + for invite in all_invites : + user = user_service.get_user_by_id(db=session , id=invite.user_id) + invite.email = user.email return all_invites def update(self): pass From fcf1acbf4a196f28fdd1e58343fcf2e1e66ee6ec Mon Sep 17 00:00:00 2001 From: utibe solomon Date: Thu, 15 Aug 2024 03:50:18 +0100 Subject: [PATCH 4/6] fix worked on product feature endpoint --- api/v1/routes/product.py | 23 +---------------------- api/v1/services/product.py | 4 ++++ 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/api/v1/routes/product.py b/api/v1/routes/product.py index cde3239a8..fe8c2a941 100644 --- a/api/v1/routes/product.py +++ b/api/v1/routes/product.py @@ -265,31 +265,10 @@ def get_organisation_products( db, user=current_user, org_id=org_id, limit=limit, page=page ) - total_products = len(products) - - total_pages = int(total_products / limit) + (total_products % limit > 0) - - product_data = [ - { - "name": product.name, - "description": product.description, - "price": str(product.price), - } - for product in products - ] - - data = { - "current_page": page, - "total_pages": total_pages, - "limit": limit, - "total_items": total_products, - "products": product_data, - } - return success_response( status_code=200, message="Successfully fetched organisations products", - data=data, + data=[jsonable_encoder(product) for product in products], ) diff --git a/api/v1/services/product.py b/api/v1/services/product.py index a52ea6a4f..60c93a63b 100644 --- a/api/v1/services/product.py +++ b/api/v1/services/product.py @@ -252,6 +252,10 @@ def fetch_all(db: Session, **query_params: Optional[Any]): ) return query.all() + + + + product_service = ProductService() From 568546a776799644ad73df554c092632c8b330bb Mon Sep 17 00:00:00 2001 From: utibe solomon Date: Thu, 15 Aug 2024 03:59:17 +0100 Subject: [PATCH 5/6] fix products endpoint --- api/v1/routes/organisation.py | 16 +------ api/v1/services/invite.py | 9 +--- .../v1/invitation/test_get_all_invitations.py | 42 ------------------- 3 files changed, 3 insertions(+), 64 deletions(-) delete mode 100644 tests/v1/invitation/test_get_all_invitations.py diff --git a/api/v1/routes/organisation.py b/api/v1/routes/organisation.py index c0568908a..d291454fe 100644 --- a/api/v1/routes/organisation.py +++ b/api/v1/routes/organisation.py @@ -126,18 +126,4 @@ async def delete_organisation( return success_response( status_code=status.HTTP_200_OK, message="Organisation with ID {org_id} deleted successfully", - ) - -@organisation.get("/invites", status_code=200) -def get_organization_invites( - db : Session = Depends(get_db), - current_user : User = Depends(user_service.get_current_super_admin), -) : - invitations = invite.InviteService.fetch_all(db) - - - return success_response( - status_code=status.HTTP_200_OK, - message='Invites fetched succesfully', - data=[jsonable_encoder(invitation, exclude=['user_id','organisation_id']) for invitation in invitations] - ) + ) \ No newline at end of file diff --git a/api/v1/services/invite.py b/api/v1/services/invite.py index bb445b9bb..5ee27b507 100644 --- a/api/v1/services/invite.py +++ b/api/v1/services/invite.py @@ -213,13 +213,8 @@ def delete_all(session: Session): def fetch(self): pass - @staticmethod - def fetch_all(session : Session): - all_invites = session.query(Invitation).options(joinedload(Invitation.organisation)).all() - for invite in all_invites : - user = user_service.get_user_by_id(db=session , id=invite.user_id) - invite.email = user.email - return all_invites + def fetch_all(self): + pass def update(self): pass diff --git a/tests/v1/invitation/test_get_all_invitations.py b/tests/v1/invitation/test_get_all_invitations.py deleted file mode 100644 index bdbd7111a..000000000 --- a/tests/v1/invitation/test_get_all_invitations.py +++ /dev/null @@ -1,42 +0,0 @@ -from unittest.mock import patch, MagicMock -import pytest -from fastapi.testclient import TestClient -from datetime import datetime, timedelta, timezone -from uuid_extensions import uuid7 -from api.v1.models.invitation import Invitation -from api.v1.services.user import user_service, UserService -from main import app -from api.db.database import get_db -from api.v1.models.user import User - -client = TestClient(app) -@pytest.fixture -def mock_db_session(): - with patch("api.db.database.get_db", autospec=True) as mock_get_db: - mock_db = MagicMock() - app.dependency_overrides[get_db] = lambda: mock_db - yield mock_db - app.dependency_overrides = {} - -def test_get_all_invitations(mock_db_session): - - invitations = [Invitation(user_id=str(uuid7()), is_valid = True , organisation_id = str(uuid7()), id=str(uuid7()))] - - mock_db_session.query().all.return_value = invitations - - app.dependency_overrides[user_service.get_current_super_admin] = lambda : User( - id=str(uuid7()), - email="testuser@gmail.com", - password="hashed_password", - first_name='Test', - last_name='User', - is_active=True, - created_at=datetime.now(timezone.utc), - updated_at=datetime.now(timezone.utc), - is_superadmin = True - ) - - response = client.get('/api/v1/organisations/invites') - - assert response.status_code == 200 - From e6d302e71061c5c1f93b97a39d27a2385f42bdd5 Mon Sep 17 00:00:00 2001 From: utibe solomon Date: Thu, 15 Aug 2024 04:12:58 +0100 Subject: [PATCH 6/6] fix products endpoint --- api/v1/routes/organisation.py | 1 - api/v1/services/invite.py | 2 +- api/v1/services/product.py | 3 --- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/api/v1/routes/organisation.py b/api/v1/routes/organisation.py index d291454fe..a41d159d8 100644 --- a/api/v1/routes/organisation.py +++ b/api/v1/routes/organisation.py @@ -3,7 +3,6 @@ from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from sqlalchemy.orm import Session -from api.v1.services import invite from api.utils.success_response import success_response from api.v1.models.user import User from api.v1.schemas.organisation import ( diff --git a/api/v1/services/invite.py b/api/v1/services/invite.py index 5ee27b507..45a818de9 100644 --- a/api/v1/services/invite.py +++ b/api/v1/services/invite.py @@ -1,7 +1,7 @@ import logging from datetime import datetime, timedelta from pytz import utc -from sqlalchemy.orm import Session,joinedload +from sqlalchemy.orm import Session from sqlalchemy import insert from fastapi import HTTPException, Request, Depends, status from collections import OrderedDict diff --git a/api/v1/services/product.py b/api/v1/services/product.py index 60c93a63b..61cce2f3a 100644 --- a/api/v1/services/product.py +++ b/api/v1/services/product.py @@ -255,7 +255,4 @@ def fetch_all(db: Session, **query_params: Optional[Any]): - - - product_service = ProductService()