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)
Ejemplo n.º 2
0
def delete_layer_after_test():
    def register_layer_to_delete(workspace, layername):
        LAYERS_TO_DELETE_AFTER_TEST.append((workspace, layername))

    yield register_layer_to_delete
    for workspace, layername in LAYERS_TO_DELETE_AFTER_TEST:
        process_client.delete_workspace_layer(workspace, layername)
Ejemplo n.º 3
0
def test_wrong_sld_causes_no_thumbnail():
    workspace = 'test_wrong_sld_causes_no_thumbnail_workspace'
    layer = 'test_wrong_sld_causes_no_thumbnail_layer'
    geojson_file = ['/code/sample/layman.layer/sample_point_cz.geojson']
    style_file = '/code/sample/layman.layer/sample_point_cz_wrong_literal.sld'

    def wait_for_thumbnail_error(response):
        ok_keys = ['db_table', 'wms', 'wfs', 'file']
        if response.status_code == 200:
            r_json = response.json()
            result = response.status_code == 200 and all(
                'status' not in r_json[k] for k in ok_keys
            ) and 'status' in r_json['thumbnail'] and r_json['thumbnail']['status'] in ['FAILURE']
        else:
            result = False
        return result

    process_client.publish_workspace_layer(workspace,
                                           layer,
                                           file_paths=geojson_file,
                                           style_file=style_file,
                                           check_response_fn=wait_for_thumbnail_error,
                                           )

    layer_info = process_client.get_workspace_layer(workspace, layer)

    assert 'error' in layer_info['thumbnail']
    assert layer_info['thumbnail']['error']['message'] == 'Thumbnail rendering failed'
    assert layer_info['thumbnail']['error']['code'] == -1

    process_client.delete_workspace_layer(workspace,
                                          layer)
Ejemplo n.º 4
0
def test_wfs_bbox(style_file, thumbnail_style_postfix):
    workspace = 'test_wfs_bbox_workspace'
    layer = 'test_wfs_bbox_layer'

    process_client.publish_workspace_layer(
        workspace,
        layer,
        style_file=style_file,
    )

    native_crs = SMALL_LAYER_NATIVE_CRS
    assert_util.assert_all_sources_bbox(
        workspace,
        layer,
        SMALL_LAYER_BBOX,
        expected_native_bbox=SMALL_LAYER_NATIVE_BBOX,
        expected_native_crs=native_crs)

    expected_bbox = (1571000.0, 6268800.0, 1572590.854206196, 6269876.33561699)
    exp_native_bbox = (14.112533113517683, 48.964264493114904, 14.126824,
                       48.970612)
    method_bbox_thumbnail_tuples = [
        (data_wfs.get_wfs20_insert_points, expected_bbox, exp_native_bbox,
         '_bigger'),
        (data_wfs.get_wfs20_delete_point, SMALL_LAYER_BBOX,
         SMALL_LAYER_NATIVE_BBOX, ''),
    ]

    for wfs_method, exp_bbox, exp_native_bbox, thumbnail_bbox_postfix in method_bbox_thumbnail_tuples:
        data_xml = wfs_method(
            workspace,
            layer,
        )

        process_client.post_wfst(data_xml, workspace=workspace)
        process_client.wait_for_publication_status(workspace,
                                                   process_client.LAYER_TYPE,
                                                   layer)

        assert_util.assert_all_sources_bbox(
            workspace,
            layer,
            exp_bbox,
            expected_native_bbox=exp_native_bbox,
            expected_native_crs=native_crs)

        expected_thumbnail_path = f'/code/sample/style/{layer}{thumbnail_style_postfix}{thumbnail_bbox_postfix}.png'
        with app.app_context():
            thumbnail_path = thumbnail.get_layer_thumbnail_path(
                workspace, layer)
        diffs = test_util.compare_images(expected_thumbnail_path,
                                         thumbnail_path)
        assert diffs < 100, expected_thumbnail_path

    process_client.delete_workspace_layer(
        workspace,
        layer,
    )
