1# Copyright (c) 2021 EUMETSAT
  2# License: Proprietary
  3
  4""" Tests for transforming Limits and LimitDefinition classes to and from XML. """
  5
  6from chart.products.scos2000.limits import Limits, LimitDefinition
  7from chart.products.scos2000.limits_xml_transform import (
  8    limits_to_xml, limit_definition_to_xml, _filter_limits_by_type,
  9    ELEM_LIMITS, ELEM_VALUE_HIGH, ELEM_VALUE_LOW, ELEM_ORDER,
 10    ELEM_APPLICABILITY, ELEM_APPLICABILITY_PARAMETER, ELEM_APPLICABILITY_VALUE)
 11from chart.common.xml import XMLElement
 12import chart.db.model.limits_model as db_model
 13
 14
 15def test_limits_create_xml_without_definitions():
 16    """ Initialize a Limits object without LimitDefinitions.
 17        Confirm that 'limits' element exists without children. """
 18    limits = Limits(['ABC12345', '1', '2', 'U', 'R'])
 19
 20    xml = limits_to_xml(limits)
 21
 22    assert xml.elem.tag == ELEM_LIMITS
 23    assert len(xml.elem.getchildren()) == 0
 24
 25
 26def test_limits_create_xml_with_definitions():
 27    """ Initialize a Limits object including LimitDefinitions.
 28        Confirm that 'limits' element exists with three children (calibrated, yellow, red). """
 29    limits = Limits(['ABC12345', '1', '2', 'U', 'R'],
 30                    [['1', 'S', '1.23', '4.56', 'DEF67890', '1'],
 31                    ['2', 'H', '2.22', '3.33', 'DEF67890', '1']])
 32
 33    xml = limits_to_xml(limits)
 34
 35    assert xml.elem.tag == ELEM_LIMITS
 36    assert len(xml.elem.getchildren()) == 3
 37
 38
 39def test_limit_definition_create_xml_no_applicability():
 40    """ Initialize a LimitDefinition object with integer limit values.
 41        Confirm that 'limit' element exists with all children except applicability fields. """
 42    limit_def = LimitDefinition(['1', 'S', '1', '4', '', '0'], 'I')
 43
 44    xml = limit_definition_to_xml(limit_def)
 45
 46    assert xml.elem.xpath(f'/yellow/{ELEM_VALUE_LOW}')[0].text == '1'
 47    assert xml.elem.xpath(f'/yellow/{ELEM_VALUE_HIGH}')[0].text == '4'
 48    assert xml.elem.xpath(f'/yellow/{ELEM_ORDER}')[0].text == '1'
 49    assert xml.elem.xpath(f'/yellow/{ELEM_APPLICABILITY}') == []
 50
 51
 52def test_limit_definition_create_xml_applicability():
 53    """ Initialize a LimitDefinition object with empty limit values.
 54        Confirm that all applicability elements exist inside the limit. """
 55    limit_def = LimitDefinition(['1', 'S', '1', '4', 'DEF67890', '1'], 'I')
 56
 57    xml = limit_definition_to_xml(limit_def)
 58
 59    assert xml.elem.xpath(f'/yellow/{ELEM_ORDER}')[0].text == '1'
 60    assert xml.elem.xpath(f'/yellow/{ELEM_APPLICABILITY}/{ELEM_APPLICABILITY_PARAMETER}'
 61                          )[0].text == 'DEF67890'
 62    assert xml.elem.xpath(f'/yellow/{ELEM_APPLICABILITY}/{ELEM_APPLICABILITY_VALUE}'
 63                          )[0].text == '1'
 64
 65
 66def test_limit_definition_create_xml_empty_values():
 67    """ Initialize a LimitDefinition object with empty limit values.
 68        Confirm that 'limit' element contains empty limit value fields. """
 69    limit_def = LimitDefinition(['1', 'C', '', '', 'DEF67890', '1'], 'I')
 70
 71    xml = limit_definition_to_xml(limit_def)
 72
 73    assert xml.elem.xpath(f'/consistency/{ELEM_VALUE_LOW}')[0].text == ''
 74    assert xml.elem.xpath(f'/consistency/{ELEM_VALUE_HIGH}')[0].text == ''
 75
 76
 77def test_limit_to_xml():
 78    """ Initialize a Limits object from XML with a red limit.
 79        Confirm that the attributes of the Limits object are set correctly. """
 80    xml_str = '<limits><calibrated>true</calibrated><red><high>3.3</high><low>2.2</low><order>1</order></red></limits>'
 81    xml_node = XMLElement(from_text=xml_str)
 82    limit = db_model.Limits(xml_node)
 83
 84    assert len(limit.red_limits) == 1
 85    assert limit.red_limits[0].order == 1
 86    assert limit.red_limits[0].low == 2.2
 87    assert limit.red_limits[0].high == 3.3
 88
 89
 90def test_limit_to_xml_with_applicability():
 91    """ Initialize a Limits object from XML with a yellow limit and applicability node.
 92        Confirm that the attributes of the Limits object are set correctly. """
 93    xml_str = """
 94        <limits>
 95            <yellow>
 96                <high>4</high>
 97                <low>1</low>
 98                <order>1</order>
 99                <applicability>
100                    <parameter>DEF67890</parameter>
101                    <value>1</value>
102                </applicability>
103            </yellow>
104        </limits>"""
105    xml_node = XMLElement(from_text=xml_str)
106    limit = db_model.Limits(xml_node)
107
108    # TODO(AA): update when applicability is implemented
109    assert limit.yellow_limits[0].applicability is None
110
111
112def test_limit_to_xml_no_low_value():
113    """ Initialize a Limits object from XML with a red limit without low value.
114        Confirm that the attributes of the Limits object are set correctly. """
115    xml_str = '<limits><red><high>3.3</high><low/><order>1</order></red></limits>'
116    xml_node = XMLElement(from_text=xml_str)
117    limit = db_model.Limits(xml_node)
118
119    assert limit.red_limits[0].low is None
120    assert limit.red_limits[0].high == 3.3
121
122
123def test_limit_to_xml_yellow_red():
124    """ Initialize a Limits object from XML with red and yellow limits.
125        Confirm that the attributes of the Limits object are set correctly. """
126    xml_str = """
127        <limits>
128            <calibrated>true</calibrated>
129            <yellow>
130                <order>1</order><high>4.56</high><low>1.23</low>
131            </yellow>
132            <red>
133                <order>2</order><high>3.33</high><low>2.22</low>
134            </red>
135        </limits>"""
136    xml_node = XMLElement(from_text=xml_str)
137    limit = db_model.Limits(xml_node)
138
139    assert limit.yellow_limits[0].low == 1.23
140    assert limit.yellow_limits[0].high == 4.56
141    assert limit.red_limits[0].low == 2.22
142    assert limit.red_limits[0].high == 3.33
143
144
145def test_filter_limits_by_type():
146    """ Initialize a Limits object with soft, hard and delta LimitDefinitions.
147        Confirm that the delta limit is removed by the filter. """
148    types = ['s', 'H']
149    limits = Limits(['test', 0, 3, 0, 'R'],
150                    [[0, 'S', 0, 0, 0, 0], [0, 'h', 0, 0, 0, 0], [0, 'C', 0, 0, 0, 0]])
151
152    _filter_limits_by_type(limits, types)
153    assert len(limits.ocp) == 2
154    assert limits.ocp[0].type.upper() in ['S', 'H']
155    assert limits.ocp[1].type.upper() in ['S', 'H']