File: test_grid.py

package info (click to toggle)
pystac 1.13.0-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 19,904 kB
  • sloc: python: 24,370; makefile: 124; sh: 7
file content (173 lines) | stat: -rw-r--r-- 5,706 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
"""Tests for pystac.extensions.grid."""

# This is for the type checking on GridTest.test_clear_code
# mypy: warn_unused_ignores=False

from datetime import datetime
from typing import Any

import pytest

import pystac
from pystac import ExtensionTypeError
from pystac.extensions import grid
from pystac.extensions.grid import GridExtension
from tests.conftest import get_data_file
from tests.utils import TestCases

code = "MGRS-4CFJ"


@pytest.fixture
def sentinel2_example_item() -> pystac.Item:
    return pystac.Item.from_file(
        TestCases.get_path("data-files/grid/example-sentinel2.json")
    )


@pytest.fixture
def item() -> pystac.Item:
    """Create basic test items that are only slightly different."""
    asset_id = "an/asset"
    start = datetime(2018, 1, 2)
    item = pystac.Item(
        id=asset_id, geometry=None, bbox=None, datetime=start, properties={}
    )

    GridExtension.add_to(item)
    return item


def test_stac_extensions(item: pystac.Item) -> None:
    assert GridExtension.has_extension(item)


def test_item_repr(item: pystac.Item) -> None:
    grid_item_ext = GridExtension.ext(item)
    assert f"<ItemGridExtension Item id={item.id}>" == grid_item_ext.__repr__()


@pytest.mark.vcr()
def test_attributes(item: pystac.Item) -> None:
    GridExtension.ext(item).apply(code)
    assert code == GridExtension.ext(item).code
    item.validate()


def test_invalid_code_value(item: pystac.Item) -> None:
    with pytest.raises(ValueError):
        GridExtension.ext(item).apply("not_a_valid_code")


@pytest.mark.vcr()
def test_modify(item: pystac.Item) -> None:
    GridExtension.ext(item).apply(code)
    GridExtension.ext(item).apply(code + "a")
    assert code + "a" == GridExtension.ext(item).code
    item.validate()


def test_from_dict() -> None:
    d: dict[str, Any] = {
        "type": "Feature",
        "stac_version": "1.1.0",
        "id": "an/asset",
        "properties": {
            "grid:code": code,
            "datetime": "2018-01-02T00:00:00Z",
        },
        "geometry": None,
        "links": [],
        "assets": {},
        "stac_extensions": [GridExtension.get_schema_uri()],
    }
    item = pystac.Item.from_dict(d)
    assert code == GridExtension.ext(item).code


def test_to_from_dict(item: pystac.Item) -> None:
    GridExtension.ext(item).apply(code)
    d = item.to_dict()
    assert code == d["properties"][grid.CODE_PROP]

    item = pystac.Item.from_dict(d)
    assert code == GridExtension.ext(item).code


def test_clear_code(item: pystac.Item) -> None:
    GridExtension.ext(item).apply(code)

    with pytest.raises(ValueError):
        # Ignore type errors because this test intentionally checks behavior
        # that does not conform to the type signature.
        # https://github.com/stac-utils/pystac/pull/878#discussion_r957352232
        GridExtension.ext(item).code = None  # type: ignore
    with pytest.raises(ValueError):
        # First segment has to be all caps
        # https://github.com/stac-utils/pystac/pull/878#discussion_r957354927
        GridExtension.ext(item).code = "this-is-not-a-grid-code"
    with pytest.raises(ValueError):
        # Folks might try to put an epsg code in
        # https://github.com/stac-utils/pystac/pull/878#discussion_r957355415
        GridExtension.ext(item).code = "4326"
    with pytest.raises(ValueError):
        # Folks might try to put an epsg code in
        # https://github.com/stac-utils/pystac/pull/878#discussion_r957355415
        GridExtension.ext(item).code = "EPSG:4326"


def test_extension_not_implemented(sentinel2_example_item: pystac.Item) -> None:
    # Should raise exception if Item does not include extension URI
    item = sentinel2_example_item
    item.stac_extensions.remove(GridExtension.get_schema_uri())

    with pytest.raises(pystac.ExtensionNotImplemented):
        _ = GridExtension.ext(item)

    # Should raise exception if owning Item does not include extension URI
    item.properties["grid:code"] = None

    with pytest.raises(pystac.ExtensionNotImplemented):
        _ = GridExtension.ext(item)


def test_item_ext_add_to(sentinel2_example_item: pystac.Item) -> None:
    item = sentinel2_example_item
    item.stac_extensions.remove(GridExtension.get_schema_uri())
    assert GridExtension.get_schema_uri() not in item.stac_extensions

    _ = GridExtension.ext(item, add_if_missing=True)

    assert GridExtension.get_schema_uri() in item.stac_extensions


def test_should_raise_when_passing_invalid_extension_object() -> None:
    with pytest.raises(
        ExtensionTypeError, match=r"^GridExtension does not apply to type 'object'$"
    ):
        # intentionally calling it wrong so tell mypy to ignore this line:
        GridExtension.ext(object())  # type: ignore


@pytest.fixture
def ext_item() -> pystac.Item:
    ext_item_uri = get_data_file("grid/example-sentinel2.json")
    return pystac.Item.from_file(ext_item_uri)


def test_older_extension_version(ext_item: pystac.Item) -> None:
    old = "https://stac-extensions.github.io/grid/v1.0.0/schema.json"
    new = "https://stac-extensions.github.io/grid/v1.1.0/schema.json"

    stac_extensions = set(ext_item.stac_extensions)
    stac_extensions.remove(new)
    stac_extensions.add(old)
    item_as_dict = ext_item.to_dict(include_self_link=False, transform_hrefs=False)
    item_as_dict["stac_extensions"] = list(stac_extensions)
    item = pystac.Item.from_dict(item_as_dict, migrate=False)
    assert GridExtension.has_extension(item)
    assert old in item.stac_extensions

    migrated_item = pystac.Item.from_dict(item_as_dict, migrate=True)
    assert GridExtension.has_extension(migrated_item)
    assert new in migrated_item.stac_extensions