diff --git a/src/fidesops/api/v1/endpoints/connection_endpoints.py b/src/fidesops/api/v1/endpoints/connection_endpoints.py index 840a02257..6b73785d6 100644 --- a/src/fidesops/api/v1/endpoints/connection_endpoints.py +++ b/src/fidesops/api/v1/endpoints/connection_endpoints.py @@ -82,7 +82,10 @@ def get_connections( logger.info( f"Finding all connection configurations with pagination params {params}" ) - return paginate(ConnectionConfig.query(db), params=params) + return paginate( + ConnectionConfig.query(db).order_by(ConnectionConfig.created_at.desc()), + params=params, + ) @router.get( diff --git a/src/fidesops/api/v1/endpoints/dataset_endpoints.py b/src/fidesops/api/v1/endpoints/dataset_endpoints.py index 1103bf7e8..f6d92f8db 100644 --- a/src/fidesops/api/v1/endpoints/dataset_endpoints.py +++ b/src/fidesops/api/v1/endpoints/dataset_endpoints.py @@ -239,7 +239,7 @@ def get_datasets( ) dataset_configs = DatasetConfig.filter( db=db, conditions=(DatasetConfig.connection_config_id == connection_config.id) - ) + ).order_by(DatasetConfig.created_at.desc()) # Generate the paginated results, but don't return them as-is. Instead, # modify the items array to be just the FidesopsDataset instead of the full diff --git a/src/fidesops/api/v1/endpoints/policy_endpoints.py b/src/fidesops/api/v1/endpoints/policy_endpoints.py index 7cd33c8d7..10480409b 100644 --- a/src/fidesops/api/v1/endpoints/policy_endpoints.py +++ b/src/fidesops/api/v1/endpoints/policy_endpoints.py @@ -59,7 +59,7 @@ def get_policy_list( Return a paginated list of all Policy records in this system """ logger.info(f"Finding all policies with pagination params '{params}'") - policies = Policy.query(db=db) + policies = Policy.query(db=db).order_by(Policy.created_at.desc()) return paginate(policies, params=params) diff --git a/src/fidesops/api/v1/endpoints/storage_endpoints.py b/src/fidesops/api/v1/endpoints/storage_endpoints.py index f8a0dce69..ee6f938d9 100644 --- a/src/fidesops/api/v1/endpoints/storage_endpoints.py +++ b/src/fidesops/api/v1/endpoints/storage_endpoints.py @@ -233,7 +233,9 @@ def get_configs( Retrieves configs for storage. """ logger.info(f"Finding all storage configurations with pagination params {params}") - return paginate(StorageConfig.query(db), params=params) + return paginate( + StorageConfig.query(db).order_by(StorageConfig.created_at.desc()), params=params + ) @router.get( diff --git a/tests/api/v1/endpoints/test_policy_endpoints.py b/tests/api/v1/endpoints/test_policy_endpoints.py index 632e3bebe..d26c58e05 100644 --- a/tests/api/v1/endpoints/test_policy_endpoints.py +++ b/tests/api/v1/endpoints/test_policy_endpoints.py @@ -1,4 +1,5 @@ import json +from uuid import uuid4 import pytest from starlette.testclient import TestClient @@ -23,6 +24,7 @@ from fidesops.service.masking.strategy.masking_strategy_nullify import NULL_REWRITE from fidesops.util.data_category import DataCategory, generate_fides_data_categories + class TestGetPolicies: @pytest.fixture(scope="function") def url(self, oauth_client) -> str: @@ -66,6 +68,48 @@ def test_get_policies_with_rules( assert rule["action_type"] == "access" assert rule["storage_destination"]["type"] == "s3" + def test_pagination_ordering( + self, + db, + oauth_client, + api_client: TestClient, + generate_auth_header, + url, + ): + auth_header = generate_auth_header(scopes=[scopes.POLICY_READ]) + policies = [] + POLICY_COUNT = 50 + for _ in range(POLICY_COUNT): + key = str(uuid4()).replace("-", "") + policies.append( + Policy.create( + db=db, + data={ + "name": key, + "key": key, + "client_id": oauth_client.id, + }, + ) + ) + + resp = api_client.get( + url, + headers=auth_header, + ) + assert resp.status_code == 200 + data = resp.json() + + assert "items" in data + assert data["total"] == POLICY_COUNT + + for policy in data["items"]: + # The most recent policy will be that which was last added to `policies` + most_recent = policies.pop() + assert policy["key"] == most_recent.key + # Once we're finished we need to delete the policies, since `oauth_client` will be + # subsequently deleted and will cause validation errors + most_recent.delete(db=db) + class TestGetPolicyDetail: @pytest.fixture(scope="function")