def test_delete_map(client): with app.app_context(): workspace = 'testuser1' mapname = 'administrativni_cleneni_libereckeho_kraje' rest_path = url_for('rest_workspace_map.delete_map', workspace=workspace, mapname=mapname) response = client.delete(rest_path) assert response.status_code == 200 resp_json = response.get_json() uuid_str = resp_json['uuid'] md_record_url = f"http://micka:80/record/basic/m-{uuid_str}" response = requests.get(md_record_url, auth=settings.CSW_BASIC_AUTHN) response.raise_for_status() assert 'Záznam nenalezen' in response.text assert mapname not in response.text publication_counter.decrease() uuid.check_redis_consistency(expected_publ_num_by_type={ f'{MAP_TYPE}': publication_counter.get() }) with app.app_context(): rest_path = url_for('rest_workspace_map.delete_map', workspace=workspace, mapname=mapname) response = client.delete(rest_path) assert response.status_code == 404 resp_json = response.get_json() assert resp_json['code'] == 26 uuid.check_redis_consistency(expected_publ_num_by_type={ f'{MAP_TYPE}': publication_counter.get() })
def test_workspace_schema_conflict(client): if len(settings.PG_NON_USER_SCHEMAS) == 0: return response = client.post(url_for('rest_workspace_layers.post', workspace=settings.PG_NON_USER_SCHEMAS[0])) assert response.status_code == 409 resp_json = response.get_json() # print(resp_json) assert resp_json['code'] == 35 assert resp_json['detail']['reserved_by'] == db.__name__ assert 'reason' not in resp_json['detail'] for schema_name in [ 'pg_catalog', 'pg_toast', 'information_schema', ]: response = client.post(url_for('rest_workspace_layers.post', workspace=schema_name), data={ 'file': [ (io.BytesIO(MIN_GEOJSON.encode()), '/file.geojson') ] }) resp_json = response.get_json() # print(resp_json) assert response.status_code == 409 assert resp_json['code'] == 35 assert resp_json['detail']['reserved_by'] == db.__name__
def test_get_layers_testuser1_v2(client): workspace = 'testuser1' layer1 = 'countries_concurrent' layer2 = 'ne_110m_admin_0_countries' layer3 = 'ne_110m_admin_0_countries_shp' response = client.get(url_for('rest_workspace_layers.get', workspace=workspace)) assert response.status_code == 200 resp_json = response.get_json() # assert len(resp_json) == 3 layernames = [layer['name'] for layer in resp_json] for layer in [ layer1, layer2, layer3, ]: assert layer in layernames workspace = 'testuser2' response = client.get(url_for('rest_workspace_layers.get', workspace=workspace)) resp_json = response.get_json() assert response.status_code == 200 assert len(resp_json) == 1 assert resp_json[0]['name'] == 'countries' uuid.check_redis_consistency(expected_publ_num_by_type={ f'{LAYER_TYPE}': publication_counter.get() })
def test_unexisting_introspection_url(client, headers): username = '******' response = client.get(url_for('rest_workspace_layers.get', workspace=username), headers=headers) assert response.status_code == 403 resp_json = response.get_json() assert resp_json['code'] == 32 assert resp_json['sub_code'] == 8
def test_no_provider_found(client, headers): username = '******' response = client.get(url_for('rest_workspace_layers.get', workspace=username), headers=headers) assert response.status_code == 403 resp_json = response.get_json() assert resp_json['code'] == 32 assert resp_json['sub_code'] == 6
def test_auth_header_bad_first_part(client, headers): username = '******' response = client.get(url_for('rest_workspace_layers.get', workspace=username), headers=headers) assert response.status_code == 403 resp_json = response.get_json() assert resp_json['code'] == 32 assert resp_json['sub_code'] == 4
def check_metadata(client, workspace, mapname, props_equal, expected_values): with app.app_context(): rest_path = url_for('rest_workspace_map_metadata_comparison.get', workspace=workspace, mapname=mapname) response = client.get(rest_path) assert response.status_code == 200, response.get_json() resp_json = response.get_json() assert METADATA_PROPERTIES == set( resp_json['metadata_properties'].keys()) # for k, v in resp_json['metadata_properties'].items(): # print(f"'{k}': {json.dumps(list(v['values'].values())[0], indent=2)},") for key, value in resp_json['metadata_properties'].items(): assert value['equal_or_null'] == ( key in props_equal ), f"Metadata property values have unexpected 'equal_or_null' value: {key}: {json.dumps(value, indent=2)}, sources: {json.dumps(resp_json['metadata_sources'], indent=2)}" assert value['equal'] == ( key in props_equal ), f"Metadata property values have unexpected 'equal' value: {key}: {json.dumps(value, indent=2)}, sources: {json.dumps(resp_json['metadata_sources'], indent=2)}" # print(f"'{k}': {json.dumps(list(v['values'].values())[0], indent=2)},") if key in expected_values: vals = list(value['values'].values()) vals.append(expected_values[key]) assert prop_equals_strict(vals, equals_fn=PROPERTIES[key].get('equals_fn', None)),\ f"Property {key} has unexpected values {json.dumps(vals, indent=2)}"
def test_post_maps_invalid_json(client): workspace = 'testuser1' rest_path = url_for('rest_workspace_maps.post', workspace=workspace) file_paths = [ 'sample/layman.map/invalid-missing-title-email.json', ] for file_path in file_paths: assert os.path.isfile(file_path) files = [] try: files = [(open(fp, 'rb'), os.path.basename(fp)) for fp in file_paths] response = client.post(rest_path, data={ 'file': files, }) assert response.status_code == 400 resp_json = response.get_json() # print('resp_json', resp_json) assert resp_json['code'] == 2 assert resp_json['detail']['parameter'] == 'file' assert resp_json['detail'][ 'reason'] == 'JSON not valid against schema https://raw.githubusercontent.com/hslayers/map-compositions/2.0.0/schema.json' assert len(resp_json['detail']['validation-errors']) == 2 finally: for file_path in files: file_path[0].close() uuid.check_redis_consistency( expected_publ_num_by_type={f'{MAP_TYPE}': publication_counter.get()})
def test_token_active(client, headers): username = '******' url = url_for('rest_workspace_layers.get', workspace=username) response = client.get(url, headers=headers) assert response.status_code == 404 resp_json = response.get_json() assert resp_json['code'] == 40
def test_get_layer_title(): workspace = 'test_get_layer_title_workspace' layers = [("c_test_get_layer_title_layer", "C Test get layer title - map layer íářžý"), ("a_test_get_layer_title_layer", "A Test get layer title - map layer íářžý"), ("b_test_get_layer_title_layer", "B Test get layer title - map layer íářžý")] sorted_layers = sorted(layers) for (name, title) in layers: process_client.publish_workspace_layer(workspace, name, title=title) # layers.GET with app.app_context(): url = url_for('rest_workspace_layers.get', workspace=workspace) response = requests.get(url) assert response.status_code == 200, response.text for i in range(0, len(sorted_layers) - 1): assert response.json()[i]["name"] == sorted_layers[i][0] assert response.json()[i]["title"] == sorted_layers[i][1] for (name, title) in layers: process_client.delete_workspace_layer(workspace, name)
def test_patch_layer_style(client): with app.app_context(): workspace = 'testuser1' layername = 'ne_110m_admin_0_countries' rest_path = url_for('rest_workspace_layer.patch', workspace=workspace, layername=layername) sld_path = 'sample/style/generic-blue_sld.xml' assert os.path.isfile(sld_path) response = client.patch(rest_path, data={ 'style': (open(sld_path, 'rb'), os.path.basename(sld_path)), 'title': 'countries in blue' }) assert response.status_code == 200 # last_task = util._get_layer_task(workspace, layername) # Time to generate testing thumbnail is probably shorter than getting & parsing WMS/WFS capabilities documents # so it's finished before PATCH request is completed # # assert last_task is not None and not util._is_task_ready(last_task) # resp_json = rv.get_json() # keys_to_check = ['thumbnail'] # for key_to_check in keys_to_check: # assert 'status' in resp_json[key_to_check] flask_client.wait_till_layer_ready(workspace, layername) # last_task['last'].get() resp_json = response.get_json() assert resp_json['title'] == "countries in blue" wms_url = geoserver_wms.get_wms_url(workspace) wms = wms_proxy(wms_url) assert layername in wms.contents assert wms[layername].title == 'countries in blue' assert wms[layername].styles[ workspace + '_wms:' + layername]['title'] == 'Generic Blue' uuid.check_redis_consistency(expected_publ_num_by_type={ f'{LAYER_TYPE}': publication_counter.get() }) expected_md_values = { 'abstract': "and new description", 'extent': [-180.0, -85.60903859383285, 180.0, 83.64513109859944], 'graphic_url': url_for_external('rest_workspace_layer_thumbnail.get', workspace=workspace, layername=layername), 'identifier': { 'identifier': url_for_external('rest_workspace_layer.get', workspace=workspace, layername=layername), 'label': 'ne_110m_admin_0_countries' }, 'language': ['eng'], 'layer_endpoint': url_for_external('rest_workspace_layer.get', workspace=workspace, layername=layername), 'organisation_name': None, 'publication_date': TODAY_DATE, 'reference_system': EXP_REFERENCE_SYSTEMS, 'revision_date': TODAY_DATE, 'spatial_resolution': { 'scale_denominator': 100000000, }, 'title': 'countries in blue', } check_metadata(client, workspace, layername, METADATA_PROPERTIES_EQUAL, expected_md_values)
def test_no_file(client): response = client.post(url_for('rest_workspace_layers.post', workspace='testuser1')) assert response.status_code == 400 resp_json = response.get_json() # print('resp_json', resp_json) assert resp_json['code'] == 1 assert resp_json['detail']['parameter'] == 'file'
def test_qml_files(workspace, publ_type, publication): ensure_publication(workspace, publ_type, publication) workspace_directory = f'{settings.LAYMAN_QGIS_DATA_DIR}/workspaces/{workspace}' layer_directory = f'{workspace_directory}/layers/{publication}' assert os.path.exists(workspace_directory) assert os.path.exists(layer_directory) with app.app_context(): url = url_for('rest_workspace_layer_style.get', workspace=workspace, layername=publication, internal=False) assert wms.get_layer_info(workspace, publication) == { 'name': publication, 'style': { 'type': 'qml', 'url': url }, '_wms': { 'qgis_capabilities_url': f'{settings.LAYMAN_QGIS_URL}?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.1.1&' f'map=/qgis/data/test/workspaces/{workspace}/layers/{publication}/{publication}.qgis' } } assert workspace in qgis.get_workspaces()
def test_post_layers_shp_missing_extensions(client): workspace = 'testuser1' rest_path = url_for('rest_workspace_layers.post', workspace=workspace) file_paths = [ 'tmp/naturalearth/110m/cultural/ne_110m_admin_0_countries.dbf', 'tmp/naturalearth/110m/cultural/ne_110m_admin_0_countries.shp', 'tmp/naturalearth/110m/cultural/ne_110m_admin_0_countries.VERSION.txt', ] for file_path in file_paths: assert os.path.isfile(file_path) files = [] try: files = [(open(fp, 'rb'), os.path.basename(fp)) for fp in file_paths] response = client.post(rest_path, data={ 'file': files, 'name': 'ne_110m_admin_0_countries_shp', }) resp_json = response.get_json() # print(resp_json) assert response.status_code == 400 assert resp_json['code'] == 18 assert sorted(resp_json['detail']['missing_extensions']) == [ '.prj', '.shx'] finally: for file_path in files: file_path[0].close() uuid.check_redis_consistency(expected_publ_num_by_type={ f'{LAYER_TYPE}': publication_counter.get() })
def test_info(workspace, publ_type, publication): ensure_publication(workspace, publ_type, publication) wms_url = f"http://localhost:8000/geoserver/{workspace}{settings.LAYMAN_GS_WMS_WORKSPACE_POSTFIX}/ows" wfs_url = f"http://localhost:8000/geoserver/{workspace}/wfs" headers = data.HEADERS.get(data.PUBLICATIONS[(workspace, publ_type, publication)][data.TEST_DATA].get('users_can_write', [None])[0]) style = data.PUBLICATIONS[(workspace, publ_type, publication)][data.TEST_DATA]['style_type'] info = process_client.get_workspace_publication(publ_type, workspace, publication, headers=headers) with app.app_context(): info_internal = layer_util.get_layer_info(workspace, publication) expected_style_url = url_for('rest_workspace_layer_style.get', workspace=workspace, layername=publication, internal=False) file_type = info_internal['file']['file_type'] item_keys = get_layer_info_keys(file_type) assert set(info.keys()) == item_keys, f'info={info}' assert info['wms'].get('url') == wms_url, f'r_json={info}, wms_url={wms_url}' assert 'url' in info['wms'], f'info={info}' assert info.get('file', dict()).get('file_type') == data.PUBLICATIONS[(workspace, publ_type, publication)][data.TEST_DATA].get('file_type') if 'wfs' in info: assert info['wfs'].get('url') == wfs_url, f'r_json={info}, wfs_url={wfs_url}' assert info_internal['style_type'] == style, f'info_internal={info_internal}' assert info['style']['type'] == style, info.get('style') external_style_url = info['style']['url'] assert external_style_url == expected_style_url, (info, external_style_url)
def test_layman_gs_user_conflict(client): """Tests that Layman detects that reserved username is in conflict with LAYMAN_GS_USER. See https://github.com/LayerManager/layman/pull/97 """ workspace = settings.LAYMAN_GS_USER layername = 'layer1' rest_path = url_for('rest_workspace_layers.post', workspace=workspace) file_paths = [ 'tmp/naturalearth/110m/cultural/ne_110m_populated_places.geojson', ] for file_path in file_paths: assert os.path.isfile(file_path) files = [] try: files = [(open(fp, 'rb'), os.path.basename(fp)) for fp in file_paths] response = client.post(rest_path, data={ 'file': files, 'name': layername, }) resp_json = response.get_json() assert response.status_code == 409 assert resp_json['code'] == 41 finally: for file_path in files: file_path[0].close()
def test_delete_layer(client): workspace = 'testuser1' layername = 'ne_110m_admin_0_countries' rest_path = url_for('rest_workspace_layer.delete_layer', workspace=workspace, layername=layername) response = client.delete(rest_path) assert response.status_code == 200 publication_counter.decrease() uuid.check_redis_consistency(expected_publ_num_by_type={ f'{LAYER_TYPE}': publication_counter.get() }) rest_path = url_for('rest_workspace_layer.delete_layer', workspace=workspace, layername=layername) response = client.delete(rest_path) assert response.status_code == 404 resp_json = response.get_json() assert resp_json['code'] == 15
def test_no_auth_header(client): username = '******' response = client.get(url_for('rest_workspace_layers.get', workspace=username), headers={ f'{ISS_URL_HEADER}': 'abc' }) assert response.status_code == 403 resp_json = response.get_json() assert resp_json['code'] == 32 assert resp_json['sub_code'] == 2
def test_get_layers_testuser2(client): workspace = 'testuser2' response = client.get(url_for('rest_workspace_layers.get', workspace=workspace)) assert response.status_code == 200 resp_json = response.get_json() assert len(resp_json) == 0 uuid.check_redis_consistency(expected_publ_num_by_type={ f'{LAYER_TYPE}': publication_counter.get() })
def test_wrong_value_of_workspace(client): workspaces = [' ', '2a', 'ě', ';', '?', 'ABC'] for workspace in workspaces: response = client.post(url_for('rest_workspace_layers.post', workspace=workspace)) resp_json = response.get_json() # print('username', username) # print(resp_json) assert response.status_code == 400 assert resp_json['code'] == 2 assert resp_json['detail']['parameter'] == 'workspace'
def test_get_layers_testuser1_v1(client): workspace = 'test_get_layers_testuser1_v1_user' layername = 'layer1' # publish and delete layer to ensure that username exists flask_client.publish_layer(workspace, layername, client) flask_client.delete_layer(workspace, layername, client) response = client.get(url_for('rest_workspace_layers.get', workspace=workspace)) assert response.status_code == 200, response.get_json() # assert len(resp_json) == 0 uuid.check_redis_consistency(expected_publ_num_by_type={ f'{LAYER_TYPE}': publication_counter.get() })
def test_post_layers_long_and_delete_it(client): workspace = 'testuser1' rest_path = url_for('rest_workspace_layers.post', workspace=workspace) file_paths = [ 'tmp/naturalearth/10m/cultural/ne_10m_admin_0_countries.geojson', ] for file_path in file_paths: assert os.path.isfile(file_path) files = [] try: files = [(open(fp, 'rb'), os.path.basename(fp)) for fp in file_paths] response = client.post(rest_path, data={ 'file': files, }) assert response.status_code == 200 finally: for file_path in files: file_path[0].close() layername = 'ne_10m_admin_0_countries' time.sleep(1) chain_info = util.get_layer_chain(workspace, layername) assert chain_info is not None and not celery_util.is_chain_ready(chain_info) layer_info = util.get_layer_info(workspace, layername) keys_to_check = ['db_table', 'wms', 'wfs', 'thumbnail', 'metadata'] for key_to_check in keys_to_check: assert 'status' in layer_info[key_to_check] rest_path = url_for('rest_workspace_layer.delete_layer', workspace=workspace, layername=layername) response = client.delete(rest_path) assert response.status_code == 200 response = client.get(url_for('rest_workspace_layer.get', workspace=workspace, layername=layername)) # print(resp_json) assert response.status_code == 404 uuid.check_redis_consistency(expected_publ_num_by_type={ f'{LAYER_TYPE}': publication_counter.get() })
def test_get_maps_empty(client): workspace = 'testuser1' flask_client.ensure_workspace(workspace, client) with app.app_context(): response = client.get( url_for('rest_workspace_maps.get', workspace=workspace)) resp_json = response.get_json() assert response.status_code == 200, response.data assert len(resp_json) == 0 uuid.check_redis_consistency(expected_publ_num_by_type={ f'{MAP_TYPE}': publication_counter.get() })
def test_get_current_user_anonymous(client): rest_path = url_for('rest_current_user.get') response = client.get(rest_path) assert response.status_code == 200 resp_json = response.get_json() assert resp_json['authenticated'] is False, resp_json assert {'authenticated', 'claims'} == set(resp_json.keys()), resp_json claims = resp_json['claims'] assert { 'iss', 'name', 'nickname' } == set(claims.keys()), claims assert claims['name'] == 'Anonymous', claims assert claims['nickname'] == 'Anonymous', claims
def test_wrong_value_of_mapname(client): workspace = 'testuser1' mapnames = [' ', '2a', 'ě', ';', '?', 'ABC'] for mapname in mapnames: response = client.get( url_for('rest_workspace_map.get', workspace=workspace, mapname=mapname)) resp_json = response.get_json() # print('workspace', workspace) # print(resp_json) assert response.status_code == 400 assert resp_json['code'] == 2 assert resp_json['detail']['parameter'] == 'mapname'
def test_wrong_value_of_layername(client): workspace = 'test_wrong_value_of_layername_workspace' layername = 'layer1' # publish and delete layer to ensure that username exists flask_client.publish_layer(workspace, layername, client) flask_client.delete_layer(workspace, layername, client) layernames = [' ', '2a', 'ě', ';', '?', 'ABC'] for layername in layernames: with app.app_context(): response = client.get(url_for('rest_workspace_layer.get', workspace=workspace, layername=layername)) resp_json = response.get_json() assert response.status_code == 400, resp_json assert resp_json['code'] == 2 assert resp_json['detail']['parameter'] == 'layername'
def correct_url_in_rest_multi(workspace, publ_type, name, headers): infos = process_client.get_workspace_publications(publ_type, workspace, headers=headers) publication_infos = [info for info in infos if info['name'] == name] info = next(iter(publication_infos)) get_workspace_publication_url = process_client.PUBLICATION_TYPES_DEF[ publ_type].get_workspace_publication_url param_name = process_client.PUBLICATION_TYPES_DEF[publ_type].url_param_name with app.app_context(): expected_url = test_util.url_for(get_workspace_publication_url, workspace=workspace, **{param_name: name}, internal=False) assert info[ 'url'] == expected_url, f'publication_infos={publication_infos}, expected_url={expected_url}'
def test_patch_layer_title(client): with app.app_context(): workspace = 'testuser1' layername = 'ne_110m_admin_0_countries' rest_path = url_for('rest_workspace_layer.patch', workspace=workspace, layername=layername) new_title = "New Title of Countries" new_description = "and new description" response = client.patch(rest_path, data={ 'title': new_title, 'description': new_description, }) assert response.status_code == 200, response.get_json() chain_info = util.get_layer_chain(workspace, layername) assert chain_info is not None and celery_util.is_chain_ready(chain_info) resp_json = response.get_json() assert resp_json['title'] == new_title assert resp_json['description'] == new_description with app.app_context(): expected_md_values = { 'abstract': "and new description", 'extent': [-180.0, -85.60903859383285, 180.0, 83.64513109859944], 'graphic_url': url_for_external('rest_workspace_layer_thumbnail.get', workspace=workspace, layername=layername), 'identifier': { 'identifier': url_for_external('rest_workspace_layer.get', workspace=workspace, layername=layername), 'label': 'ne_110m_admin_0_countries' }, 'language': ['eng'], 'layer_endpoint': url_for_external('rest_workspace_layer.get', workspace=workspace, layername=layername), 'organisation_name': None, 'publication_date': TODAY_DATE, 'reference_system': EXP_REFERENCE_SYSTEMS, 'revision_date': TODAY_DATE, 'spatial_resolution': { 'scale_denominator': 100000000, }, 'title': "New Title of Countries", } check_metadata(client, workspace, layername, METADATA_PROPERTIES_EQUAL, expected_md_values) uuid.check_redis_consistency(expected_publ_num_by_type={ f'{LAYER_TYPE}': publication_counter.get() })
def test_authorize_publications_decorator_on_rest_api( self, rest_action, url_for_params, authz_status_code, authz_response, unauthz_status_code, unauthz_response, ): username = self.username authz_headers = self.authz_headers patch_method = None publ_name = None if '_layer' in rest_action: patch_method = process_client.patch_workspace_layer publ_name = self.layername elif '_map' in rest_action: patch_method = process_client.patch_workspace_map publ_name = self.mapname assert publ_name url_for_params['workspace'] = username with app.app_context(): rest_url = url_for(rest_action, **url_for_params) patch_method(username, publ_name, headers=authz_headers, access_rights={ 'read': username, 'write': username, }) response = requests.get(rest_url, headers=authz_headers) self.assert_response(response, authz_status_code, authz_response) response = requests.get(rest_url) self.assert_response(response, unauthz_status_code, unauthz_response) patch_method(username, publ_name, headers=authz_headers, access_rights={ 'read': settings.RIGHTS_EVERYONE_ROLE, 'write': settings.RIGHTS_EVERYONE_ROLE, }) response = requests.get(rest_url, headers=authz_headers) self.assert_response(response, authz_status_code, authz_response) response = requests.get(rest_url) self.assert_response(response, authz_status_code, authz_response)
def test_layername_db_object_conflict(client): file_paths = [ 'tmp/naturalearth/110m/cultural/ne_110m_admin_0_countries.geojson', ] for file_path in file_paths: assert os.path.isfile(file_path) files = [] try: files = [(open(fp, 'rb'), os.path.basename(fp)) for fp in file_paths] response = client.post(url_for('rest_workspace_layers.post', workspace='testuser1'), data={ 'file': files, 'name': 'spatial_ref_sys', }) assert response.status_code == 409 resp_json = response.get_json() assert resp_json['code'] == 9 finally: for file_path in files: file_path[0].close()