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']