Ejemplo n.º 5
0
 def provide_publications(self):
     username = self.username
     authz_headers = self.authz_headers
     layername = self.layername
     mapname = self.mapname
     process_client.ensure_reserved_username(username, headers=authz_headers)
     process_client.publish_workspace_layer(username, layername, headers=authz_headers)
     process_client.publish_workspace_map(username, mapname, headers=authz_headers)
     yield
     process_client.delete_workspace_layer(username, layername, headers=authz_headers)
     process_client.delete_workspace_map(username, mapname, headers=authz_headers)
Ejemplo n.º 6
0
def test_map_refresh_after_layer_change():
    workspace = 'test_map_refresh_after_layer_change_workspace'
    layer = 'test_map_refresh_after_layer_change_layer'
    map = 'test_map_refresh_after_layer_change_map'
    bbox = (1571000.0, 6268800.0, 1572590.8542062, 6269876.33561699)

    process_client.publish_workspace_layer(workspace, layer)

    file_path = f'tmp/map_with_internal_layers.json'
    map_data.create_map_with_internal_layers_file([(workspace, layer)],
                                                  file_path=file_path,
                                                  native_extent=bbox,
                                                  native_crs='EPSG:3857')
    process_client.publish_workspace_map(workspace,
                                         map,
                                         file_paths=[file_path])

    assert_map_thumbnail(
        workspace, map,
        f'/code/test_tools/data/thumbnail/map_with_internal_layer_basic.png')

    # Test refresh map thumbnail after layer WFS-T query
    data_xml = data_wfs.get_wfs20_insert_points(
        workspace,
        layer,
    )
    process_client.post_wfst(data_xml)
    process_client.wait_for_publication_status(workspace,
                                               process_client.LAYER_TYPE,
                                               layer)
    assert_map_thumbnail(
        workspace, map,
        f'/code/test_tools/data/thumbnail/map_with_internal_layer_basic_after_wfst.png'
    )

    # Test refresh map thumbnail after patch layer
    process_client.patch_workspace_layer(
        workspace,
        layer,
        file_paths=['sample/layman.layer/small_layer.geojson'])
    process_client.wait_for_publication_status(workspace,
                                               process_client.LAYER_TYPE,
                                               layer)
    assert_map_thumbnail(
        workspace, map,
        f'/code/test_tools/data/thumbnail/map_with_internal_layer_basic.png')

    process_client.delete_workspace_map(workspace, map)
    process_client.delete_workspace_layer(workspace, layer)
Ejemplo n.º 7
0
def test_layer_with_different_geometry():
    workspace = 'testgeometryuser1'
    layername = 'layer_with_different_geometry'
    file_paths = [
        'tmp/naturalearth/110m/cultural/ne_110m_populated_places.geojson',
    ]
    process_client.publish_workspace_layer(workspace, layername, file_paths=file_paths)

    url_path_ows = urljoin(urljoin(settings.LAYMAN_GS_URL, workspace), 'ows?service=WFS&request=Transaction')
    url_path_wfs = urljoin(urljoin(settings.LAYMAN_GS_URL, workspace), 'wfs?request=Transaction')

    headers_wfs = {
        'Accept': 'text/xml',
        'Content-type': 'text/xml',
    }

    data_xml = data_wfs.get_wfs20_insert_points(workspace, layername)

    response = requests.post(url_path_ows,
                             data=data_xml,
                             headers=headers_wfs,
                             auth=settings.LAYMAN_GS_AUTH
                             )
    response.raise_for_status()

    response = requests.post(url_path_wfs,
                             data=data_xml,
                             headers=headers_wfs,
                             auth=settings.LAYMAN_GS_AUTH
                             )
    assert response.status_code == 200, f"HTTP Error {response.status_code}\n{response.text}"

    data_xml2 = data_wfs.get_wfs20_insert_lines(workspace, layername)

    response = requests.post(url_path_ows,
                             data=data_xml2,
                             headers=headers_wfs,
                             auth=settings.LAYMAN_GS_AUTH
                             )
    assert response.status_code == 200, f"HTTP Error {response.status_code}\n{response.text}"

    response = requests.post(url_path_wfs,
                             data=data_xml2,
                             headers=headers_wfs,
                             auth=settings.LAYMAN_GS_AUTH
                             )
    assert response.status_code == 200, f"HTTP Error {response.status_code}\n{response.text}"
    process_client.delete_workspace_layer(workspace, layername)
