Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
"""Tests for $geometry valid argument handling —
Comment thread
PatersonProjects marked this conversation as resolved.
valid structures, field ordering, and CRS."""

import pytest

from documentdb_tests.compatibility.tests.core.operator.query.utils.query_test_case import (
QueryTestCase,
)
from documentdb_tests.framework.assertions import assertSuccess
from documentdb_tests.framework.executor import execute_command
from documentdb_tests.framework.parametrize import pytest_params

STRICT_CRS = {
"type": "name",
"properties": {"name": "urn:x-mongodb:crs:strictwinding:EPSG:4326"},
}

VALID_GEOMETRY_TESTS: list[QueryTestCase] = [
QueryTestCase(
id="valid_point",
filter={"loc": {"$geoIntersects": {"$geometry": {"type": "Point", "coordinates": [0, 0]}}}},
doc=[{"_id": 1, "loc": {"type": "Point", "coordinates": [0, 0]}}],
expected=[{"_id": 1, "loc": {"type": "Point", "coordinates": [0, 0]}}],
msg="Should accept valid Point $geometry",
),
QueryTestCase(
id="extra_field_in_geometry",
filter={
"loc": {
"$geoIntersects": {
"$geometry": {"type": "Point", "coordinates": [0, 0], "extra": 1}
}
}
},
doc=[{"_id": 1, "loc": {"type": "Point", "coordinates": [0, 0]}}],
expected=[{"_id": 1, "loc": {"type": "Point", "coordinates": [0, 0]}}],
msg="Should ignore extra fields in $geometry",
),
QueryTestCase(
id="coordinates_before_type",
filter={"loc": {"$geoIntersects": {"$geometry": {"coordinates": [0, 0], "type": "Point"}}}},
doc=[{"_id": 1, "loc": {"type": "Point", "coordinates": [0, 0]}}],
expected=[{"_id": 1, "loc": {"type": "Point", "coordinates": [0, 0]}}],
msg="Should accept coordinates before type (field order doesn't matter)",
),
QueryTestCase(
id="array_value_as_legacy_coordinates",
filter={"loc": {"$geoIntersects": {"$geometry": [0, 0]}}},
doc=[
{"_id": 1, "loc": {"type": "Point", "coordinates": [0, 0]}},
{"_id": 2, "loc": {"type": "Point", "coordinates": [50, 50]}},
],
expected=[{"_id": 1, "loc": {"type": "Point", "coordinates": [0, 0]}}],
msg="$geometry: array value should be treated as a legacy coordinate pair",
),
QueryTestCase(
id="multiple_extra_fields",
filter={
"loc": {
"$geoIntersects": {
"$geometry": {
"type": "Point",
"coordinates": [1, 1],
"bbox": [-1, -1, 1, 1],
"id": "test",
"properties": {"name": "foo"},
}
}
}
},
doc=[
{"_id": 1, "loc": {"type": "Point", "coordinates": [1, 1]}},
{"_id": 2, "loc": {"type": "Point", "coordinates": [50, 50]}},
],
expected=[{"_id": 1, "loc": {"type": "Point", "coordinates": [1, 1]}}],
msg="Should ignore multiple extra fields (bbox, id, properties) in $geometry",
),
QueryTestCase(
id="crs_with_geoIntersects",
filter={
"loc": {
"$geoIntersects": {
"$geometry": {
"type": "Polygon",
"coordinates": [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]],
"crs": STRICT_CRS,
}
}
}
},
doc=[
{"_id": 1, "loc": {"type": "Point", "coordinates": [0.5, 0.5]}},
{"_id": 2, "loc": {"type": "Point", "coordinates": [5, 5]}},
],
expected=[{"_id": 1, "loc": {"type": "Point", "coordinates": [0.5, 0.5]}}],
msg="Should accept custom CRS with $geoIntersects",
),
]


@pytest.mark.parametrize("test", pytest_params(VALID_GEOMETRY_TESTS))
def test_geometry_argument_handling(collection, test):
"""Verifies $geometry accepts valid GeoJSON structures."""
collection.create_index([("loc", "2dsphere")])
collection.insert_many(test.doc)
result = execute_command(collection, {"find": collection.name, "filter": test.filter})
assertSuccess(result, test.expected, msg=test.msg)
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
"""Tests for $geometry valid coordinate boundary values — longitude/latitude limits,
poles, longitude non-equivalence at antimeridian, pole longitude equivalence,
origin, negative coordinates, and high-precision coordinates."""

import pytest

from documentdb_tests.compatibility.tests.core.operator.query.utils.query_test_case import (
QueryTestCase,
)
from documentdb_tests.framework.assertions import assertSuccess
from documentdb_tests.framework.executor import execute_command
from documentdb_tests.framework.parametrize import pytest_params

