def test_validate_item_collection(self): sv = SchemaValidator() ic_1 = ItemCollection([]) sv.validate_object(ic_1) sv.validate_dict(self.IC_DICT, STACObjectType.ITEMCOLLECTION) ic_2 = ItemCollection.from_file(self.IC_URI) ic_val_dict = ic_2.to_dict() ic_val_dict['features'] = 'not an array' with self.assertRaises(STACValidationError): sv.validate_dict(ic_val_dict, STACObjectType.ITEMCOLLECTION)
def test_validate_item_collection(self): sv = SchemaValidator() ic_1 = ItemCollection([]) sv.validate_object(ic_1) sv.validate_dict(self.IC_DICT, ItemCollection) ic_2 = ItemCollection.from_file(self.IC_URI) ic_val_dict = ic_2.to_dict() ic_val_dict['features'] = 'not an array' with self.assertRaises(ValidationError): print('[Validation error expected] - ', end='') sv.validate_dict(ic_val_dict, ItemCollection)
def test_validate_single_file(self): sv = SchemaValidator() sv.validate_dict(self.EXAMPLE_SF_DICT, SingleFileSTAC) sf_from_file = SingleFileSTAC.from_file(self.EXAMPLE_SINGLE_FILE) sv.validate_object(sf_from_file) with TemporaryDirectory() as tmp_dir: tmp_uri = join(tmp_dir, 'test-single-file-val.json') sf_from_file.save(tmp_uri) with open(tmp_uri) as f: val_dict = json.load(f) sv.validate_dict(val_dict, SingleFileSTAC) val_dict['search']['endpoint'] = 1 with self.assertRaises(ValidationError): print('[Validation error expected] - ', end='') sv.validate_dict(val_dict, SingleFileSTAC)
class CommonsTest(unittest.TestCase): def setUp(self): self.validator = SchemaValidator() self.maxDiff = None def test_reads_common_metadata_if_enabled(self): # Test reading from collection collection = pystac.read_file( TestCases.get_path('data-files/commons/example-collection-with-commons.json')) self.assertTrue(collection.ext.implements(pystac.Extensions.COMMONS)) item = collection.get_item("item-with") self.assertTrue(item.ext.implements(pystac.Extensions.COMMONS)) self.assertTrue(item.ext.implements(pystac.Extensions.EO)) self.validator.validate_object(item) # Test reading item directly item2 = pystac.read_file( TestCases.get_path('data-files/commons/example-item-with-commons.json')) self.assertTrue(item2.ext.implements(pystac.Extensions.COMMONS)) self.assertTrue(item2.ext.implements(pystac.Extensions.EO)) self.validator.validate_object(item2) def test_doesnt_common_metadata_if_not_enabled(self): # Test reading from collection collection = pystac.read_file( TestCases.get_path('data-files/commons/example-collection-without-commons.json')) self.assertFalse(collection.ext.implements(pystac.Extensions.COMMONS)) item = collection.get_item("item-without") self.assertFalse(item.ext.implements(pystac.Extensions.COMMONS)) self.assertTrue(item.ext.implements(pystac.Extensions.EO)) # Should fail since required EO properties weren't inherited. with self.assertRaises(STACValidationError): self.validator.validate_object(item) # Test reading item directly item2 = pystac.read_file( TestCases.get_path('data-files/commons/example-item-without-commons.json')) self.assertFalse(item2.ext.implements(pystac.Extensions.COMMONS)) self.assertTrue(item2.ext.implements(pystac.Extensions.EO)) with self.assertRaises(STACValidationError): self.validator.validate_object(item2)
def test_validate_label(self): sv = SchemaValidator() with open(self.label_example_1_uri) as f: label_example_1_dict = json.load(f) sv.validate_dict(label_example_1_dict, LabelItem) with TemporaryDirectory() as tmp_dir: cat_dir = os.path.join(tmp_dir, 'catalog') catalog = TestCases.test_case_1() label_item = LabelItem.from_dict(label_example_1_dict) catalog.add_item(label_item) catalog.normalize_and_save(cat_dir, catalog_type=CatalogType.SELF_CONTAINED) cat_read = Catalog.from_file(os.path.join(cat_dir, 'catalog.json')) label_item_read = cat_read.get_item("label-example-1-label-item") sv = SchemaValidator() sv.validate_object(label_item_read)
def test_validate_eo(self): sv = SchemaValidator() self.assertIsNone(sv.validate_dict(self.eo_dict, EOItem)) with open(self.URI_2) as f: eo_dict_2 = json.load(f) with self.assertRaises(ValidationError): print('[Validation error expected] - ', end='') sv.validate_dict(eo_dict_2, EOItem) with TemporaryDirectory() as tmp_dir: cat_dir = os.path.join(tmp_dir, 'catalog') catalog = TestCases.test_case_1() eo_item = EOItem.from_dict(self.eo_dict) catalog.add_item(eo_item) catalog.normalize_and_save(cat_dir, catalog_type=CatalogType.ABSOLUTE_PUBLISHED) cat_read = Catalog.from_file(os.path.join(cat_dir, 'catalog.json')) eo_item_read = cat_read.get_item("LC08_L1TP_107018_20181001_20181001_01_RT") sv = SchemaValidator() sv.validate_object(eo_item_read) sv.validate_dict(eo_item_read.to_dict(), EOItem)
class ViewTest(unittest.TestCase): def setUp(self): self.validator = SchemaValidator() self.maxDiff = None self.example_uri = TestCases.get_path( 'data-files/view/example-landsat8.json') def test_to_from_dict(self): with open(self.example_uri) as f: d = json.load(f) test_to_from_dict(self, Item, d) def test_apply(self): item = next(TestCases.test_case_2().get_all_items()) with self.assertRaises(ExtensionError): item.ext.view item.ext.enable(Extensions.VIEW) item.ext.view.apply(off_nadir=1.0, incidence_angle=2.0, azimuth=3.0, sun_azimuth=2.0, sun_elevation=1.0) def test_validate_view(self): item = pystac.read_file(self.example_uri) self.validator.validate_object(item) def test_off_nadir(self): view_item = pystac.read_file(self.example_uri) # Get self.assertIn("view:off_nadir", view_item.properties) view_off_nadir = view_item.ext.view.off_nadir self.assertEqual(view_off_nadir, view_item.properties['view:off_nadir']) # Set view_item.ext.view.off_nadir = view_off_nadir + 100 self.assertEqual(view_off_nadir + 100, view_item.properties['view:off_nadir']) self.validator.validate_object(view_item) def test_incidence_angle(self): view_item = pystac.read_file(self.example_uri) # Get self.assertIn("view:incidence_angle", view_item.properties) view_incidence_angle = view_item.ext.view.incidence_angle self.assertEqual(view_incidence_angle, view_item.properties['view:incidence_angle']) # Set view_item.ext.view.incidence_angle = view_incidence_angle + 100 self.assertEqual(view_incidence_angle + 100, view_item.properties['view:incidence_angle']) self.validator.validate_object(view_item) def test_azimuth(self): view_item = pystac.read_file(self.example_uri) # Get self.assertIn("view:azimuth", view_item.properties) view_azimuth = view_item.ext.view.azimuth self.assertEqual(view_azimuth, view_item.properties['view:azimuth']) # Set view_item.ext.view.azimuth = view_azimuth + 100 self.assertEqual(view_azimuth + 100, view_item.properties['view:azimuth']) self.validator.validate_object(view_item) def test_sun_azimuth(self): view_item = pystac.read_file(self.example_uri) # Get self.assertIn("view:sun_azimuth", view_item.properties) view_sun_azimuth = view_item.ext.view.sun_azimuth self.assertEqual(view_sun_azimuth, view_item.properties['view:sun_azimuth']) # Set view_item.ext.view.sun_azimuth = view_sun_azimuth + 100 self.assertEqual(view_sun_azimuth + 100, view_item.properties['view:sun_azimuth']) self.validator.validate_object(view_item) def test_sun_elevation(self): view_item = pystac.read_file(self.example_uri) # Get self.assertIn("view:sun_elevation", view_item.properties) view_sun_elevation = view_item.ext.view.sun_elevation self.assertEqual(view_sun_elevation, view_item.properties['view:sun_elevation']) # Set view_item.ext.view.sun_elevation = view_sun_elevation + 100 self.assertEqual(view_sun_elevation + 100, view_item.properties['view:sun_elevation']) self.validator.validate_object(view_item)
class STACWritingTest(unittest.TestCase): """Tests writing STACs, using JSON Schema validation, and ensure that links are correctly set to relative or absolute. """ def setUp(self): self.schema_validator = SchemaValidator() def validate_catalog(self, catalog): self.schema_validator.validate_object(catalog, print_on_error=True) validated_count = 1 for child in catalog.get_children(): validated_count += self.validate_catalog(child) for item in catalog.get_items(): self.schema_validator.validate_object(item, print_on_error=True) validated_count += 1 return validated_count def validate_file(self, path, object_type): d = STAC_IO.read_json(path) return self.schema_validator.validate_dict(d, object_type, print_on_error=True) def validate_link_types(self, root_href, catalog_type): def validate_item_link_type(href, link_type, should_include_self): item_dict = STAC_IO.read_json(href) item = STACObject.from_file(href) for link in item.get_links(): if not link.rel == 'self': self.assertEqual(link.link_type, link_type) rels = set([link['rel'] for link in item_dict['links']]) self.assertEqual('self' in rels, should_include_self) def validate_catalog_link_type(href, link_type, should_include_self): cat_dict = STAC_IO.read_json(href) cat = STACObject.from_file(href) for link in cat.get_links(): if not link.rel == 'self': self.assertEqual(link.link_type, link_type) rels = set([link['rel'] for link in cat_dict['links']]) self.assertEqual('self' in rels, should_include_self) for child_link in cat.get_child_links(): child_href = make_absolute_href(child_link.target, href) validate_catalog_link_type(child_href, link_type, catalog_type == CatalogType.ABSOLUTE_PUBLISHED) for item_link in cat.get_item_links(): item_href = make_absolute_href(item_link.target, href) validate_item_link_type(item_href, link_type, catalog_type == CatalogType.ABSOLUTE_PUBLISHED) link_type = LinkType.RELATIVE if catalog_type == CatalogType.ABSOLUTE_PUBLISHED: link_type = LinkType.ABSOLUTE root_should_include_href = catalog_type in [ CatalogType.ABSOLUTE_PUBLISHED, CatalogType.RELATIVE_PUBLISHED ] validate_catalog_link_type(root_href, link_type, root_should_include_href) def do_test(self, catalog, catalog_type): with TemporaryDirectory() as tmp_dir: catalog.normalize_hrefs(tmp_dir) self.validate_catalog(catalog) catalog.save(catalog_type=catalog_type) root_href = catalog.get_self_href() self.validate_link_types(root_href, catalog_type) for parent, children, items in catalog.walk(): if issubclass(type(parent), Collection): stac_object_type = STACObjectType.COLLECTION else: stac_object_type = STACObjectType.CATALOG self.validate_file(parent.get_self_href(), stac_object_type) for item in items: self.validate_file(item.get_self_href(), STACObjectType.ITEM) def test_testcases(self): for catalog in TestCases.all_test_catalogs(): catalog = catalog.full_copy() for catalog_type in [ CatalogType.ABSOLUTE_PUBLISHED, CatalogType.RELATIVE_PUBLISHED, CatalogType.SELF_CONTAINED ]: with self.subTest(title='Catalog {} [{}]'.format(catalog.id, catalog_type)): self.do_test(catalog, catalog_type)
class EOTest(unittest.TestCase): def setUp(self): self.validator = SchemaValidator() self.maxDiff = None self.URI_1 = TestCases.get_path( 'data-files/eo/eo-landsat-example.json') self.URI_2 = TestCases.get_path( 'data-files/eo/eo-landsat-example-INVALID.json') self.eoi = Item.from_file(self.URI_1) with open(self.URI_1) as f: self.eo_dict = json.load(f) def test_to_from_dict(self): test_to_from_dict(self, Item, self.eo_dict) def test_from_file(self): self.assertEqual(len(self.eoi.ext.eo.bands), 11) for b in self.eoi.ext.eo.bands: self.assertIsInstance(b, Band) self.assertEqual(len(self.eoi.links), 3) href = ('https://odu9mlf7d6.execute-api.us-east-1.amazonaws.com/stage/' 'stac/search?id=LC08_L1TP_107018_20181001_20181001_01_RT') self.assertEqual(self.eoi.get_self_href(), href) def test_from_item(self): i = Item.from_file(self.URI_1) with self.assertRaises(AttributeError): getattr(i, 'bands') self.assertTrue('eo:bands' in i.properties.keys()) eo_ext = i.ext.eo self.assertIsNotNone(getattr(eo_ext, 'bands')) def test_read_eo_item_owns_asset(self): item = Item.from_file(self.URI_1) assert len(item.assets) > 0 for asset_key in item.assets: self.assertEqual(item.assets[asset_key].owner, item) def test_validate_eo(self): self.validator.validate_dict(self.eo_dict, STACObjectType.ITEM) with open(self.URI_2) as f: eo_dict_2 = json.load(f) try: self.validator.validate_dict(eo_dict_2, STACObjectType.ITEM) except STACValidationError as e: self.assertTrue('extension eo' in str(e)) with TemporaryDirectory() as tmp_dir: cat_dir = os.path.join(tmp_dir, 'catalog') catalog = TestCases.test_case_1() eo_item = Item.from_dict(self.eo_dict) catalog.add_item(eo_item) catalog.normalize_and_save( cat_dir, catalog_type=CatalogType.ABSOLUTE_PUBLISHED) cat_read = Catalog.from_file(os.path.join(cat_dir, 'catalog.json')) eo_item_read = cat_read.get_item( "LC08_L1TP_107018_20181001_20181001_01_RT") self.assertTrue(eo_item_read.ext.implements('eo')) self.validator.validate_object(eo_item_read) def test_gsd(self): eo_item = pystac.read_file( TestCases.get_path('data-files/eo/eo-landsat-example.json')) # Get self.assertIn("eo:gsd", eo_item.properties) eo_gsd = eo_item.ext.eo.gsd self.assertEqual(eo_gsd, eo_item.properties['eo:gsd']) # Set eo_item.ext.eo.gsd = eo_gsd + 100 self.assertEqual(eo_gsd + 100, eo_item.properties['eo:gsd']) self.validator.validate_object(eo_item) def test_bands(self): eo_item = pystac.read_file( TestCases.get_path('data-files/eo/eo-landsat-example.json')) # Get self.assertIn("eo:bands", eo_item.properties) bands = eo_item.ext.eo.bands self.assertEqual(list(map(lambda x: x.name, bands)), [ 'B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B9', 'B10', 'B11' ]) for band in bands: self.assertIsInstance(band.common_name, str) self.assertIn(type(band.center_wavelength), [float, int]) self.assertIn(type(band.full_width_half_max), [float, int]) self.assertIs(None, band.description) # Ensure modifying the bands make changes on the item. bands_dict = {band.name: band for band in bands} bands_dict['B1'].description = "Band 1" self.assertTrue( [x for x in eo_item.properties['eo:bands'] if x['name'] == 'B1'][0]['description'] == "Band 1") # Set new_bands = [ Band.create(name="red", description=Band.band_description("red")), Band.create(name="green", description=Band.band_description("green")), Band.create(name="blue", description=Band.band_description("blue")), ] eo_item.ext.eo.bands = new_bands self.assertEqual('Common name: red, Range: 0.6 to 0.7', eo_item.properties['eo:bands'][0]['description']) self.validator.validate_object(eo_item) def test_get_asset_bands(self): eo_item = pystac.read_file( TestCases.get_path('data-files/eo/eo-landsat-example.json')) b1_asset = eo_item.assets['B1'] asset_bands = eo_item.ext.eo.get_asset_bands(b1_asset) self.assertIsNot(None, asset_bands) self.assertEqual(len(asset_bands), 1) self.assertEqual(asset_bands[0].name, 'B1') index_asset = eo_item.assets['index'] asset_bands = eo_item.ext.eo.get_asset_bands(index_asset) self.assertIs(None, asset_bands) def test_set_asset_bands(self): eo_item = pystac.read_file( TestCases.get_path('data-files/eo/eo-landsat-example.json')) b1_asset = eo_item.assets['B1'] eo_item.ext.eo.set_asset_bands(b1_asset, ['B2']) eo_item_mod = Item.from_dict(eo_item.to_dict()) b1_asset_mod = eo_item_mod.assets['B1'] asset_bands = eo_item_mod.ext.eo.get_asset_bands(b1_asset_mod) self.assertIsNot(None, asset_bands) self.assertEqual(len(asset_bands), 1) self.assertEqual(asset_bands[0].name, 'B2') self.validator.validate_object(eo_item) # Check setting with invalid keys with self.assertRaises(KeyError): eo_item.ext.eo.set_asset_bands(b1_asset, ['BAD_KEY', 'BAD_KEY_2']) # Check adding a new asset asset = pystac.Asset(href="some/path.tif", media_type=pystac.MediaType.GEOTIFF) eo_item.ext.eo.set_asset_bands(asset, [b.name for b in eo_item.ext.eo.bands]) eo_item.add_asset("test", asset) self.assertEqual(eo_item.assets["test"].properties["eo:bands"], list(range(0, len(eo_item.ext.eo.bands)))) def test_read_pre_09_fields_into_common_metadata(self): eo_item = pystac.read_file( TestCases.get_path('data-files/examples/0.8.1/item-spec/examples/' 'landsat8-sample.json')) self.assertEqual(eo_item.common_metadata.platform, "landsat-8") self.assertEqual(eo_item.common_metadata.instruments, ["oli_tirs"])
class LabelTest(unittest.TestCase): def setUp(self): self.validator = SchemaValidator() self.maxDiff = None self.label_example_1_uri = TestCases.get_path( 'data-files/label/label-example-1.json') self.label_example_2_uri = TestCases.get_path( 'data-files/label/label-example-2.json') def test_to_from_dict(self): with open(self.label_example_1_uri) as f: label_example_1_dict = json.load(f) test_to_from_dict(self, Item, label_example_1_dict) def test_from_file(self): label_example_1 = Item.from_file(self.label_example_1_uri) self.assertEqual( len(label_example_1.ext.label.label_overviews[0].counts), 2) self.validator.validate_object(label_example_1) label_example_2 = Item.from_file(self.label_example_2_uri) self.assertEqual( len(label_example_2.ext.label.label_overviews[0].counts), 2) # TODO: Validate for 1.0 as schema was fixed. # In 0.9.0 the properties are required (but need to be null for raster labels) # self.validator.validate_object(label_example_2) def test_from_file_pre_081(self): d = STAC_IO.read_json(self.label_example_1_uri) d['stac_version'] = '0.8.0-rc1' d['properties']['label:property'] = d['properties']['label:properties'] d['properties'].pop('label:properties') d['properties']['label:overview'] = d['properties']['label:overviews'] d['properties'].pop('label:overviews') d['properties']['label:method'] = d['properties']['label:methods'] d['properties'].pop('label:methods') d['properties']['label:task'] = d['properties']['label:tasks'] d['properties'].pop('label:tasks') label_example_1 = STAC_IO.stac_object_from_dict(d) self.assertEqual(len(label_example_1.ext.label.label_tasks), 2) def test_get_sources(self): cat = TestCases.test_case_1() items = cat.get_all_items() item_ids = set([i.id for i in items]) for li in items: if li.ext.implements('label'): sources = li.ext.label.get_sources() self.assertEqual(len(sources), 1) self.assertTrue(sources[0].id in item_ids) def test_validate_label(self): with open(self.label_example_1_uri) as f: label_example_1_dict = json.load(f) self.validator.validate_dict(label_example_1_dict, "ITEM") with TemporaryDirectory() as tmp_dir: cat_dir = os.path.join(tmp_dir, 'catalog') catalog = TestCases.test_case_1() catalog.normalize_and_save(cat_dir, catalog_type=CatalogType.SELF_CONTAINED) cat_read = Catalog.from_file(os.path.join(cat_dir, 'catalog.json')) label_item_read = cat_read.get_item("area-2-2-labels", recursive=True) self.validator.validate_object(label_item_read) def test_read_label_item_owns_asset(self): item = next(x for x in TestCases.test_case_2().get_all_items() if x.ext.implements("label")) assert len(item.assets) > 0 for asset_key in item.assets: self.assertEqual(item.assets[asset_key].owner, item) def test_label_description(self): label_item = pystac.read_file(self.label_example_1_uri) # Get self.assertIn("label:description", label_item.properties) label_desc = label_item.ext.label.label_description self.assertEqual(label_desc, label_item.properties['label:description']) # Set label_item.ext.label.label_description = "A detailed description" self.assertEqual("A detailed description", label_item.properties['label:description']) self.validator.validate_object(label_item) def test_label_type(self): label_item = pystac.read_file(self.label_example_1_uri) # Get self.assertIn("label:type", label_item.properties) label_type = label_item.ext.label.label_type self.assertEqual(label_type, label_item.properties['label:type']) # Set label_item.ext.label.label_type = label.LabelType.RASTER self.assertEqual(label.LabelType.RASTER, label_item.properties['label:type']) self.validator.validate_object(label_item) def test_label_properties(self): label_item = pystac.read_file(self.label_example_1_uri) label_item2 = pystac.read_file(self.label_example_2_uri) # Get self.assertIn("label:properties", label_item.properties) label_prop = label_item.ext.label.label_properties self.assertEqual(label_prop, label_item.properties['label:properties']) raster_label_prop = label_item2.ext.label.label_properties self.assertEqual(raster_label_prop, None) # Set label_item.ext.label.label_properties = ["prop1", "prop2"] self.assertEqual(["prop1", "prop2"], label_item.properties['label:properties']) self.validator.validate_object(label_item) def test_label_classes(self): # Get label_item = pystac.read_file(self.label_example_1_uri) label_classes = label_item.ext.label.label_classes self.assertEqual(len(label_classes), 2) self.assertEqual(label_classes[1].classes, ["three", "four"]) # Set new_classes = [ label.LabelClasses.create(name="label2", classes=["five", "six"]), label.LabelClasses.create(name="label", classes=["seven", "eight"]) ] label_item.ext.label.label_classes = new_classes self.assertEqual([ class_name for lc in label_item.properties["label:classes"] for class_name in lc["classes"] ], ["five", "six", "seven", "eight"]) self.validator.validate_object(label_item) def test_label_tasks(self): label_item = pystac.read_file(self.label_example_1_uri) # Get self.assertIn("label:tasks", label_item.properties) label_prop = label_item.ext.label.label_tasks self.assertEqual(label_prop, ["classification", "regression"]) # Set label_item.ext.label.label_tasks = ["classification"] self.assertEqual(["classification"], label_item.properties['label:tasks']) self.validator.validate_object(label_item) def test_label_methods(self): label_item = pystac.read_file(self.label_example_1_uri) # Get self.assertIn("label:methods", label_item.properties) label_prop = label_item.ext.label.label_methods self.assertEqual(label_prop, ["manual"]) # Set label_item.ext.label.label_methods = ["manual", "automated"] self.assertEqual(["manual", "automated"], label_item.properties['label:methods']) self.validator.validate_object(label_item) def test_label_overviews(self): # Get label_item = pystac.read_file(self.label_example_1_uri) label_overviews = label_item.ext.label.label_overviews label_item2 = pystac.read_file(self.label_example_2_uri) label_overviews2 = label_item2.ext.label.label_overviews self.assertEqual(len(label_overviews), 2) self.assertEqual(label_overviews[1].property_key, "label-reg") self.assertEqual(label_overviews2[1].property_key, None) # Raster label_counts = label_overviews[0].counts self.assertEqual(label_counts[1].count, 17) label_item.ext.label.label_overviews[0].counts[1].count = 18 self.assertEqual( label_item.properties['label:overviews'][0]['counts'][1]['count'], 18) label_statistics = label_overviews[1].statistics self.assertEqual(label_statistics[0].name, "mean") label_item.ext.label.label_overviews[1].statistics[0].name = "avg" self.assertEqual( label_item.properties['label:overviews'][1]['statistics'][0] ['name'], "avg") # Set new_overviews = [ label.LabelOverview.create(property_key="label2", counts=[ label.LabelCount.create(name="one", count=1), label.LabelCount.create(name="two", count=1), ]), label.LabelOverview.create( property_key="label-reg", statistics=[ label.LabelStatistics.create(name="min", value=0.1), label.LabelStatistics.create(name="max", value=1.0), ]) ] label_item.ext.label.label_overviews = new_overviews self.assertEqual([ (count['name'], count['count']) for count in label_item.properties["label:overviews"][0]['counts'] ], [("one", 1), ("two", 1)]) self.assertEqual([(count['name'], count['value']) for count in label_item.properties["label:overviews"] [1]['statistics']], [("min", 0.1), ("max", 1.0)]) self.validator.validate_object(label_item)
class STACWritingTest(unittest.TestCase): """Tests writing STACs, using JSON Schema validation, and ensure that links are correctly set to relative or absolute. """ def setUp(self): self.schema_validator = SchemaValidator() def validate_catalog(self, catalog): self.schema_validator.validate_object(catalog) validated_count = 1 for child in catalog.get_children(): validated_count += self.validate_catalog(child) for item in catalog.get_items(): self.schema_validator.validate_object(item) validated_count += 1 return validated_count def validate_file(self, path, object_type): d = STAC_IO.read_json(path) return self.schema_validator.validate_dict(d, object_type) def validate_link_types(self, root_href, catalog_type): def validate_item_link_type(href, link_type, should_include_self): item_dict = STAC_IO.read_json(href) item = STACObject.from_file(href) for link in item.get_links(): if not link.rel == 'self': self.assertEqual(link.link_type, link_type) rels = set([l['rel'] for l in item_dict['links']]) self.assertEqual('self' in rels, should_include_self) def validate_catalog_link_type(href, link_type, should_include_self): cat_dict = STAC_IO.read_json(href) cat = STACObject.from_file(href) for link in cat.get_links(): if not link.rel == 'self': self.assertEqual(link.link_type, link_type) rels = set([l['rel'] for l in cat_dict['links']]) self.assertEqual('self' in rels, should_include_self) for child_link in cat.get_child_links(): child_href = make_absolute_href(child_link.target, href) validate_catalog_link_type( child_href, link_type, catalog_type == CatalogType.ABSOLUTE_PUBLISHED) for item_link in cat.get_item_links(): item_href = make_absolute_href(item_link.target, href) validate_item_link_type( item_href, link_type, catalog_type == CatalogType.ABSOLUTE_PUBLISHED) link_type = LinkType.RELATIVE if catalog_type == CatalogType.ABSOLUTE_PUBLISHED: link_type = LinkType.ABSOLUTE root_should_include_href = catalog_type in [ CatalogType.ABSOLUTE_PUBLISHED, CatalogType.RELATIVE_PUBLISHED ] validate_catalog_link_type(root_href, link_type, root_should_include_href) def do_test(self, catalog, catalog_type): with TemporaryDirectory() as tmp_dir: catalog.normalize_hrefs(tmp_dir) self.validate_catalog(catalog) catalog.save(catalog_type=catalog_type) root_href = catalog.get_self_href() self.validate_link_types(root_href, catalog_type) for parent, children, items in catalog.walk(): self.validate_file(parent.get_self_href(), type(parent)) for item in items: self.validate_file(item.get_self_href(), type(item)) def test_testcase1_absolute_published(self): catalog = TestCases.test_case_1() self.do_test(catalog, CatalogType.ABSOLUTE_PUBLISHED) def test_testcase1_relative_published(self): catalog = TestCases.test_case_1() self.do_test(catalog, CatalogType.RELATIVE_PUBLISHED) def test_testcase1_self_contained(self): catalog = TestCases.test_case_1() self.do_test(catalog, CatalogType.SELF_CONTAINED) def test_testcase2_absolute_published(self): catalog = TestCases.test_case_2() catalog = catalog.full_copy() self.do_test(catalog, CatalogType.ABSOLUTE_PUBLISHED) def test_testcase2_relative_published(self): catalog = TestCases.test_case_2() self.do_test(catalog, CatalogType.RELATIVE_PUBLISHED) def test_testcase2_self_contained(self): catalog = TestCases.test_case_2() self.do_test(catalog, CatalogType.SELF_CONTAINED) def test_testcase3_absolute_published(self): catalog = TestCases.test_case_3() catalog = catalog.full_copy() self.do_test(catalog, CatalogType.ABSOLUTE_PUBLISHED) def test_testcase3_relative_published(self): catalog = TestCases.test_case_3() self.do_test(catalog, CatalogType.RELATIVE_PUBLISHED) def test_testcase3_self_contained(self): catalog = TestCases.test_case_3() self.do_test(catalog, CatalogType.SELF_CONTAINED)