def test_style_correctly_saved(source_style_file_path, layer_suffix,
                               expected_style_file_template,
                               expected_style_type):
    workspace = 'test_style_correctly_saved_workspace'
    layer = 'test_style_correctly_saved_layer' + layer_suffix
    expected_style_file = expected_style_file_template.format(
        workspace=workspace,
        layer=layer) if expected_style_file_template else None
    process_client.publish_workspace_layer(workspace,
                                           layer,
                                           style_file=source_style_file_path)
    assert_style_file(workspace, layer, expected_style_file)
    with app.app_context():
        info = layman_util.get_publication_info(workspace,
                                                process_client.LAYER_TYPE,
                                                layer,
                                                context={
                                                    'keys':
                                                    ['style_type', 'style'],
                                                })
    assert info['style_type'] == expected_style_type

    process_client.delete_workspace_layer(workspace, layer)
    process_client.publish_workspace_layer(workspace, layer)

    with app.app_context():
        info = layer_util.get_layer_info(workspace, layer)
    assert info['style_type'] == 'sld'
    assert info['style']['type'] == 'sld', info.get('style')
    assert info['style']['url'], info.get('style')

    assert_style_file(workspace, layer, None)

    process_client.patch_workspace_layer(workspace,
                                         layer,
                                         style_file=source_style_file_path)
    assert_style_file(workspace, layer, expected_style_file)
    with app.app_context():
        info = layer_util.get_layer_info(workspace, layer)
    assert info['style_type'] == expected_style_type

    process_client.delete_workspace_layer(workspace, layer)
Ejemplo n.º 9
0
def test_post_layers_zero_length_attribute():
    workspace = 'testuser1'
    layername = 'zero_length_attribute'
    file_paths = [
        'sample/data/zero_length_attribute.geojson',
    ]

    def wait_for_db_finish(response):
        info = response.json()
        return info.get('db_table', dict()).get('status', '') == 'FAILURE'

    process_client.publish_workspace_layer(workspace, layername, file_paths=file_paths, check_response_fn=wait_for_db_finish)

    layer_info = util.get_layer_info(workspace, layername)
    assert layer_info['db_table']['status'] == 'FAILURE', f'layer_info={layer_info}'
    assert layer_info['db_table']['error']['code'] == 28, f'layer_info={layer_info}'

    process_client.delete_workspace_layer(workspace, layername)

    uuid.check_redis_consistency(expected_publ_num_by_type={
        f'{LAYER_TYPE}': publication_counter.get()
    })
