-
Notifications
You must be signed in to change notification settings - Fork 213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add Pagination Support to GET /api/v1/activity-log Endpoint #1197 #1223
Open
Dafinci01
wants to merge
15
commits into
hngprojects:dev
Choose a base branch
from
Dafinci01:dev
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
42d1155
Merge pull request #983 from hngprojects/dev
Homoakin619 7edb452
Merge pull request #984 from hngprojects/dev
Homoakin619 85ca844
postgre database fixed
13f72fa
activty-log pagination succesfully added
32054f8
Merge branch 'main' into dev
c0c96d2
Merge branch 'activity-log-pagination' into dev
fba6641
fixed: README.md api/v1/services/activity_logs.py
3f10de4
Updated .gitignore to ignore environment files
81df0ec
Restored environment files
092804f
Updated ignored files and pushed changes
9f8ec56
Revert incorrect change to Alembic migration command in README
e82d3e6
Restore .env.sample
2d125b6
feat: get and fetch activty log added
dff8690
pagination endpoint tested
f2f8f67
feat: Pagination seervice layer added
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
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
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
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
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,126 @@ | ||
import pytest | ||
from fastapi.testclient import TestClient | ||
from unittest.mock import patch, MagicMock | ||
from main import app # Assuming your main app file is main.py | ||
from api.v1.models.user import User | ||
from api.v1.services.user import user_service | ||
from api.v1.models.activity_logs import ActivityLog # Ensure you import your ActivityLog MODEL, not schema | ||
from uuid_extensions import uuid7 | ||
from api.db.database import get_db | ||
from fastapi import status | ||
from datetime import datetime, timezone, timedelta | ||
from typing import List | ||
|
||
|
||
@pytest.mark.usefixtures("mock_db_session", "mock_user_service") | ||
def test_get_all_activity_logs_default_pagination(mock_user_service, mock_db_session): | ||
"""Test default pagination (no page/limit params).""" | ||
mock_user = create_mock_user(mock_user_service, mock_db_session) | ||
access_token = user_service.create_access_token(user_id=str(uuid7())) | ||
|
||
# Mock 12 activity logs to test default limit of 10 | ||
mock_logs = [ | ||
create_mock_activity_log(str(uuid7()), str(uuid7()), f"action_{i}", datetime.now(timezone.utc)) | ||
for i in range(12) | ||
] | ||
mock_db_session.query.return_value.order_by.return_value.offset.return_value.limit.return_value.all.return_value = mock_logs[:10] # Mock first 10 for page 1 | ||
|
||
response = client.get(ACTIVITY_LOGS_ENDPOINT, headers={'Authorization': f'Bearer {access_token}'}) | ||
|
||
assert response.status_code == status.HTTP_200_OK | ||
response_data = response.json() | ||
assert isinstance(response_data, list) | ||
assert len(response_data) == 10 # Verify default limit is 10 | ||
|
||
|
||
@pytest.mark.usefixtures("mock_db_session", "mock_user_service") | ||
def test_get_all_activity_logs_limit_5(mock_user_service, mock_db_session): | ||
"""Test setting limit to 5.""" | ||
mock_user = create_mock_user(mock_user_service, mock_db_session) | ||
access_token = user_service.create_access_token(user_id=str(uuid7())) | ||
|
||
mock_logs = [ | ||
create_mock_activity_log(str(uuid7()), str(uuid7()), f"action_{i}", datetime.now(timezone.utc)) | ||
for i in range(7) # Mock 7 logs, limit should return max 5 | ||
] | ||
mock_db_session.query.return_value.order_by.return_value.offset.return_value.limit.return_value.all.return_value = mock_logs[:5] # Mock first 5 for limit 5 | ||
|
||
|
||
response = client.get(ACTIVITY_LOGS_ENDPOINT, headers={'Authorization': f'Bearer {access_token}'}, params={'limit': 5}) | ||
|
||
assert response.status_code == status.HTTP_200_OK | ||
response_data = response.json() | ||
assert isinstance(response_data, list) | ||
assert len(response_data) == 5 # Verify limit is respected | ||
|
||
|
||
@pytest.mark.usefixtures("mock_db_session", "mock_user_service") | ||
def test_get_all_activity_logs_page_2_limit_5(mock_user_service, mock_db_session): | ||
"""Test getting page 2 with limit 5.""" | ||
mock_user = create_mock_user(mock_user_service, mock_db_session) | ||
access_token = user_service.create_access_token(user_id=str(uuid7())) | ||
|
||
mock_logs = [ | ||
create_mock_activity_log(str(uuid7()), str(uuid7()), f"action_{i}", datetime.now(timezone.utc)) | ||
for i in range(12) # Mock 12 logs | ||
] | ||
mock_db_session.query.return_value.order_by.return_value.offset.return_value.limit.return_value.all.side_effect = [ # Use side_effect to return different data for each page request | ||
mock_logs[:5], # Page 1 (items 0-4) | ||
mock_logs[5:10], # Page 2 (items 5-9) | ||
[] # Page 3 and beyond (empty list) | ||
] | ||
|
||
response_page1 = client.get(ACTIVITY_LOGS_ENDPOINT, headers={'Authorization': f'Bearer {access_token}'}, params={'page': 1, 'limit': 5}) | ||
response_page2 = client.get(ACTIVITY_LOGS_ENDPOINT, headers={'Authorization': f'Bearer {access_token}'}, params={'page': 2, 'limit': 5}) | ||
response_page3 = client.get(ACTIVITY_LOGS_ENDPOINT, headers={'Authorization': f'Bearer {access_token}'}, params={'page': 3, 'limit': 5}) | ||
|
||
|
||
assert response_page1.status_code == status.HTTP_200_OK | ||
assert len(response_page1.json()) == 5 | ||
assert response_page2.status_code == status.HTTP_200_OK | ||
assert len(response_page2.json()) == 5 | ||
assert response_page3.status_code == status.HTTP_200_OK | ||
assert len(response_page3.json()) == 0 # Page 3 should be empty | ||
|
||
|
||
# Add more pagination test cases here, like testing page beyond last page, etc. | ||
|
||
|
||
@pytest.mark.usefixtures("mock_db_session", "mock_user_service") | ||
def test_get_all_activity_logs_empty(mock_user_service, mock_db_session): | ||
"""Test for fetching all activity logs with no data.""" | ||
mock_user = create_mock_user(mock_user_service, mock_db_session) | ||
access_token = user_service.create_access_token(user_id=str(uuid7())) | ||
mock_db_session.query.return_value.order_by.return_value.offset.return_value.limit.return_value.all.return_value = [] # Mock empty list for no data | ||
response = client.get(ACTIVITY_LOGS_ENDPOINT, headers={'Authorization': f'Bearer {access_token}'}) | ||
|
||
assert response.status_code == status.HTTP_200_OK | ||
assert response.json() == [] # Verify empty list when no data | ||
|
||
|
||
@pytest.mark.usefixtures("mock_db_session", "mock_user_service") | ||
def test_get_all_activity_logs_with_data(mock_user_service, mock_db_session): | ||
"""Test for fetching all activity logs with data.""" | ||
mock_user = create_mock_user(mock_user_service, mock_db_session) | ||
access_token = user_service.create_access_token(user_id=str(uuid7())) | ||
|
||
mock_logs = [create_mock_activity_log(str(uuid7()), str(uuid7()), "profile Update", datetime.now(timezone.utc))] | ||
mock_db_session.query.return_value.order_by.return_value.offset.return_value.limit.return_value.all.return_value = mock_logs # Mock a single log | ||
|
||
response = client.get(ACTIVITY_LOGS_ENDPOINT, headers={'Authorization': f'Bearer {access_token}'}) | ||
|
||
assert response.status_code == status.HTTP_200_OK | ||
response_data = response.json() | ||
assert isinstance(response_data, list) | ||
assert len(response_data) == 1 # Verify one log returned | ||
|
||
|
||
@pytest.mark.usefixtures("mock_db_session", "mock_user_service") | ||
def test_get_all_activity_logs_non_super_admin(mock_user_service, mock_db_session): | ||
"""Test for fetching all activity logs as a non-super admin user.""" | ||
mock_user = create_mock_user( | ||
mock_user_service, mock_db_session, is_superadmin=False) | ||
access_token = user_service.create_access_token(user_id=str(uuid7())) | ||
response = client.get(ACTIVITY_LOGS_ENDPOINT, headers={'Authorization': f'Bearer {access_token}'}) | ||
|
||
assert response.status_code |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just passing the page and page limits doesn't mean it's reflected in the implementation.