diff --git a/test_tools/process.py b/test_tools/process.py index 60981ba12..ea87c0e91 100644 --- a/test_tools/process.py +++ b/test_tools/process.py @@ -69,6 +69,7 @@ def oauth2_provider_mock(): 'dynamic_test_workspace_geoserver_proxy_user_2': None, 'dynamic_test_layer_patch_without_data_user': None, 'test_fix_issuer_id_user': None, + 'layer_map_relation_user': None, }, }, 'host': '0.0.0.0', diff --git a/tests/asserts/final/publication/metadata.py b/tests/asserts/final/publication/metadata.py index d8f9219d7..622b1f0b1 100644 --- a/tests/asserts/final/publication/metadata.py +++ b/tests/asserts/final/publication/metadata.py @@ -53,14 +53,16 @@ def expected_values_in_micka_metadata(workspace, publ_type, name, expected_value ) -def correct_values_in_metadata(workspace, publ_type, name, http_method, *, exp_values=None): +def correct_values_in_metadata(workspace, publ_type, name, http_method, *, exp_values=None, actor_name=None): exp_values = exp_values or {} + actor_name = actor_name or settings.ANONYM_USER md_props = { process_client.LAYER_TYPE: LAYER_METADATA_PROPERTIES, process_client.MAP_TYPE: MAP_METADATA_PROPERTIES, }[publ_type] with app.app_context(): - resp_json = process_client.get_workspace_publication_metadata_comparison(publ_type, workspace, name,) + resp_json = process_client.get_workspace_publication_metadata_comparison(publ_type, workspace, name, + actor_name=actor_name) assert md_props.issubset(set(resp_json['metadata_properties'].keys())) for key, value in resp_json['metadata_properties'].items(): assert value['equal_or_null'] is True, f'key={key}, value={value}' @@ -68,7 +70,7 @@ def correct_values_in_metadata(workspace, publ_type, name, http_method, *, exp_v get_template_path_and_values_method, args = { process_client.LAYER_TYPE: (layer_csw_util.get_template_path_and_values, {}), - process_client.MAP_TYPE: (map_csw_util.get_template_path_and_values, {'actor_name': settings.ANONYM_USER}), + process_client.MAP_TYPE: (map_csw_util.get_template_path_and_values, {'actor_name': actor_name}), }[publ_type] with app.app_context(): _, md_values = get_template_path_and_values_method(workspace, name, http_method=http_method, **args) diff --git a/tests/dynamic_data/publications/map_layer_relation/internal_hranice_private.json b/tests/dynamic_data/publications/map_layer_relation/internal_hranice_private.json new file mode 100644 index 000000000..40ccf41c4 --- /dev/null +++ b/tests/dynamic_data/publications/map_layer_relation/internal_hranice_private.json @@ -0,0 +1,57 @@ +{ + "describedBy": "https://raw.githubusercontent.com/hslayers/map-compositions/2.0.0/schema.json", + "schema_version": "2.0.0", + "abstract": "World places and boundaries abstract", + "title": "World places and boundaries", + "extent": [ + -35.0, + -48.5, + 179, + 81.5 + ], + "nativeExtent": [ + -3896182.18, + -6190443.81, + 19926188.85, + 16579785.82 + ], + "projection": "epsg:3857", + "layers": [ + { + "metadata": {}, + "visibility": true, + "opacity": 1, + "title": "Defini\u010dn\u00ed body administrativn\u00edch celk\u016f", + "className": "HSLayers.Layer.WMS", + "singleTile": true, + "wmsMaxScale": 0, + "legends": [ + "https%3A%2F%2Fgeoportal.kraj-lbc.cz%2Fcgi-bin%2Fmapserv%3Fmap%3D%2Fdata%2Fgis%2FMapServer%2Fprojects%2Fwms%2Fatlas%2Fadministrativni_cleneni.map%26version%3D1.3.0%26service%3DWMS%26request%3DGetLegendGraphic%26sld_version%3D1.1.0%26layer%3Ddefinicni_body_administrativnich_celku%26format%3Dimage%2Fpng%26STYLE%3Ddefault" + ], + "maxResolution": null, + "minResolution": 0, + "url": "https%3A%2F%2Fgeoportal.kraj-lbc.cz%2Fcgi-bin%2Fmapserv%3Fmap%3D%2Fdata%2Fgis%2FMapServer%2Fprojects%2Fwms%2Fatlas%2Fadministrativni_cleneni.map%26", + "params": { + "LAYERS": "definicni_body_administrativnich_celku", + "INFO_FORMAT": "application\/vnd.ogc.gml", + "FORMAT": "image\/png", + "FROMCRS": "EPSG:3857", + "VERSION": "1.3.0" + }, + "dimensions": {} + }, + { + "metadata": {}, + "visibility": true, + "opacity": 1, + "title": "Hranice", + "className": "HSLayers.Layer.WMS", + "singleTile": true, + "url": "http://localhost:8000/geoserver/layer_map_relation_user_wms/ows", + "params": { + "LAYERS": "hranice_private", + "FORMAT": "image\/png" + } + } + ] +} diff --git a/tests/dynamic_data/publications/map_layer_relation/map_layer_relation.py b/tests/dynamic_data/publications/map_layer_relation/map_layer_relation.py index f7735264f..59964b39b 100644 --- a/tests/dynamic_data/publications/map_layer_relation/map_layer_relation.py +++ b/tests/dynamic_data/publications/map_layer_relation/map_layer_relation.py @@ -1,6 +1,8 @@ import os +import pytest + from layman import app -from layman.common import REQUEST_METHOD_POST +from layman.common import REQUEST_METHOD_POST, REQUEST_METHOD_PATCH from layman.util import get_publication_info from test_tools import process_client from tests import EnumTestTypes, Publication @@ -14,8 +16,10 @@ DIRECTORY = os.path.dirname(os.path.abspath(__file__)) WORKSPACE = 'layer_map_relation_workspace' +PRIVATE_WORKSPACE = 'layer_map_relation_user' LAYER_HRANICE = Publication(WORKSPACE, process_client.LAYER_TYPE, 'hranice') +LAYER_HRANICE_PRIVATE = Publication(PRIVATE_WORKSPACE, process_client.LAYER_TYPE, 'hranice_private') LAYER_MISTA_NON_EXISTENT = Publication(WORKSPACE, process_client.LAYER_TYPE, 'mista') MAP_HRANICE = Publication(WORKSPACE, process_client.MAP_TYPE, 'map_hranice') MAP_HRANICE_OPERATES_ON = [LAYER_HRANICE] @@ -60,15 +64,35 @@ 'operates_on': None, }, }, + 'patch_map_with_unauthorized_layer': { + 'post_before_test_args': { + 'file_paths': [os.path.join(DIRECTORY, 'internal_hranice_private.json')], + }, + 'exp_before_rest_method': { + 'map_layers': [(LAYER_HRANICE_PRIVATE, 1, True)], + 'operates_on': [], + }, + 'rest_method': base_test_classes.RestMethodAll.PATCH, + 'rest_args': { + 'actor_name': PRIVATE_WORKSPACE, + }, + 'exp_after_rest_method': { + 'map_layers': [(LAYER_HRANICE_PRIVATE, 1, True)], + 'operates_on': [LAYER_HRANICE_PRIVATE], + }, + }, } +@pytest.mark.usefixtures('oauth2_provider_mock') class TestPublication(base_test.TestSingleRestPublication): workspace = WORKSPACE publication_type = process_client.MAP_TYPE rest_parametrization = [] + usernames_to_reserve = [PRIVATE_WORKSPACE] + test_cases = [base_test.TestCaseType(key=key, params=params, rest_args=params['rest_args'], @@ -88,11 +112,23 @@ def before_class(self): ], }, scope='class') + self.post_publication(LAYER_HRANICE_PRIVATE, args={ + 'file_paths': [ + 'tmp/naturalearth/110m/cultural/ne_110m_admin_0_boundary_lines_land.cpg', + 'tmp/naturalearth/110m/cultural/ne_110m_admin_0_boundary_lines_land.dbf', + 'tmp/naturalearth/110m/cultural/ne_110m_admin_0_boundary_lines_land.prj', + 'tmp/naturalearth/110m/cultural/ne_110m_admin_0_boundary_lines_land.shp', + 'tmp/naturalearth/110m/cultural/ne_110m_admin_0_boundary_lines_land.shx', + ], + 'access_rights': {'read': PRIVATE_WORKSPACE, 'write': PRIVATE_WORKSPACE}, + 'actor_name': PRIVATE_WORKSPACE, + }, scope='class') + self.post_publication(MAP_HRANICE, args={ 'file_paths': [os.path.join(DIRECTORY, 'internal_hranice.json')], }, scope='class') - def assert_exp_map_layers(self, map, exp_map_layers, exp_operates_on): + def assert_exp_map_layers(self, map, exp_map_layers, exp_operates_on, http_method, actor_name): with app.app_context(): publ_info = get_publication_info(map.workspace, map.type, map.name, context={'keys': ['map_layers']}) @@ -118,7 +154,7 @@ def assert_exp_map_layers(self, map, exp_map_layers, exp_operates_on): for layer in exp_operates_on ] asserts_publ.metadata.correct_values_in_metadata( - map.workspace, map.type, map.name, http_method=REQUEST_METHOD_POST, exp_values={ + map.workspace, map.type, map.name, http_method=http_method, actor_name=actor_name, exp_values={ 'operates_on': exp_operates_on, }) @@ -138,18 +174,21 @@ def assert_exp_layer_maps(layer, map_operates_on_tuples): def test_publication(self, map, rest_method, rest_args, params): exp = params['exp_before_rest_method'] - self.assert_exp_map_layers(map, exp['map_layers'], exp['operates_on']) + self.assert_exp_map_layers(map, exp['map_layers'], exp['operates_on'], http_method=REQUEST_METHOD_POST, + actor_name=params['post_before_test_args'].get('actor_name')) self.assert_exp_layer_maps(LAYER_HRANICE, [ (MAP_HRANICE, MAP_HRANICE_OPERATES_ON), (map, exp['operates_on'] or []), ]) rest_method(map, args=rest_args) - if rest_method == self.post_publication: # pylint: disable=W0143 + if rest_method in [self.post_publication, self.patch_publication]: assert_util.is_publication_valid_and_complete(map) exp = params['exp_after_rest_method'] - self.assert_exp_map_layers(map, exp['map_layers'], exp['operates_on']) + http_method = REQUEST_METHOD_PATCH if rest_method == self.patch_publication else REQUEST_METHOD_POST # pylint: disable=W0143 + self.assert_exp_map_layers(map, exp['map_layers'], exp['operates_on'], http_method=http_method, + actor_name=rest_args.get('actor_name')) self.assert_exp_layer_maps(LAYER_HRANICE, [ (MAP_HRANICE, MAP_HRANICE_OPERATES_ON), (map, exp['operates_on'] or []), diff --git a/tests/static_data/__init__.py b/tests/static_data/__init__.py index 128aaa1c4..bd880e778 100644 --- a/tests/static_data/__init__.py +++ b/tests/static_data/__init__.py @@ -785,37 +785,6 @@ 'bbox': (3000, 3000, 5000, 5000), }, }, - (OWNER, MAP_TYPE, 'post_unauthorized_layer'): { - DEFINITION: [ - {'file_paths': ['sample/layman.map/internal_url_unauthorized_layer.json'], - 'access_rights': {'read': 'EVERYONE', - 'write': f"{OWNER},{OWNER2}", - }, - 'headers': HEADERS[OWNER], - }, - ], - TEST_DATA: { - 'layers': [(OWNER, LAYER_TYPE, 'post_private_sld'), (OWNER2, LAYER_TYPE, 'post_private_sld2'), ], - 'operates_on': {(OWNER, LAYER_TYPE, 'post_private_sld'), }, - 'users_can_write': [OWNER, OWNER2], - }, - }, - (OWNER, MAP_TYPE, 'patch_unauthorized_layer'): { - DEFINITION: [ - {'file_paths': ['sample/layman.map/internal_url_unauthorized_layer.json'], - 'access_rights': {'read': 'EVERYONE', - 'write': f"{OWNER},{OWNER2}", - }, - 'headers': HEADERS[OWNER], - }, - {'headers': HEADERS[OWNER2], } - ], - TEST_DATA: { - 'layers': [(OWNER, LAYER_TYPE, 'post_private_sld'), (OWNER2, LAYER_TYPE, 'post_private_sld2'), ], - 'operates_on': {(OWNER2, LAYER_TYPE, 'post_private_sld2'), }, - 'users_can_write': [OWNER, OWNER2], - }, - }, (WORKSPACE1, MAP_TYPE, 'test_publications_same_name_publ'): { DEFINITION: [ {}, @@ -854,9 +823,6 @@ LIST_QML_LAYERS = [(workspace, publ_type, publication) for (workspace, publ_type, publication), values in PUBLICATIONS.items() if publ_type == LAYER_TYPE and values[TEST_DATA].get('style_type') == 'qml'] -LIST_INTERNAL_MAPS = [(workspace, publ_type, publication) for (workspace, publ_type, publication), values in PUBLICATIONS.items() - if publ_type == MAP_TYPE and values[TEST_DATA].get('layers')] - WORKSPACES = {workspace for workspace, _, _ in PUBLICATIONS} assert len(WORKSPACES) > 0, WORKSPACES @@ -869,7 +835,6 @@ assert len(LIST_VECTOR_LAYERS) > 0, LIST_VECTOR_LAYERS assert len(LIST_SLD_LAYERS) > 0, LIST_SLD_LAYERS assert len(LIST_QML_LAYERS) > 0, LIST_QML_LAYERS -assert len(LIST_INTERNAL_MAPS) > 0, LIST_INTERNAL_MAPS assert any('normalized_overviews' in v[TEST_DATA] for v in PUBLICATIONS.values()) diff --git a/tests/static_data/multi_publications/__init__.py b/tests/static_data/multi_publications/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/static_data/multi_publications/publications_test.py b/tests/static_data/multi_publications/publications_test.py deleted file mode 100644 index 36d2c8b4b..000000000 --- a/tests/static_data/multi_publications/publications_test.py +++ /dev/null @@ -1,23 +0,0 @@ -import pytest -from layman import app -from layman.util import get_publication_info -from ... import static_data as data -from ..data import ensure_all_publications - - -@pytest.mark.timeout(600) -@pytest.mark.usefixtures('oauth2_provider_mock', 'ensure_layman') -def test_find_maps_containing_layer(): - ensure_all_publications() - - for l_workspace, l_type, layer in data.LIST_LAYERS: - expected_maps = {(workspace, publication) - for (workspace, publ_type, publication), values in data.PUBLICATIONS.items() - if publ_type == data.MAP_TYPE and (l_workspace, l_type, layer) in values[data.TEST_DATA].get('layers', [])} - - with app.app_context(): - result_maps = { - (mo['workspace'], mo['name']) - for mo in get_publication_info(l_workspace, l_type, layer, context={'keys': ['layer_maps']})['_layer_maps'] - } - assert result_maps == expected_maps diff --git a/tests/static_data/single_publication/maps_test.py b/tests/static_data/single_publication/maps_test.py deleted file mode 100644 index 151fc0815..000000000 --- a/tests/static_data/single_publication/maps_test.py +++ /dev/null @@ -1,41 +0,0 @@ -import json -import pytest - -from layman import app, util as layman_util -from test_tools import process_client -from ... import static_data as data -from ..data import ensure_publication - - -def assert_operates_on(workspace, mapname, expected_layers, authz_headers): - md_comparison = process_client.get_workspace_map_metadata_comparison(workspace, mapname, authz_headers) - operates_on = md_comparison['metadata_properties']['operates_on'] - assert (operates_on['equal']), json.dumps(operates_on, indent=2) - assert (operates_on['equal_or_null']), json.dumps(operates_on, indent=2) - assert len(operates_on['values'].values()) == 2 # GET Map File, CSW - - for operates_on_value in operates_on['values'].values(): - for (layer_uuid, layer_title) in expected_layers: - layer_record = next(rec for rec in operates_on_value - if rec['xlink:title'] == layer_title and layer_uuid in rec['xlink:href']) - assert layer_record, f"Layer uuid={layer_uuid}, title={layer_title} not found in operates_on value {json.dumps(operates_on_value, indent=2)}" - assert len(expected_layers) == len( - operates_on_value), f"Expected layers {expected_layers}, found {json.dumps(operates_on_value, indent=2)}" - - -@pytest.mark.parametrize('workspace, publ_type, publication', data.LIST_INTERNAL_MAPS) -@pytest.mark.usefixtures('oauth2_provider_mock', 'ensure_layman') -def test_map_with_unauthorized_layer(workspace, publ_type, publication): - ensure_publication(workspace, publ_type, publication) - - operates_on_layers = data.PUBLICATIONS[(workspace, publ_type, publication)][data.TEST_DATA]['operates_on'] - exp_operates_on = [] - for layer_workspace, layer_type, layer in operates_on_layers: - with app.app_context(): - info = layman_util.get_publication_info(layer_workspace, layer_type, layer, context={'keys': ['uuid', 'title']}) - uuid = info['uuid'] - title = info['title'] - exp_operates_on.append((uuid, title)) - - for headers in data.HEADERS.values(): - assert_operates_on(workspace, publication, exp_operates_on, authz_headers=headers)