Ejemplo n.º 10
0
def test_geometry_types(layer, exp_db_types, qml_geometry_dict):
    def get_qml_style_path(style_name):
        return f'/code/sample/data/geometry-types/{style_name}.qml' if style_name else None

    workspace = 'test_geometry_types_workspace'
    process_client.publish_workspace_layer(workspace, layer, file_paths=[f'/code/sample/data/geometry-types/{layer}.geojson'], )
    with app.app_context():
        db_types = db.get_geometry_types(workspace, layer)
    assert set(db_types) == exp_db_types

    qgis_geometries = ['Point', 'Line', 'Polygon', 'Unknown geometry']

    old_qml_style_name = None
    for qml_geometry in qgis_geometries:
        exp_source_type, new_qml_style_name = qml_geometry_dict.get(qml_geometry, (None, None))
        if exp_source_type is None:
            with pytest.raises(LaymanError) as excinfo:
                util.get_source_type(db_types, qml_geometry)
            assert excinfo.value.code == 47, f"qml_geometry={qml_geometry}, exp_source_type={exp_source_type}"
        else:
            source_type = util.get_source_type(db_types, qml_geometry)
            assert source_type == exp_source_type, f"qml_geometry={qml_geometry}, exp_source_type={exp_source_type}, " \
                                                   f"source_type={source_type}, db_types={db_types}"
        if new_qml_style_name:
            if new_qml_style_name != old_qml_style_name:
                process_client.patch_workspace_layer(workspace, layer, style_file=get_qml_style_path(new_qml_style_name))
                old_qml_style_name = new_qml_style_name
            with app.app_context():
                qml = util.get_original_style_xml(workspace, layer)
            found_qml_geometry = util.get_qml_geometry_from_qml(qml)
            assert found_qml_geometry == qml_geometry
            exp_file_path = f'/code/sample/data/geometry-types/{new_qml_style_name}.png'
            with app.app_context():
                thumbnail_path = thumbnail.get_layer_thumbnail_path(workspace, layer)
            diff_pixels = test_util.compare_images(thumbnail_path, exp_file_path)
            assert diff_pixels == 0, f"thumbnail_path={thumbnail_path}, exp_file_path={exp_file_path}"

    process_client.delete_workspace_layer(workspace, layer)
Ejemplo n.º 11
0
def test_empty_shapefile(layername, file_paths):
    workspace = 'test_empty_bbox_workspace'
    title = layername

    process_client.publish_workspace_layer(workspace,
                                           layername,
                                           file_paths=file_paths)

    wms_layer = assert_wms_layer(workspace, layername, title)
    native_bbox = wms_layer.boundingBox
    wgs_bbox = wms_layer.boundingBoxWGS84

    title = 'new title'
    process_client.patch_workspace_layer(workspace, layername, title=title)
    wms_layer = assert_wms_layer(workspace, layername, title)
    assert wms_layer.boundingBox == native_bbox
    assert wms_layer.boundingBoxWGS84 == wgs_bbox

    wfs_t_insert_point(workspace, layername)
    wms_layer = assert_wms_layer(workspace, layername, title)
    assert wms_layer.boundingBox == native_bbox
    assert wms_layer.boundingBoxWGS84 == wgs_bbox

    process_client.delete_workspace_layer(workspace, layername)
