martin 1.6.0

Blazing fast and lightweight tile server with PostGIS, MBTiles, and PMTiles support
Documentation
#![cfg(feature = "test-pg")]

use indoc::indoc;
use insta::assert_yaml_snapshot;
use martin_tile_utils::TileCoord;
pub mod utils;
pub use utils::*;

#[actix_rt::test]
async fn table_source() {
    let mock = mock_sources(mock_pgcfg("connection_string: $DATABASE_URL")).await;
    insta::with_settings!({sort_maps => true}, {
    assert_yaml_snapshot!(mock.0.tile_manager.tile_sources().get_catalog(), @r#"
    "-function.withweired---_-characters":
      content_type: application/x-protobuf
      description: a function source with special characters
    ".-Points-----------quote":
      content_type: application/x-protobuf
      description: Escaping test table
    MixPoints:
      content_type: application/x-protobuf
      description: a description from comment on table
    antimeridian:
      content_type: application/x-protobuf
      description: public.antimeridian.geom
    auto_table:
      content_type: application/x-protobuf
      description: autodetect.auto_table.geom
    bigint_table:
      content_type: application/x-protobuf
      description: autodetect.bigint_table.geom
    empty_bounds:
      content_type: application/x-protobuf
      description: public.empty_bounds.geom
    function_Mixed_Name:
      content_type: application/x-protobuf
      description: a function source with MixedCase name
    function_null:
      content_type: application/x-protobuf
      description: public.function_null
    function_null_row:
      content_type: application/x-protobuf
      description: public.function_null_row
    function_null_row2:
      content_type: application/x-protobuf
      description: public.function_null_row2
    function_zoom_xy:
      content_type: application/x-protobuf
      description: public.function_zoom_xy
    function_zxy:
      content_type: application/x-protobuf
      description: public.function_zxy
    function_zxy2:
      content_type: application/x-protobuf
      description: public.function_zxy2
    function_zxy_query:
      content_type: application/x-protobuf
    function_zxy_query_jsonb:
      content_type: application/x-protobuf
      description: public.function_zxy_query_jsonb
    function_zxy_query_test:
      content_type: application/x-protobuf
      description: public.function_zxy_query_test
    function_zxy_row:
      content_type: application/x-protobuf
      description: public.function_zxy_row
    function_zxy_row_key:
      content_type: application/x-protobuf
      description: public.function_zxy_row_key
    linestring_bounds:
      content_type: application/x-protobuf
      description: public.linestring_bounds.geom
    linestring_bounds_vertical:
      content_type: application/x-protobuf
      description: public.linestring_bounds_vertical.geom
    point_bounds:
      content_type: application/x-protobuf
      description: public.point_bounds.geom
    points1:
      content_type: application/x-protobuf
      description: public.points1.geom
    points1_vw:
      content_type: application/x-protobuf
      description: description from SQL comment
      attribution: some attribution from SQL comment
    points2:
      content_type: application/x-protobuf
      description: public.points2.geom
    points3857:
      content_type: application/x-protobuf
      description: public.points3857.geom
    table_name_existing_two_schemas:
      content_type: application/x-protobuf
      description: schema_a.table_name_existing_two_schemas.a_geom
    table_name_existing_two_schemas.1:
      content_type: application/x-protobuf
      description: schema_b.table_name_existing_two_schemas.b_geom
    table_source:
      content_type: application/x-protobuf
    table_source_geog:
      content_type: application/x-protobuf
    table_source_multiple_geom:
      content_type: application/x-protobuf
      description: public.table_source_multiple_geom.geom1
    table_source_multiple_geom.1:
      content_type: application/x-protobuf
      description: public.table_source_multiple_geom.geom2
    view_name_existing_two_schemas:
      content_type: application/x-protobuf
      description: schema_a.view_name_existing_two_schemas.a_geom
    view_name_existing_two_schemas.1:
      content_type: application/x-protobuf
      description: schema_b.view_name_existing_two_schemas.b_geom
    "#);
    });

    let source = table(&mock, "table_source");
    assert_yaml_snapshot!(source, @r"
    schema: public
    table: table_source
    srid: 4326
    geometry_column: geom
    bounds:
      - -2
      - -1
      - 142.84131509869133
      - 45
    geometry_type: GEOMETRY
    properties:
      gid: int4
    ");

    let source2 = table(&mock, "table_source_geog");
    assert_yaml_snapshot!(source2, @r"
    schema: public
    table: table_source_geog
    srid: 4326
    geometry_column: geog
    bounds:
      - -2
      - 0
      - 142.84131509869133
      - 45
    geometry_type: Geometry
    properties:
      gid: int4
    ");

    let source3 = table(&mock, "points3857");
    assert_yaml_snapshot!(source3, @r"
    schema: public
    table: points3857
    srid: 3857
    geometry_column: geom
    bounds:
      - -161.40590777554058
      - -81.50727021609012
      - 172.51549126768532
      - 84.2440187164111
    geometry_type: POINT
    properties:
      gid: int4
    ");
}

#[actix_rt::test]
async fn tables_tilejson() {
    let mock = mock_sources(mock_pgcfg("connection_string: $DATABASE_URL")).await;
    let src = source(&mock, "table_source");
    assert_yaml_snapshot!(src.get_tilejson(), @r"
    tilejson: 3.0.0
    tiles: []
    vector_layers:
      - id: table_source
        fields:
          gid: int4
    bounds:
      - -2
      - -1
      - 142.84131509869133
      - 45
    name: table_source
    foo:
      bar: foo
    ");
}

#[actix_rt::test]
async fn tables_tile_ok() {
    let mock = mock_sources(mock_pgcfg("connection_string: $DATABASE_URL")).await;
    let tile = source(&mock, "table_source")
        .get_tile(TileCoord { z: 0, x: 0, y: 0 }, None)
        .await
        .unwrap();

    assert!(!tile.is_empty());
}

#[actix_rt::test]
async fn tables_srid_ok() {
    let mock = mock_sources(mock_pgcfg(indoc! {"
        connection_string: $DATABASE_URL
        default_srid: 900913
    "}))
    .await;

    let source = table(&mock, "points1");
    assert_eq!(source.srid, 4326);

    let source = table(&mock, "points2");
    assert_eq!(source.srid, 4326);

    let source = table(&mock, "points3857");
    assert_eq!(source.srid, 3857);

    let source = table(&mock, "points_empty_srid");
    assert_eq!(source.srid, 900_913);
}

#[actix_rt::test]
async fn tables_multiple_geom_ok() {
    let mock = mock_sources(mock_pgcfg("connection_string: $DATABASE_URL")).await;

    let source = table(&mock, "table_source_multiple_geom");
    assert_eq!(source.geometry_column, "geom1");

    let source = table(&mock, "table_source_multiple_geom.1");
    assert_eq!(source.geometry_column, "geom2");
}

#[actix_rt::test]
async fn table_source_schemas() {
    let cfg = mock_pgcfg(indoc! {"
        connection_string: $DATABASE_URL
        auto_publish:
          tables:
            from_schemas: MixedCase
          functions: false
    "});
    let sources = mock_sources(cfg).await.0;
    assert_yaml_snapshot!(sources.tile_manager.tile_sources().get_catalog(), @r"
    MixPoints:
      content_type: application/x-protobuf
      description: a description from comment on table
    ");
}

#[actix_rt::test]
async fn table_bounds_linestring_horizontal_ok() {
    let mock = mock_sources(mock_pgcfg("connection_string: $DATABASE_URL")).await;
    let source = table(&mock, "linestring_bounds");
    assert_yaml_snapshot!(source, @r"
    schema: public
    table: linestring_bounds
    srid: 4326
    geometry_column: geom
    bounds:
      - 8.9581704
      - 9.0370178
      - 10.9675324
      - 11.0370178
    geometry_type: GEOMETRY
    properties:
      gid: int4
    ");
}

#[actix_rt::test]
async fn table_bounds_linestring_vertical_ok() {
    let mock = mock_sources(mock_pgcfg("connection_string: $DATABASE_URL")).await;
    let source = table(&mock, "linestring_bounds_vertical");
    assert_yaml_snapshot!(source, @r"
    schema: public
    table: linestring_bounds_vertical
    srid: 4326
    geometry_column: geom
    bounds:
      - 9
      - 8.9581704
      - 11
      - 10.9675324
    geometry_type: GEOMETRY
    properties:
      gid: int4
    ");
}

#[actix_rt::test]
async fn table_bounds_single_point_ok() {
    let mock = mock_sources(mock_pgcfg("connection_string: $DATABASE_URL")).await;
    let source = table(&mock, "point_bounds");
    assert_yaml_snapshot!(source, @r"
    schema: public
    table: point_bounds
    srid: 4326
    geometry_column: geom
    bounds:
      - 9
      - 19
      - 11
      - 21
    geometry_type: GEOMETRY
    properties:
      gid: int4
    ");
}

#[actix_rt::test]
async fn table_bounds_empty_table_ok() {
    let mock = mock_sources(mock_pgcfg("connection_string: $DATABASE_URL")).await;
    let source = table(&mock, "empty_bounds");
    assert_yaml_snapshot!(source, @r"
    schema: public
    table: empty_bounds
    srid: 4326
    geometry_column: geom
    geometry_type: GEOMETRY
    properties:
      gid: int4
    ");
}