diff --git a/tests/vosi/VOSIAvailability-v1.0.xsd b/tests/vosi/VOSIAvailability-v1.0.xsd new file mode 100644 index 0000000..7c72bc3 --- /dev/null +++ b/tests/vosi/VOSIAvailability-v1.0.xsd @@ -0,0 +1,73 @@ + + + + + + A schema for formatting availability metadata as returned by an + availability resource defined in the IVOA Support Interfaces + specification (VOSI). + See http://www.ivoa.net/Documents/latest/VOSI.html. + + + + + + + + + + + + + Indicates whether the service is currently available. + + + + + + + + The instant at which the service last became available. + + + + + + + + The instant at which the service is next scheduled to become + unavailable. + + + + + + + + The instant at which the service is scheduled to become available + again after a period of unavailability. + + + + + + + + A textual note concerning availability. + + + + + + + + diff --git a/tests/vosi/__init__.py b/tests/vosi/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/vosi/availability_test.py b/tests/vosi/availability_test.py new file mode 100644 index 0000000..12bae51 --- /dev/null +++ b/tests/vosi/availability_test.py @@ -0,0 +1,59 @@ +"""Tests for VOSI Availability models.""" + +from datetime import timezone as tz +from unittest import TestCase +from xml.etree.ElementTree import canonicalize + +from lxml import etree + +with open("tests/vosi/VOSIAvailability-v1.0.xsd") as f: + availability_schema = etree.parse(f) + +from vo_models.xml.vosi.availability import Availability +from vo_models.xml.generics import VODateTime + +VOSI_AVAILABILITY_HEADER = """xmlns="http://www.ivoa.net/xml/VOSIAvailability/v1.0" +xmlns:xsd="http://www.w3.org/2001/XMLSchema" +xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +""" + +class TestVOSIAvailabilityType(TestCase): + """Tests the VOSI Availability complex type.""" + + test_avaiability_xml = f""" + true + 2021-01-01T00:00:00.000Z + 2021-01-01T00:00:00.000Z + 2021-01-01T00:00:00.000Z + Test note + """ + + def test_read_from_xml(self): + """Test reading Availability from XML.""" + availability = Availability.from_xml(self.test_avaiability_xml) + self.assertTrue(availability.available) + self.assertEqual(availability.up_since, VODateTime(2021, 1, 1, tzinfo=tz.utc)) + self.assertEqual(availability.down_at, VODateTime(2021, 1, 1, tzinfo=tz.utc)) + self.assertEqual(availability.back_at, VODateTime(2021, 1, 1, tzinfo=tz.utc)) + self.assertEqual(availability.note, ["Test note"]) + + def test_write_to_xml(self): + """Test writing Availability to XML.""" + availability = Availability( + available=True, + up_since="2021-01-01T00:00:00.000Z", + down_at="2021-01-01T00:00:00.000Z", + back_at="2021-01-01T00:00:00.000Z", + note=["Test note"], + ) + + with open("debug.xml", "w") as f: + f.write(canonicalize(availability.to_xml())) + f.write("\n") + f.write(canonicalize(self.test_avaiability_xml)) + + availability_xml = availability.to_xml() + self.assertEqual( + canonicalize(availability_xml, strip_text=True), + canonicalize(self.test_avaiability_xml, strip_text=True), + ) \ No newline at end of file diff --git a/vo_models/xml/vosi/__init__.py b/vo_models/xml/vosi/__init__.py new file mode 100644 index 0000000..a6b6c8b --- /dev/null +++ b/vo_models/xml/vosi/__init__.py @@ -0,0 +1 @@ +"""Module containing VOSI (VO Service Interface) classes.""" diff --git a/vo_models/xml/vosi/availability.py b/vo_models/xml/vosi/availability.py new file mode 100644 index 0000000..29b0fc5 --- /dev/null +++ b/vo_models/xml/vosi/availability.py @@ -0,0 +1,32 @@ +"""VOSIAvailability pydantic-xml models.""" + +from typing import Optional + +from pydantic_xml import BaseXmlModel, element + +from vo_models.xml.generics import VODateTime + +NSMAP = { + "": "http://www.ivoa.net/xml/VOSIAvailability/v1.0", + "xsd": "http://www.w3.org/2001/XMLSchema", + "xsi": "http://www.w3.org/2001/XMLSchema-instance", +} + + +class Availability(BaseXmlModel, tag="availability", nsmap=NSMAP): + """VOSI Availability complex type. + + Elements: + available (bool): Whether the service is currently available. + upSince (datetime): The instant at which the service last became available. + downAt (datetime): The instant at which the service is next scheduled to become unavailable. + backAt (datetime): The instant at which the service is scheduled to become available again after a period + of unavailability. + note (str): A textual note concerning availability. + """ + + available: bool = element(tag="available") + up_since: Optional[VODateTime] = element(tag="upSince") + down_at: Optional[VODateTime] = element(tag="downAt") + back_at: Optional[VODateTime] = element(tag="backAt") + note: Optional[list[str]] = element(tag="note")