Ejemplo n.º 12
0
def test_missing_attribute(style_file, ):
    username = '******'
    layername = 'inexisting_attribute_layer'
    layername2 = 'inexisting_attribute_layer2'

    authn_headers = get_authz_headers(username)

    process_client.ensure_reserved_username(username, headers=authn_headers)
    process_client.publish_workspace_layer(
        username,
        layername,
        file_paths=[
            'tmp/naturalearth/110m/cultural/ne_110m_admin_0_countries.geojson',
        ],
        style_file=style_file,
        headers=authn_headers,
    )
    process_client.publish_workspace_layer(
        username,
        layername2,
        file_paths=[
            'tmp/naturalearth/110m/cultural/ne_110m_admin_0_countries.geojson',
        ],
        style_file=style_file,
        headers=authn_headers,
    )

    with app.app_context():
        style_type = layman_util.get_publication_info(
            username,
            process_client.LAYER_TYPE,
            layername,
            context={
                'keys': ['style_type'],
            })['style_type']

    def wfs_post(workspace, attr_names_list, data_xml):
        with app.app_context():
            wfs_url = f"http://{settings.LAYMAN_SERVER_NAME}/geoserver/{workspace}/wfs"
            old_db_attributes = {}
            old_wfs_properties = {}
            for layer, attr_names in attr_names_list:
                # test that all attr_names are not yet presented in DB table
                old_db_attributes[layer] = db.get_all_column_names(
                    workspace, layer)
                for attr_name in attr_names:
                    assert attr_name not in old_db_attributes[
                        layer], f"old_db_attributes={old_db_attributes[layer]}, attr_name={attr_name}"
                layer_schema = get_wfs_schema(wfs_url,
                                              typename=f"{workspace}:{layer}",
                                              version=geoserver_wfs.VERSION,
                                              headers=authn_headers)
                old_wfs_properties[layer] = sorted(
                    layer_schema['properties'].keys())
                if style_type == 'qml':
                    assert qgis_wms.get_layer_info(workspace, layer)
                    old_qgis_attributes = qgis_util.get_layer_attribute_names(
                        workspace, layer)
                    assert all(
                        attr_name not in old_qgis_attributes
                        for attr_name in attr_names), (attr_names,
                                                       old_qgis_attributes)

            process_client.post_wfst(data_xml,
                                     headers=authn_headers,
                                     workspace=username)

            new_db_attributes = {}
            new_wfs_properties = {}
            for layer, attr_names in attr_names_list:
                # test that exactly all attr_names were created in DB table
                new_db_attributes[layer] = db.get_all_column_names(
                    workspace, layer)
                for attr_name in attr_names:
                    assert attr_name in new_db_attributes[
                        layer], f"new_db_attributes={new_db_attributes[layer]}, attr_name={attr_name}"
                assert set(attr_names).union(set(
                    old_db_attributes[layer])) == set(new_db_attributes[layer])

                # test that exactly all attr_names were distinguished also in WFS feature type
                layer_schema = get_wfs_schema(wfs_url,
                                              typename=f"{workspace}:{layer}",
                                              version=geoserver_wfs.VERSION,
                                              headers=authn_headers)
                new_wfs_properties[layer] = sorted(
                    layer_schema['properties'].keys())
                for attr_name in attr_names:
                    assert attr_name in new_wfs_properties[
                        layer], f"new_wfs_properties={new_wfs_properties[layer]}, attr_name={attr_name}"
                assert set(attr_names).union(set(old_wfs_properties[layer])) == set(new_wfs_properties[layer]),\
                    set(new_wfs_properties[layer]).difference(set(attr_names).union(set(old_wfs_properties[layer])))
                if style_type == 'qml':
                    assert qgis_wms.get_layer_info(workspace, layer)
                    new_qgis_attributes = qgis_util.get_layer_attribute_names(
                        workspace, layer)
                    assert all(
                        attr_name in new_qgis_attributes
                        for attr_name in attr_names), (attr_names,
                                                       new_qgis_attributes)
                else:
                    assert not qgis_wms.get_layer_info(workspace, layer)

    attr_names = ['inexisting_attribute_attr', 'inexisting_attribute_attr1a']
    data_xml = data_wfs.get_wfs20_insert_points_new_attr(
        username, layername, attr_names)
    wfs_post(username, [(layername, attr_names)], data_xml)

    attr_names2 = ['inexisting_attribute_attr2']
    data_xml = data_wfs.get_wfs20_update_points_new_attr(
        username, layername, attr_names2)
    wfs_post(username, [(layername, attr_names2)], data_xml)

    attr_names3 = ['inexisting_attribute_attr3']
    data_xml = data_wfs.get_wfs20_update_points_new_attr(
        username, layername, attr_names3, with_attr_namespace=True)
    wfs_post(username, [(layername, attr_names3)], data_xml)

    attr_names4 = ['inexisting_attribute_attr4']
    data_xml = data_wfs.get_wfs20_update_points_new_attr(username,
                                                         layername,
                                                         attr_names4,
                                                         with_filter=True)
    wfs_post(username, [(layername, attr_names4)], data_xml)

    attr_names5 = ['inexisting_attribute_attr5']
    data_xml = data_wfs.get_wfs20_replace_points_new_attr(
        username, layername, attr_names5)
    wfs_post(username, [(layername, attr_names5)], data_xml)

    attr_names_i1 = ['inexisting_attribute_attr_complex_i1']
    attr_names_i2 = ['inexisting_attribute_attr_complex_i2']
    attr_names_u = ['inexisting_attribute_attr_complex_u']
    attr_names_r = ['inexisting_attribute_attr_complex_r']
    attr_names_complex = [(layername, attr_names_i1 + attr_names_r),
                          (layername2, attr_names_i2 + attr_names_u)]
    data_xml = data_wfs.get_wfs20_complex_new_attr(
        workspace=username,
        layername1=layername,
        layername2=layername2,
        attr_names_insert1=attr_names_i1,
        attr_names_insert2=attr_names_i2,
        attr_names_update=attr_names_u,
        attr_names_replace=attr_names_r)
    wfs_post(username, attr_names_complex, data_xml)

    attr_names6 = ['inexisting_attribute_attr6']
    data_xml = data_wfs.get_wfs10_insert_points_new_attr(
        username, layername, attr_names6)
    wfs_post(username, [(layername, attr_names6)], data_xml)

    attr_names7 = ['inexisting_attribute_attr7']
    data_xml = data_wfs.get_wfs11_insert_points_new_attr(
        username, layername, attr_names7)
    wfs_post(username, [(layername, attr_names7)], data_xml)

    attr_names8 = ['inexisting_attribute_attr8']
    data_xml = data_wfs.get_wfs10_update_points_new(username,
                                                    layername,
                                                    attr_names8,
                                                    with_attr_namespace=True)
    wfs_post(username, [(layername, attr_names8)], data_xml)

    attr_names9 = ['inexisting_attribute_attr9']
    data_xml = data_wfs.get_wfs10_update_points_new(username,
                                                    layername,
                                                    attr_names9,
                                                    with_filter=True)
    wfs_post(username, [(layername, attr_names9)], data_xml)

    attr_names10 = ['inexisting_attribute_attr10']
    data_xml = data_wfs.get_wfs11_insert_polygon_new_attr(
        username, layername, attr_names10)
    wfs_post(username, [(layername, attr_names10)], data_xml)

    process_client.delete_workspace_layer(username,
                                          layername,
                                          headers=authn_headers)
    process_client.delete_workspace_layer(username,
                                          layername2,
                                          headers=authn_headers)
