Files
grecia/spec/models/geojson_format_validator_spec.rb
Javi Martín d18c627392 Add and apply Layout/EmptyLinesAfterModuleInclusion rule
This rule was added in rubocop 1.79. We were inconsistent about it, so
we're adding it to get more consistency.
2025-11-05 14:27:12 +01:00

610 lines
15 KiB
Ruby

require "rails_helper"
describe GeojsonFormatValidator do
before do
dummy_model = Class.new do
include ActiveModel::Model
attr_accessor :geojson
validates :geojson, geojson_format: true
end
stub_const("DummyModel", dummy_model)
end
let(:record) { DummyModel.new }
it "is not valid with an empty hash" do
record.geojson = "{}"
expect(record).not_to be_valid
end
it "is not valid with arbitrary keys" do
record.geojson = '{ "invalid": "yes" }'
expect(record).not_to be_valid
end
it "is not valid without a type" do
record.geojson = '{ "coordinates": [1.23, 4.56] }'
expect(record).not_to be_valid
end
it "is not valid without a type but a geometry" do
record.geojson = '{ "geometry": { "type": "Point", "coordinates": [1.23, 4.56] } }'
expect(record).not_to be_valid
end
context "Point geometry" do
it "is not valid without coordinates" do
record.geojson = '{ "type": "Point" }'
expect(record).not_to be_valid
end
it "is not valid with only one the longitude" do
record.geojson = '{ "type": "Point", "coordinates": 1.23 }'
expect(record).not_to be_valid
end
it "is not valid with non-numerical coordinates" do
record.geojson = '{ "type": "Point", "coordinates": ["1.23", "4.56"] }'
expect(record).not_to be_valid
end
it "is not valid with 3-dimensional coordinates" do
record.geojson = '{ "type": "Point", "coordinates": [1.23, 4.56, 7.89] }'
expect(record).not_to be_valid
end
it "is not valid with multiple coordinates" do
record.geojson = '{ "type": "Point", "coordinates": [[1.23, 4.56], [7.89, 10.11]] }'
expect(record).not_to be_valid
end
it "is not valid with a longitude above 180" do
record.geojson = '{ "type": "Point", "coordinates": [180.01, 4.56] }'
expect(record).not_to be_valid
end
it "is not valid with a longitude below -180" do
record.geojson = '{ "type": "Point", "coordinates": [-180.01, 4.56] }'
expect(record).not_to be_valid
end
it "is not valid with a latitude above 90" do
record.geojson = '{ "type": "Point", "coordinates": [1.23, 90.01] }'
expect(record).not_to be_valid
end
it "is not valid with a latitude below -90" do
record.geojson = '{ "type": "Point", "coordinates": [1.23, -90.01] }'
expect(record).not_to be_valid
end
it "is valid with coordinates in the valid range" do
record.geojson = '{ "type": "Point", "coordinates": [1.23, 4.56] }'
expect(record).to be_valid
end
it "is valid with coordinates at the positive end of the range" do
record.geojson = '{ "type": "Point", "coordinates": [180.0, 90.0] }'
expect(record).to be_valid
end
it "is valid with coordinates at the negative end of the range" do
record.geojson = '{ "type": "Point", "coordinates": [-180.0, -90.0] }'
expect(record).to be_valid
end
end
context "LineString or MultiPoint geometry" do
it "is not valid with a one-dimensional array of coordinates" do
record.geojson = '{ "type": "LineString", "coordinates": [1.23, 4.56] }'
expect(record).not_to be_valid
record.geojson = '{ "type": "MultiPoint", "coordinates": [1.23, 4.56] }'
expect(record).not_to be_valid
end
it "is not valid when some coordinates are invalid" do
record.geojson = '{ "type": "LineString", "coordinates": [[1.23, 4.56], [180.01, 4.56]] }'
expect(record).not_to be_valid
record.geojson = '{ "type": "MultiPoint", "coordinates": [[1.23, 4.56], [180.01, 4.56]] }'
expect(record).not_to be_valid
end
it "is valid when all the coordinates are valid" do
record.geojson = '{ "type": "LineString", "coordinates": [[1.23, 4.56], [7.89, 4.56]] }'
expect(record).to be_valid
record.geojson = '{ "type": "MultiPoint", "coordinates": [[1.23, 4.56], [7.89, 4.56]] }'
expect(record).to be_valid
end
end
context "LineString geometry" do
it "is not valid with only one point" do
record.geojson = '{ "type": "LineString", "coordinates": [[1.23, 4.56]] }'
expect(record).not_to be_valid
end
end
context "MultiPoint geometry" do
it "is valid with only one point" do
record.geojson = '{ "type": "MultiPoint", "coordinates": [[1.23, 4.56]] }'
expect(record).to be_valid
end
end
context "Polygon or MultiLineString geometry" do
it "is not valid with a one-dimensional array of coordinates" do
record.geojson = '{ "type": "MultiLineString", "coordinates": [1.23, 4.56] }'
expect(record).not_to be_valid
record.geojson = '{ "type": "Polygon", "coordinates": [1.23, 4.56] }'
expect(record).not_to be_valid
end
it "is not valid with a two-dimensional array of coordinates" do
record.geojson = '{ "type": "MultiLineString", "coordinates": [[1.23, 4.56], [7.89, 4.56]] }'
expect(record).not_to be_valid
record.geojson = '{ "type": "Polygon", "coordinates": [[1.23, 4.56], [7.89, 4.56]] }'
expect(record).not_to be_valid
end
end
context "MultiLineString geometry" do
it "is valid with just one line" do
record.geojson = '{ "type": "MultiLineString", "coordinates": [[[1.23, 4.56], [7.89, 4.56]]] }'
expect(record).to be_valid
end
it "is valid with multiple valid lines" do
record.geojson = <<~JSON
{
"type": "MultiLineString",
"coordinates": [
[[1.23, 4.56], [7.89, 4.56]],
[[10.11, 12.13], [14.15, 16.17]]
]
}
JSON
expect(record).to be_valid
end
it "is not valid if some lines are invalid" do
record.geojson = <<~JSON
{
"type": "MultiLineString",
"coordinates": [
[[1.23, 4.56], [7.89, 4.56]],
[[10.11, 12.13]]
]
}
JSON
expect(record).not_to be_valid
end
end
context "Polygon geometry" do
it "is not valid with a ring having less than four elements" do
record.geojson = <<~JSON
{
"type": "Polygon",
"coordinates": [[
[1.23, 4.56],
[7.89, 10.11],
[1.23, 4.56]
]]
}
JSON
expect(record).not_to be_valid
end
it "is not valid with a ring which with different starting and end points" do
record.geojson = <<~JSON
{
"type": "Polygon",
"coordinates": [[
[1.23, 4.56],
[7.89, 10.11],
[12.13, 14.15],
[16.17, 18.19]
]]
}
JSON
expect(record).not_to be_valid
end
it "is valid with one valid ring" do
record.geojson = <<~JSON
{
"type": "Polygon",
"coordinates": [[
[1.23, 4.56],
[7.89, 10.11],
[12.13, 14.15],
[1.23, 4.56]
]]
}
JSON
expect(record).to be_valid
end
it "is valid with multiple valid rings" do
record.geojson = <<~JSON
{
"type": "Polygon",
"coordinates": [
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
],
[
[100.8, 0.8],
[100.8, 0.2],
[100.2, 0.2],
[100.2, 0.8],
[100.8, 0.8]
]
]
}
JSON
expect(record).to be_valid
end
it "is not valid with multiple rings if some rings are invalid" do
record.geojson = <<~JSON
{
"type": "Polygon",
"coordinates": [
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
],
[
[100.8, 0.8],
[100.8, 0.2],
[100.2, 0.2]
]
]
}
JSON
expect(record).not_to be_valid
end
end
context "MultiPolygon geometry" do
it "is not valid with a one-dimensional array of coordinates" do
record.geojson = '{ "type": "MultiPolygon", "coordinates": [1.23, 4.56] }'
expect(record).not_to be_valid
end
it "is not valid with a two-dimensional array of coordinates" do
record.geojson = '{ "type": "MultiPolygon", "coordinates": [[1.23, 4.56], [7.89, 4.56]] }'
expect(record).not_to be_valid
end
it "is not valid with a three-dimensional polygon coordinates array" do
record.geojson = <<~JSON
{
"type": "MultiPolygon",
"coordinates": [[
[1.23, 4.56],
[7.89, 10.11],
[12.13, 14.15],
[1.23, 4.56]
]]
}
JSON
expect(record).not_to be_valid
end
it "is valid with a valid polygon" do
record.geojson = <<~JSON
{
"type": "MultiPolygon",
"coordinates": [[[
[1.23, 4.56],
[7.89, 10.11],
[12.13, 14.15],
[1.23, 4.56]
]]]
}
JSON
expect(record).to be_valid
end
it "is valid with multiple valid polygons" do
record.geojson = <<~JSON
{
"type": "MultiPolygon",
"coordinates": [
[
[
[1.23, 4.56],
[7.89, 10.11],
[12.13, 14.15],
[1.23, 4.56]
]
],
[
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
],
[
[100.8, 0.8],
[100.8, 0.2],
[100.2, 0.2],
[100.2, 0.8],
[100.8, 0.8]
]
]
]
}
JSON
expect(record).to be_valid
end
it "is not valid with multiple polygons if some polygons are invalid" do
record.geojson = <<~JSON
{
"type": "MultiPolygon",
"coordinates": [
[
[
[1.23, 4.56],
[7.89, 10.11],
[12.13, 14.15],
[1.23, 4.56]
]
],
[
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
],
[
[100.8, 0.8],
[100.8, 0.2],
[100.2, 0.2]
]
]
]
}
JSON
expect(record).not_to be_valid
end
end
context "GeometryCollection" do
it "is not valid if it doesn't contain geometries" do
record.geojson = '{ "type": "GeometryCollection" }'
expect(record).not_to be_valid
end
it "is not valid if geometries is not an array" do
record.geojson = <<~JSON
{
"type": "GeometryCollection",
"geometries": { "type": "Point", "coordinates": [1.23, 4.56] }
}
JSON
expect(record).not_to be_valid
end
it "is valid if the array of geometries is empty" do
record.geojson = '{ "type": "GeometryCollection", "geometries": [] }'
expect(record).to be_valid
end
it "is valid if all geometries are valid" do
record.geojson = <<~JSON
{
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"coordinates": [100.0, 0.0]
},
{
"type": "LineString",
"coordinates": [
[101.0, 0.0],
[102.0, 1.0]
]
}
]
}
JSON
expect(record).to be_valid
end
it "is not valid if some geometries are invalid" do
record.geojson = <<~JSON
{
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"coordinates": [100.0, 0.0]
},
{
"type": "LineString",
"coordinates": [101.0, 0.0]
}
]
}
JSON
expect(record).not_to be_valid
end
end
context "Feature" do
it "is valid with a valid geometry" do
record.geojson = <<~JSON
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [1.23, 4.56]
}
}
JSON
expect(record).to be_valid
end
it "is not valid with a valid geometry" do
record.geojson = <<~JSON
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [1.23]
}
}
JSON
expect(record).not_to be_valid
end
end
context "FeatureCollection" do
it "is not valid without features" do
record.geojson = '{ "type": "FeatureCollection" }'
end
it "is not valid if features is not an array" do
record.geojson = <<~JSON
{
"type": "FeatureCollection",
"features": {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [1.23, 4.56]
}
}
}
JSON
end
it "is valid if the array of features is empty" do
record.geojson = '{ "type": "FeatureCollection", "features": [] }'
expect(record).to be_valid
end
it "is valid if all features are valid" do
record.geojson = <<~JSON
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [1.23, 4.56]
}
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [[101.0, 0.0], [102.0, 1.0]]
}
}
]
}
JSON
expect(record).to be_valid
end
it "is not valid if some features are invalid" do
record.geojson = <<~JSON
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [1.23, 4.56]
}
},
{
"type": "LineString",
"coordinates": [[101.0, 0.0], [102.0, 1.0]]
}
]
}
JSON
expect(record).not_to be_valid
end
end
end