VALID_BOUNDARY_TESTS: list[QueryTestCase] = [
QueryTestCase(
id="longitude_negative_180",
filter={
"loc": {"$geoIntersects": {"$geometry": {"type": "Point", "coordinates": [-180, 0]}}}
},
doc=[
{"_id": 1, "loc": {"type": "Point", "coordinates": [-180, 0]}},
{"_id": 2, "loc": {"type": "Point", "coordinates": [0, 0]}},
],
expected=[{"_id": 1, "loc": {"type": "Point", "coordinates": [-180, 0]}}],
msg="Should accept longitude = -180",
),
QueryTestCase(
id="longitude_positive_180",
filter={
"loc": {"$geoIntersects": {"$geometry": {"type": "Point", "coordinates": [180, 0]}}}
},
doc=[
{"_id": 1, "loc": {"type": "Point", "coordinates": [180, 0]}},
{"_id": 2, "loc": {"type": "Point", "coordinates": [0, 0]}},
],
expected=[{"_id": 1, "loc": {"type": "Point", "coordinates": [180, 0]}}],
msg="Should accept longitude = 180",
),
QueryTestCase(
id="latitude_negative_90",
filter={
"loc": {"$geoIntersects": {"$geometry": {"type": "Point", "coordinates": [0, -90]}}}
},
doc=[
{"_id": 1, "loc": {"type": "Point", "coordinates": [0, -90]}},
{"_id": 2, "loc": {"type": "Point", "coordinates": [0, 0]}},
],
expected=[{"_id": 1, "loc": {"type": "Point", "coordinates": [0, -90]}}],
msg="Should accept latitude = -90",
),
QueryTestCase(
id="origin_zero_zero",
filter={"loc": {"$geoIntersects": {"$geometry": {"type": "Point", "coordinates": [0, 0]}}}},
doc=[
{"_id": 1, "loc": {"type": "Point", "coordinates": [0, 0]}},
{"_id": 2, "loc": {"type": "Point", "coordinates": [45, 45]}},
],
expected=[{"_id": 1, "loc": {"type": "Point", "coordinates": [0, 0]}}],
msg="Should accept coordinates at origin (0, 0)",
),
QueryTestCase(
id="negative_coordinates",
filter={
"loc": {"$geoIntersects": {"$geometry": {"type": "Point", "coordinates": [-45, -45]}}}
},
doc=[
{"_id": 1, "loc": {"type": "Point", "coordinates": [-45, -45]}},
{"_id": 2, "loc": {"type": "Point", "coordinates": [45, 45]}},
],
expected=[{"_id": 1, "loc": {"type": "Point", "coordinates": [-45, -45]}}],
msg="Should accept negative longitude and latitude",
),
QueryTestCase(
id="lng_180_does_not_match_negative_180",
filter={
"loc": {"$geoIntersects": {"$geometry": {"type": "Point", "coordinates": [180, 0]}}}
},
doc=[
{"_id": 1, "loc": {"type": "Point", "coordinates": [-180, 0]}},
{"_id": 2, "loc": {"type": "Point", "coordinates": [180, 0]}},
],
expected=[{"_id": 2, "loc": {"type": "Point", "coordinates": [180, 0]}}],
msg="Longitude 180 and -180 should not be treated as equivalent (strict numeric)",
),
QueryTestCase(
id="north_pole_any_longitude",
filter={
"loc": {"$geoIntersects": {"$geometry": {"type": "Point", "coordinates": [0, 90]}}}
},
doc=[
{"_id": 1, "loc": {"type": "Point", "coordinates": [0, 90]}},
{"_id": 2, "loc": {"type": "Point", "coordinates": [180, 90]}},
{"_id": 3, "loc": {"type": "Point", "coordinates": [-90, 90]}},
{"_id": 4, "loc": {"type": "Point", "coordinates": [0, 0]}},
],
expected=[
{"_id": 1, "loc": {"type": "Point", "coordinates": [0, 90]}},
{"_id": 2, "loc": {"type": "Point", "coordinates": [180, 90]}},
{"_id": 3, "loc": {"type": "Point", "coordinates": [-90, 90]}},
],
msg="At the North Pole (lat=90), longitude is irrelevant — all pole points should match",
),
QueryTestCase(
id="high_precision_coordinates",
filter={
"loc": {
"$geoIntersects": {
"$geometry": {
"type": "Point",
"coordinates": [1.123456789012345, 2.123456789012345],
}
}
}
},
doc=[
{
"_id": 1,
"loc": {"type": "Point", "coordinates": [1.123456789012345, 2.123456789012345]},
},
],
expected=[
{
"_id": 1,
"loc": {"type": "Point", "coordinates": [1.123456789012345, 2.123456789012345]},
},
],
msg="Should accept high-precision coordinates (15+ decimal places)",
),
]


@pytest.mark.parametrize("test", pytest_params(VALID_BOUNDARY_TESTS))
def test_geometry_coordinate_boundaries(collection, test):
"""Verifies $geometry accepts coordinates at valid boundary values."""
collection.create_index([("loc", "2dsphere")])
collection.insert_many(test.doc)
result = execute_command(collection, {"find": collection.name, "filter": test.filter})
assertSuccess(result, test.expected, msg=test.msg, ignore_doc_order=True)
Loading
Loading