Ejemplo n.º 13
0
def test_missing_attribute_authz():
    username = '******'
    layername1 = 'testmissingattr_authz_layer'
    username2 = 'testmissingattr_authz2'

    authn_headers1 = get_authz_headers(username)
    authn_headers2 = get_authz_headers(username2)

    def do_test(wfs_query, attribute_names):
        # Test, that unauthorized user will not cause new attribute
        with app.app_context():
            old_db_attributes = db.get_all_column_names(username, layername1)
        for attr_name in attribute_names:
            assert attr_name not in old_db_attributes, f"old_db_attributes={old_db_attributes}, attr_name={attr_name}"
        with pytest.raises(GS_Error) as exc:
            process_client.post_wfst(wfs_query,
                                     headers=authn_headers2,
                                     workspace=username)
        assert exc.value.data['status_code'] == 400

        with app.app_context():
            new_db_attributes = db.get_all_column_names(username, layername1)
        for attr_name in attribute_names:
            assert attr_name not in new_db_attributes, f"new_db_attributes={new_db_attributes}, attr_name={attr_name}"

        # Test, that authorized user will cause new attribute
        process_client.post_wfst(wfs_query,
                                 headers=authn_headers1,
                                 workspace=username)
        with app.app_context():
            new_db_attributes = db.get_all_column_names(username, layername1)
        for attr_name in attribute_names:
            assert attr_name in new_db_attributes, f"new_db_attributes={new_db_attributes}, attr_name={attr_name}"

    process_client.reserve_username(username, headers=authn_headers1)
    process_client.publish_workspace_layer(
        username,
        layername1,
        file_paths=[
            'tmp/naturalearth/110m/cultural/ne_110m_admin_0_countries.geojson',
        ],
        headers=authn_headers1)

    # Testing, that user2 is not able to write to layer of user1
    process_client.reserve_username(username2, headers=authn_headers2)

    # INSERT
    attr_names = ['inexisting_attribute_auth1', 'inexisting_attribute_auth2']
    data_xml = data_wfs.get_wfs20_insert_points_new_attr(
        username, layername1, attr_names)
    do_test(data_xml, attr_names)

    # UPDATE
    attr_names = ['inexisting_attribute_auth3', 'inexisting_attribute_auth4']
    data_xml = data_wfs.get_wfs20_update_points_new_attr(
        username, layername1, attr_names)
    do_test(data_xml, attr_names)

    process_client.delete_workspace_layer(username,
                                          layername1,
                                          headers=authn_headers1)
