diff --git a/pygeoapi/api/__init__.py b/pygeoapi/api/__init__.py index 99818996e..9116737a4 100644 --- a/pygeoapi/api/__init__.py +++ b/pygeoapi/api/__init__.py @@ -8,7 +8,7 @@ # Ricardo Garcia Silva # # Copyright (c) 2026 Tom Kralidis -# Copyright (c) 2025 Francesco Bartoli +# Copyright (c) 2026 Francesco Bartoli # Copyright (c) 2022 John A Stevenson and Colin Blackburn # Copyright (c) 2023 Ricardo Garcia Silva # @@ -886,7 +886,7 @@ def conformance(api: API, request: APIRequest) -> Tuple[dict, int, str]: apis_dict = all_apis() - conformance_list = CONFORMANCE_CLASSES + conformance_list = list(CONFORMANCE_CLASSES) for key, value in api.config['resources'].items(): if value['type'] == 'process': diff --git a/tests/api/test_api.py b/tests/api/test_api.py index 0f8e785c1..816fe8178 100644 --- a/tests/api/test_api.py +++ b/tests/api/test_api.py @@ -4,9 +4,11 @@ # John A Stevenson # Colin Blackburn # Bernhard Mallinger +# Francesco Bartoli # # Copyright (c) 2024 Tom Kralidis # Copyright (c) 2022 John A Stevenson and Colin Blackburn +# Copyright (c) 2026 Francesco Bartoli # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation @@ -39,10 +41,10 @@ import pytest from pygeoapi.api import ( - API, APIRequest, FORMAT_TYPES, F_HTML, F_JSON, F_JSONLD, F_GZIP, - __version__, validate_bbox, validate_datetime, evaluate_limit, - validate_subset, landing_page, openapi_, conformance, describe_collections, - get_collection_schema, + API, APIRequest, CONFORMANCE_CLASSES, FORMAT_TYPES, F_HTML, F_JSON, + F_JSONLD, F_GZIP, __version__, validate_bbox, validate_datetime, + evaluate_limit, validate_subset, landing_page, openapi_, conformance, + describe_collections, get_collection_schema, ) from pygeoapi.util import yaml_load, get_api_rules, get_base_url @@ -567,6 +569,37 @@ def test_conformance(config, api_): assert rsp_headers['Content-Language'] == 'en-US' +def test_conformance_does_not_mutate_global_list(config, api_): + """Test conformance method does not mutate CONFORMANCE_CLASSES. + + This test verifies that the global CONFORMANCE_CLASSES list is not + mutated by calls to the conformance function. The base conformance + classes should remain unchanged after multiple calls. + """ + + # Store the original length and content of the global list + original_length = len(CONFORMANCE_CLASSES) + original_classes = list(CONFORMANCE_CLASSES) + + req = mock_api_request() + + # Make multiple calls to conformance + for _ in range(3): + conformance(api_, req) + + # The global list should NOT have been mutated + assert len(CONFORMANCE_CLASSES) == original_length, ( + f'Global CONFORMANCE_CLASSES was mutated! ' + f'Original length: {original_length}, ' + f'Current length: {len(CONFORMANCE_CLASSES)}. ' + f'The conformance() function should create a copy of the list ' + f'before extending it.' + ) + assert CONFORMANCE_CLASSES == original_classes, ( + 'Global CONFORMANCE_CLASSES content was modified' + ) + + def test_describe_collections(config, api_): req = mock_api_request({"f": "html"}) rsp_headers, code, response = describe_collections(api_, req)