Ejemplo n.º 14
0
def clear_country_chunks():
    yield
    process_client.delete_workspace_layer(WORKSPACE, LAYERNAME, skip_404=True)
Ejemplo n.º 15
0
def test_geoserver_bbox():
    workspace = 'test_geoserver_bbox_workspace'
    layer = 'test_geoserver_bbox_layer'
    expected_bbox_1 = test_data.SMALL_LAYER_BBOX
    crs = crs_def.EPSG_3857
    no_area_bbox_padding = crs_def.CRSDefinitions[crs].no_area_bbox_padding
    expected_bboxes = [
        ((1571203, 6268895, 1572589, 6269864), (1571203, 6268895, 1572589,
                                                6269864)),
        ((1571203, 6268895, 1571203, 6269864),
         (1571203 - no_area_bbox_padding, 6268895,
          1571203 + no_area_bbox_padding, 6269864)),  # line
        ((1571203, 6268895, 1571203, 6268895),
         (1571203 - no_area_bbox_padding, 6268895 - no_area_bbox_padding,
          1571203 + no_area_bbox_padding,
          6268895 + no_area_bbox_padding)),  # point
        ((None, None, None, None), crs_def.CRSDefinitions[crs].max_bbox),
    ]

    process_client.publish_workspace_layer(
        workspace, layer, style_file='sample/style/small_layer.qml')

    assert_util.assert_wfs_bbox(workspace, layer, expected_bbox_1)
    assert_util.assert_wms_bbox(workspace, layer, expected_bbox_1)

    kwargs = {
        'description': '',
        'title': layer,
        'access_rights': None,
    }

    # test WFS
    for bbox, expected_bbox in expected_bboxes:
        wfs.delete_layer(workspace, layer)
        with app.app_context():
            publications.set_bbox(
                workspace,
                process_client.LAYER_TYPE,
                layer,
                bbox,
                crs,
            )
            wfs.delete_layer(workspace, layer)
            tasks.refresh_wfs.apply(
                args=[workspace, layer],
                kwargs=kwargs,
            )
        assert_util.assert_wfs_bbox(workspace, layer, expected_bbox)

    # test WMS
    for bbox, expected_bbox in expected_bboxes:
        wms.delete_layer(workspace, layer)
        with app.app_context():
            publications.set_bbox(
                workspace,
                process_client.LAYER_TYPE,
                layer,
                bbox,
                crs,
            )
            tasks.refresh_wms.apply(
                args=[workspace, layer, True],
                kwargs=kwargs,
            )
        assert_util.assert_wms_bbox(workspace, layer, expected_bbox)

    # test cascade WMS from QGIS
    for bbox, expected_bbox in expected_bboxes:
        wms.delete_layer(workspace, layer)
        with app.app_context():
            publications.set_bbox(
                workspace,
                process_client.LAYER_TYPE,
                layer,
                bbox,
                crs,
            )
            wms.delete_layer(workspace, layer)
            tasks.refresh_wms.apply(
                args=[workspace, layer, False],
                kwargs=kwargs,
            )
        assert_util.assert_wms_bbox(workspace, layer, expected_bbox)

    process_client.delete_workspace_layer(workspace, layer)