Merge lp:~alisonken1/openlp/pjlink2-i into lp:openlp
- pjlink2-i
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Raoul Snyman |
Approved revision: | 2760 |
Merged at revision: | 2760 |
Proposed branch: | lp:~alisonken1/openlp/pjlink2-i |
Merge into: | lp:openlp |
Diff against target: |
1078 lines (+690/-117) 3 files modified
openlp/core/lib/projector/pjlink.py (+45/-35) tests/functional/openlp_core_lib/test_projector_pjlink_cmd_routing.py (+1/-1) tests/functional/openlp_core_lib/test_projector_pjlink_commands.py (+644/-81) |
To merge this branch: | bzr merge lp:~alisonken1/openlp/pjlink2-i |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Raoul Snyman | Approve | ||
Tomas Groth | Approve | ||
Tim Bentley | Pending | ||
Review via email: mp+328951@code.launchpad.net |
This proposal supersedes a proposal from 2017-08-12.
Commit message
PJLink2 update I
Description of the change
More minor code cleanups
- Renamed get_shutter_status to get_av_mute_status (checks shutter and audio)
- Renamed shutter/audio mute test
- Update socket read to get 1K bytes in buffer
- Updated get_status for valid input
- Updated process_sver check valid length
- Update change_status to not use NETWORK_SENDING as a connection status check
- Added read check for packet length > allowed max
- Added test for process_inf1
- Added test for process_inf2
- Added test for process_info
- Added test for process_inst
- Added test for process_lamp with invalid data
- Update tests for process_powr
- Added test for process_
- Added tests for process_sver
- Added tests for change_status
- Added test for get_av_mute_status
- Added test for get_available_
- Added test for get_error_status
- Added test for get_input_source
- Added test for get_lamp_status
- Added test for get_manufacturer
- Added test for get_model
- Added test for get_name
- Added test for get_other_info
- Added test for get_power_status
- Added tests for get_status
- Added test for process_inf1
- Added test for get_process_inf2
- Added test for get_process_info
- Added test for reset_information
- Fix deprecated log calls
-------
lp:~alisonken1/openlp/pjlink2-i (revision 2760)
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[FAILURE] https:/
Tim Bentley (trb143) wrote : Posted in a previous version of this proposal | # |
Tomas Groth (tomasgroth) wrote : | # |
Looks ok to me.
Raoul Snyman (raoul-snyman) : | # |
Preview Diff
1 | === modified file 'openlp/core/lib/projector/pjlink.py' |
2 | --- openlp/core/lib/projector/pjlink.py 2017-08-11 11:04:33 +0000 |
3 | +++ openlp/core/lib/projector/pjlink.py 2017-08-12 21:17:39 +0000 |
4 | @@ -57,7 +57,7 @@ |
5 | E_AUTHENTICATION, E_CONNECTION_REFUSED, E_GENERAL, E_INVALID_DATA, E_NETWORK, E_NOT_CONNECTED, E_OK, \ |
6 | E_PARAMETER, E_PROJECTOR, E_SOCKET_TIMEOUT, E_UNAVAILABLE, E_UNDEFINED, PJLINK_ERRORS, PJLINK_ERST_DATA, \ |
7 | PJLINK_ERST_STATUS, PJLINK_MAX_PACKET, PJLINK_PORT, PJLINK_POWR_STATUS, PJLINK_VALID_CMD, \ |
8 | - STATUS_STRING, S_CONNECTED, S_CONNECTING, S_NETWORK_RECEIVED, S_NETWORK_SENDING, \ |
9 | + STATUS_STRING, S_CONNECTED, S_CONNECTING, S_INFO, S_NETWORK_RECEIVED, S_NETWORK_SENDING, \ |
10 | S_NOT_CONNECTED, S_OFF, S_OK, S_ON, S_STATUS |
11 | |
12 | # Shortcuts |
13 | @@ -159,7 +159,7 @@ |
14 | # A command returned successfully, no further processing needed |
15 | return |
16 | elif _cmd not in self.pjlink_functions: |
17 | - log.warn("({ip}) Unable to process command='{cmd}' (Future option)".format(ip=self.ip, cmd=cmd)) |
18 | + log.warning("({ip}) Unable to process command='{cmd}' (Future option)".format(ip=self.ip, cmd=cmd)) |
19 | return |
20 | elif _data in PJLINK_ERRORS: |
21 | # Oops - projector error |
22 | @@ -231,7 +231,7 @@ |
23 | # : Received: '%1CLSS=Class 1' (Optoma) |
24 | # : Received: '%1CLSS=Version1' (BenQ) |
25 | if len(data) > 1: |
26 | - log.warn("({ip}) Non-standard CLSS reply: '{data}'".format(ip=self.ip, data=data)) |
27 | + log.warning("({ip}) Non-standard CLSS reply: '{data}'".format(ip=self.ip, data=data)) |
28 | # Due to stupid projectors not following standards (Optoma, BenQ comes to mind), |
29 | # AND the different responses that can be received, the semi-permanent way to |
30 | # fix the class reply is to just remove all non-digit characters. |
31 | @@ -261,15 +261,15 @@ |
32 | """ |
33 | if len(data) != PJLINK_ERST_DATA['DATA_LENGTH']: |
34 | count = PJLINK_ERST_DATA['DATA_LENGTH'] |
35 | - log.warn("{ip}) Invalid error status response '{data}': length != {count}".format(ip=self.ip, |
36 | - data=data, |
37 | - count=count)) |
38 | + log.warning("{ip}) Invalid error status response '{data}': length != {count}".format(ip=self.ip, |
39 | + data=data, |
40 | + count=count)) |
41 | return |
42 | try: |
43 | datacheck = int(data) |
44 | except ValueError: |
45 | # Bad data - ignore |
46 | - log.warn("({ip}) Invalid error status response '{data}'".format(ip=self.ip, data=data)) |
47 | + log.warning("({ip}) Invalid error status response '{data}'".format(ip=self.ip, data=data)) |
48 | return |
49 | if datacheck == 0: |
50 | self.projector_errors = None |
51 | @@ -429,9 +429,9 @@ |
52 | if self.model_filter is None: |
53 | self.model_filter = data |
54 | else: |
55 | - log.warn("({ip}) Filter model already set".format(ip=self.ip)) |
56 | - log.warn("({ip}) Saved model: '{old}'".format(ip=self.ip, old=self.model_filter)) |
57 | - log.warn("({ip}) New model: '{new}'".format(ip=self.ip, new=data)) |
58 | + log.warning("({ip}) Filter model already set".format(ip=self.ip)) |
59 | + log.warning("({ip}) Saved model: '{old}'".format(ip=self.ip, old=self.model_filter)) |
60 | + log.warning("({ip}) New model: '{new}'".format(ip=self.ip, new=data)) |
61 | |
62 | def process_rlmp(self, data): |
63 | """ |
64 | @@ -440,9 +440,9 @@ |
65 | if self.model_lamp is None: |
66 | self.model_lamp = data |
67 | else: |
68 | - log.warn("({ip}) Lamp model already set".format(ip=self.ip)) |
69 | - log.warn("({ip}) Saved lamp: '{old}'".format(ip=self.ip, old=self.model_lamp)) |
70 | - log.warn("({ip}) New lamp: '{new}'".format(ip=self.ip, new=data)) |
71 | + log.warning("({ip}) Lamp model already set".format(ip=self.ip)) |
72 | + log.warning("({ip}) Saved lamp: '{old}'".format(ip=self.ip, old=self.model_lamp)) |
73 | + log.warning("({ip}) New lamp: '{new}'".format(ip=self.ip, new=data)) |
74 | |
75 | def process_snum(self, data): |
76 | """ |
77 | @@ -457,27 +457,32 @@ |
78 | else: |
79 | # Compare serial numbers and see if we got the same projector |
80 | if self.serial_no != data: |
81 | - log.warn("({ip}) Projector serial number does not match saved serial number".format(ip=self.ip)) |
82 | - log.warn("({ip}) Saved: '{old}'".format(ip=self.ip, old=self.serial_no)) |
83 | - log.warn("({ip}) Received: '{new}'".format(ip=self.ip, new=data)) |
84 | - log.warn("({ip}) NOT saving serial number".format(ip=self.ip)) |
85 | + log.warning("({ip}) Projector serial number does not match saved serial number".format(ip=self.ip)) |
86 | + log.warning("({ip}) Saved: '{old}'".format(ip=self.ip, old=self.serial_no)) |
87 | + log.warning("({ip}) Received: '{new}'".format(ip=self.ip, new=data)) |
88 | + log.warning("({ip}) NOT saving serial number".format(ip=self.ip)) |
89 | self.serial_no_received = data |
90 | |
91 | def process_sver(self, data): |
92 | """ |
93 | Software version of projector |
94 | """ |
95 | - if self.sw_version is None: |
96 | + if len(data) > 32: |
97 | + # Defined in specs max version is 32 characters |
98 | + log.warning("Invalid software version - too long") |
99 | + return |
100 | + elif self.sw_version is None: |
101 | log.debug("({ip}) Setting projector software version to '{data}'".format(ip=self.ip, data=data)) |
102 | self.sw_version = data |
103 | self.db_update = True |
104 | else: |
105 | # Compare software version and see if we got the same projector |
106 | if self.serial_no != data: |
107 | - log.warn("({ip}) Projector software version does not match saved software version".format(ip=self.ip)) |
108 | - log.warn("({ip}) Saved: '{old}'".format(ip=self.ip, old=self.sw_version)) |
109 | - log.warn("({ip}) Received: '{new}'".format(ip=self.ip, new=data)) |
110 | - log.warn("({ip}) NOT saving serial number".format(ip=self.ip)) |
111 | + log.warning("({ip}) Projector software version does not match saved " |
112 | + "software version".format(ip=self.ip)) |
113 | + log.warning("({ip}) Saved: '{old}'".format(ip=self.ip, old=self.sw_version)) |
114 | + log.warning("({ip}) Received: '{new}'".format(ip=self.ip, new=data)) |
115 | + log.warning("({ip}) Saving new serial number as sw_version_received".format(ip=self.ip)) |
116 | self.sw_version_received = data |
117 | |
118 | |
119 | @@ -605,7 +610,7 @@ |
120 | Normally called by timer(). |
121 | """ |
122 | if self.state() != self.ConnectedState: |
123 | - log.warn("({ip}) poll_loop(): Not connected - returning".format(ip=self.ip)) |
124 | + log.warning("({ip}) poll_loop(): Not connected - returning".format(ip=self.ip)) |
125 | return |
126 | log.debug('({ip}) Updating projector status'.format(ip=self.ip)) |
127 | # Reset timer in case we were called from a set command |
128 | @@ -649,7 +654,9 @@ |
129 | :param status: Status/Error code |
130 | :returns: (Status/Error code, String) |
131 | """ |
132 | - if status in ERROR_STRING: |
133 | + if not isinstance(status, int): |
134 | + return -1, 'Invalid status code' |
135 | + elif status in ERROR_STRING: |
136 | return ERROR_STRING[status], ERROR_MSG[status] |
137 | elif status in STATUS_STRING: |
138 | return STATUS_STRING[status], ERROR_MSG[status] |
139 | @@ -674,7 +681,7 @@ |
140 | elif status >= S_NOT_CONNECTED and status < S_STATUS: |
141 | self.status_connect = status |
142 | self.projector_status = S_NOT_CONNECTED |
143 | - elif status < S_NETWORK_SENDING: |
144 | + elif status <= S_INFO: |
145 | self.status_connect = S_CONNECTED |
146 | self.projector_status = status |
147 | (status_code, status_message) = self._get_status(self.status_connect) |
148 | @@ -803,7 +810,8 @@ |
149 | log.debug('({ip}) get_data(): Not connected - returning'.format(ip=self.ip)) |
150 | self.send_busy = False |
151 | return |
152 | - read = self.readLine(self.max_size) |
153 | + # Although we have a packet length limit, go ahead and use a larger buffer |
154 | + read = self.readLine(1024) |
155 | log.debug("({ip}) get_data(): '{buff}'".format(ip=self.ip, buff=read)) |
156 | if read == -1: |
157 | # No data available |
158 | @@ -816,6 +824,8 @@ |
159 | data = data_in.strip() |
160 | if (len(data) < 7) or (not data.startswith(PJLINK_PREFIX)): |
161 | return self._trash_buffer(msg='get_data(): Invalid packet - length or prefix') |
162 | + elif len(data) > self.max_size: |
163 | + return self._trash_buffer(msg='get_data(): Invalid packet - too long') |
164 | elif '=' not in data: |
165 | return self._trash_buffer(msg='get_data(): Invalid packet does not have equal') |
166 | log.debug('({ip}) get_data(): Checking new data "{data}"'.format(ip=self.ip, data=data)) |
167 | @@ -830,8 +840,8 @@ |
168 | log.warning('({ip}) get_data(): Invalid packet - unknown command "{data}"'.format(ip=self.ip, data=cmd)) |
169 | return self._trash_buffer(msg='get_data(): Unknown command "{data}"'.format(data=cmd)) |
170 | if int(self.pjlink_class) < int(version): |
171 | - log.warn('({ip}) get_data(): Projector returned class reply higher ' |
172 | - 'than projector stated class'.format(ip=self.ip)) |
173 | + log.warning('({ip}) get_data(): Projector returned class reply higher ' |
174 | + 'than projector stated class'.format(ip=self.ip)) |
175 | return self.process_command(cmd, data) |
176 | |
177 | @QtCore.pyqtSlot(QtNetwork.QAbstractSocket.SocketError) |
178 | @@ -993,6 +1003,13 @@ |
179 | self.reset_information() |
180 | self.projectorUpdateIcons.emit() |
181 | |
182 | + def get_av_mute_status(self): |
183 | + """ |
184 | + Send command to retrieve shutter status. |
185 | + """ |
186 | + log.debug('({ip}) Sending AVMT command'.format(ip=self.ip)) |
187 | + return self.send_command(cmd='AVMT') |
188 | + |
189 | def get_available_inputs(self): |
190 | """ |
191 | Send command to retrieve available source inputs. |
192 | @@ -1056,13 +1073,6 @@ |
193 | log.debug('({ip}) Sending POWR command'.format(ip=self.ip)) |
194 | return self.send_command(cmd='POWR') |
195 | |
196 | - def get_shutter_status(self): |
197 | - """ |
198 | - Send command to retrieve shutter status. |
199 | - """ |
200 | - log.debug('({ip}) Sending AVMT command'.format(ip=self.ip)) |
201 | - return self.send_command(cmd='AVMT') |
202 | - |
203 | def set_input_source(self, src=None): |
204 | """ |
205 | Verify input source available as listed in 'INST' command, |
206 | |
207 | === modified file 'tests/functional/openlp_core_lib/test_projector_pjlink_cmd_routing.py' |
208 | --- tests/functional/openlp_core_lib/test_projector_pjlink_cmd_routing.py 2017-08-11 11:04:33 +0000 |
209 | +++ tests/functional/openlp_core_lib/test_projector_pjlink_cmd_routing.py 2017-08-12 21:17:39 +0000 |
210 | @@ -179,7 +179,7 @@ |
211 | |
212 | # THEN: Error should be logged and no command called |
213 | self.assertFalse(mock_functions.called, 'Should not have gotten to the end of the method') |
214 | - mock_log.warn.assert_called_once_with(log_text) |
215 | + mock_log.warning.assert_called_once_with(log_text) |
216 | |
217 | @patch.object(pjlink_test, 'pjlink_functions') |
218 | @patch.object(openlp.core.lib.projector.pjlink, 'log') |
219 | |
220 | === modified file 'tests/functional/openlp_core_lib/test_projector_pjlink_commands.py' |
221 | --- tests/functional/openlp_core_lib/test_projector_pjlink_commands.py 2017-08-11 11:04:33 +0000 |
222 | +++ tests/functional/openlp_core_lib/test_projector_pjlink_commands.py 2017-08-12 21:17:39 +0000 |
223 | @@ -23,12 +23,14 @@ |
224 | Package to test the openlp.core.lib.projector.pjlink commands package. |
225 | """ |
226 | from unittest import TestCase |
227 | -from unittest.mock import patch, MagicMock |
228 | +from unittest.mock import patch |
229 | |
230 | import openlp.core.lib.projector.pjlink |
231 | from openlp.core.lib.projector.pjlink import PJLink |
232 | from openlp.core.lib.projector.constants import ERROR_STRING, PJLINK_ERST_DATA, PJLINK_ERST_STATUS, \ |
233 | - PJLINK_POWR_STATUS, E_WARN, E_ERROR, S_OFF, S_STANDBY, S_ON |
234 | + PJLINK_POWR_STATUS, \ |
235 | + E_ERROR, E_NOT_CONNECTED, E_SOCKET_ADDRESS_NOT_AVAILABLE, E_UNKNOWN_SOCKET_ERROR, E_WARN, \ |
236 | + S_CONNECTED, S_OFF, S_ON, S_NOT_CONNECTED, S_CONNECTING, S_STANDBY |
237 | |
238 | from tests.resources.projector.data import TEST_PIN |
239 | |
240 | @@ -45,48 +47,408 @@ |
241 | """ |
242 | Tests for the PJLink module |
243 | """ |
244 | - def test_projector_reset_information(self): |
245 | - """ |
246 | - Test reset_information() resets all information and stops timers |
247 | - """ |
248 | - # GIVEN: Test object and test data |
249 | - pjlink = pjlink_test |
250 | - pjlink.power = S_ON |
251 | - pjlink.pjlink_name = 'OPENLPTEST' |
252 | - pjlink.manufacturer = 'PJLINK' |
253 | - pjlink.model = '1' |
254 | - pjlink.shutter = True |
255 | - pjlink.mute = True |
256 | - pjlink.lamp = True |
257 | - pjlink.fan = True |
258 | - pjlink.source_available = True |
259 | - pjlink.other_info = 'ANOTHER TEST' |
260 | - pjlink.send_queue = True |
261 | - pjlink.send_busy = True |
262 | - pjlink.timer = MagicMock() |
263 | - pjlink.socket_timer = MagicMock() |
264 | - |
265 | - # WHEN: reset_information() is called |
266 | - with patch.object(pjlink.timer, 'stop') as mock_timer: |
267 | - with patch.object(pjlink.socket_timer, 'stop') as mock_socket_timer: |
268 | - pjlink.reset_information() |
269 | - |
270 | - # THEN: All information should be reset and timers stopped |
271 | - self.assertEqual(pjlink.power, S_OFF, 'Projector power should be OFF') |
272 | - self.assertIsNone(pjlink.pjlink_name, 'Projector pjlink_name should be None') |
273 | - self.assertIsNone(pjlink.manufacturer, 'Projector manufacturer should be None') |
274 | - self.assertIsNone(pjlink.model, 'Projector model should be None') |
275 | - self.assertIsNone(pjlink.shutter, 'Projector shutter should be None') |
276 | - self.assertIsNone(pjlink.mute, 'Projector shuttter should be None') |
277 | - self.assertIsNone(pjlink.lamp, 'Projector lamp should be None') |
278 | - self.assertIsNone(pjlink.fan, 'Projector fan should be None') |
279 | - self.assertIsNone(pjlink.source_available, 'Projector source_available should be None') |
280 | - self.assertIsNone(pjlink.source, 'Projector source should be None') |
281 | - self.assertIsNone(pjlink.other_info, 'Projector other_info should be None') |
282 | - self.assertEqual(pjlink.send_queue, [], 'Projector send_queue should be an empty list') |
283 | - self.assertFalse(pjlink.send_busy, 'Projector send_busy should be False') |
284 | - self.assertTrue(mock_timer.called, 'Projector timer.stop() should have been called') |
285 | - self.assertTrue(mock_socket_timer.called, 'Projector socket_timer.stop() should have been called') |
286 | + @patch.object(pjlink_test, 'changeStatus') |
287 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
288 | + def test_projector_change_status_connection_error(self, mock_log, mock_change_status): |
289 | + """ |
290 | + Test change_status with connection error |
291 | + """ |
292 | + # GIVEN: Test object |
293 | + pjlink = pjlink_test |
294 | + pjlink.projector_status = 0 |
295 | + pjlink.status_connect = 0 |
296 | + test_code = E_UNKNOWN_SOCKET_ERROR |
297 | + mock_change_status.reset_mock() |
298 | + mock_log.reset_mock() |
299 | + |
300 | + # WHEN: change_status called with unknown socket error |
301 | + pjlink.change_status(status=test_code, msg=None) |
302 | + |
303 | + # THEN: Proper settings should change and signals sent |
304 | + self.assertEqual(pjlink.projector_status, E_NOT_CONNECTED, 'Projector status should be NOT CONNECTED') |
305 | + self.assertEqual(pjlink.status_connect, E_NOT_CONNECTED, 'Status connect should be NOT CONNECTED') |
306 | + mock_change_status.emit.assert_called_once_with(pjlink.ip, E_UNKNOWN_SOCKET_ERROR, |
307 | + 'An unidentified error occurred') |
308 | + self.assertEqual(mock_log.debug.call_count, 3, 'Debug log should have been called 3 times') |
309 | + |
310 | + @patch.object(pjlink_test, 'changeStatus') |
311 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
312 | + def test_projector_change_status_connection_status_connecting(self, mock_log, mock_change_status): |
313 | + """ |
314 | + Test change_status with connection status |
315 | + """ |
316 | + # GIVEN: Test object |
317 | + pjlink = pjlink_test |
318 | + pjlink.projector_status = 0 |
319 | + pjlink.status_connect = 0 |
320 | + test_code = S_CONNECTING |
321 | + mock_change_status.reset_mock() |
322 | + mock_log.reset_mock() |
323 | + |
324 | + # WHEN: change_status called with unknown socket error |
325 | + pjlink.change_status(status=test_code, msg=None) |
326 | + |
327 | + # THEN: Proper settings should change and signals sent |
328 | + self.assertEqual(pjlink.projector_status, S_NOT_CONNECTED, 'Projector status should be NOT CONNECTED') |
329 | + self.assertEqual(pjlink.status_connect, S_CONNECTING, 'Status connect should be CONNECTING') |
330 | + mock_change_status.emit.assert_called_once_with(pjlink.ip, S_CONNECTING, 'Connecting') |
331 | + self.assertEqual(mock_log.debug.call_count, 3, 'Debug log should have been called 3 times') |
332 | + |
333 | + @patch.object(pjlink_test, 'changeStatus') |
334 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
335 | + def test_projector_change_status_connection_status_connected(self, mock_log, mock_change_status): |
336 | + """ |
337 | + Test change_status with connection status |
338 | + """ |
339 | + # GIVEN: Test object |
340 | + pjlink = pjlink_test |
341 | + pjlink.projector_status = 0 |
342 | + pjlink.status_connect = 0 |
343 | + test_code = S_ON |
344 | + mock_change_status.reset_mock() |
345 | + mock_log.reset_mock() |
346 | + |
347 | + # WHEN: change_status called with unknown socket error |
348 | + pjlink.change_status(status=test_code, msg=None) |
349 | + |
350 | + # THEN: Proper settings should change and signals sent |
351 | + self.assertEqual(pjlink.projector_status, S_ON, 'Projector status should be ON') |
352 | + self.assertEqual(pjlink.status_connect, S_CONNECTED, 'Status connect should be CONNECTED') |
353 | + mock_change_status.emit.assert_called_once_with(pjlink.ip, S_ON, 'Power is on') |
354 | + self.assertEqual(mock_log.debug.call_count, 3, 'Debug log should have been called 3 times') |
355 | + |
356 | + @patch.object(pjlink_test, 'changeStatus') |
357 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
358 | + def test_projector_change_status_connection_status_with_message(self, mock_log, mock_change_status): |
359 | + """ |
360 | + Test change_status with connection status |
361 | + """ |
362 | + # GIVEN: Test object |
363 | + pjlink = pjlink_test |
364 | + pjlink.projector_status = 0 |
365 | + pjlink.status_connect = 0 |
366 | + test_message = 'Different Status Message than default' |
367 | + test_code = S_ON |
368 | + mock_change_status.reset_mock() |
369 | + mock_log.reset_mock() |
370 | + |
371 | + # WHEN: change_status called with unknown socket error |
372 | + pjlink.change_status(status=test_code, msg=test_message) |
373 | + |
374 | + # THEN: Proper settings should change and signals sent |
375 | + self.assertEqual(pjlink.projector_status, S_ON, 'Projector status should be ON') |
376 | + self.assertEqual(pjlink.status_connect, S_CONNECTED, 'Status connect should be CONNECTED') |
377 | + mock_change_status.emit.assert_called_once_with(pjlink.ip, S_ON, test_message) |
378 | + self.assertEqual(mock_log.debug.call_count, 3, 'Debug log should have been called 3 times') |
379 | + |
380 | + @patch.object(pjlink_test, 'send_command') |
381 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
382 | + def test_projector_get_av_mute_status(self, mock_log, mock_send_command): |
383 | + """ |
384 | + Test sending command to retrieve shutter/audio state |
385 | + """ |
386 | + # GIVEN: Test object |
387 | + pjlink = pjlink_test |
388 | + mock_log.reset_mock() |
389 | + mock_send_command.reset_mock() |
390 | + test_data = 'AVMT' |
391 | + test_log = '(127.0.0.1) Sending AVMT command' |
392 | + |
393 | + # WHEN: get_av_mute_status is called |
394 | + pjlink.get_av_mute_status() |
395 | + |
396 | + # THEN: log data and send_command should have been called |
397 | + mock_log.debug.assert_called_once_with(test_log) |
398 | + mock_send_command.assert_called_once_with(cmd=test_data) |
399 | + |
400 | + @patch.object(pjlink_test, 'send_command') |
401 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
402 | + def test_projector_get_available_inputs(self, mock_log, mock_send_command): |
403 | + """ |
404 | + Test sending command to retrieve avaliable inputs |
405 | + """ |
406 | + # GIVEN: Test object |
407 | + pjlink = pjlink_test |
408 | + mock_log.reset_mock() |
409 | + mock_send_command.reset_mock() |
410 | + test_data = 'INST' |
411 | + test_log = '(127.0.0.1) Sending INST command' |
412 | + |
413 | + # WHEN: get_available_inputs is called |
414 | + pjlink.get_available_inputs() |
415 | + |
416 | + # THEN: log data and send_command should have been called |
417 | + mock_log.debug.assert_called_once_with(test_log) |
418 | + mock_send_command.assert_called_once_with(cmd=test_data) |
419 | + |
420 | + @patch.object(pjlink_test, 'send_command') |
421 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
422 | + def test_projector_get_error_status(self, mock_log, mock_send_command): |
423 | + """ |
424 | + Test sending command to retrieve projector error status |
425 | + """ |
426 | + # GIVEN: Test object |
427 | + pjlink = pjlink_test |
428 | + mock_log.reset_mock() |
429 | + mock_send_command.reset_mock() |
430 | + test_data = 'ERST' |
431 | + test_log = '(127.0.0.1) Sending ERST command' |
432 | + |
433 | + # WHEN: get_error_status is called |
434 | + pjlink.get_error_status() |
435 | + |
436 | + # THEN: log data and send_command should have been called |
437 | + mock_log.debug.assert_called_once_with(test_log) |
438 | + mock_send_command.assert_called_once_with(cmd=test_data) |
439 | + |
440 | + @patch.object(pjlink_test, 'send_command') |
441 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
442 | + def test_projector_get_input_source(self, mock_log, mock_send_command): |
443 | + """ |
444 | + Test sending command to retrieve current input |
445 | + """ |
446 | + # GIVEN: Test object |
447 | + pjlink = pjlink_test |
448 | + mock_log.reset_mock() |
449 | + mock_send_command.reset_mock() |
450 | + test_data = 'INPT' |
451 | + test_log = '(127.0.0.1) Sending INPT command' |
452 | + |
453 | + # WHEN: get_input_source is called |
454 | + pjlink.get_input_source() |
455 | + |
456 | + # THEN: log data and send_command should have been called |
457 | + mock_log.debug.assert_called_once_with(test_log) |
458 | + mock_send_command.assert_called_once_with(cmd=test_data) |
459 | + |
460 | + @patch.object(pjlink_test, 'send_command') |
461 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
462 | + def test_projector_get_lamp_status(self, mock_log, mock_send_command): |
463 | + """ |
464 | + Test sending command to retrieve lamp(s) status |
465 | + """ |
466 | + # GIVEN: Test object |
467 | + pjlink = pjlink_test |
468 | + mock_log.reset_mock() |
469 | + mock_send_command.reset_mock() |
470 | + test_data = 'LAMP' |
471 | + test_log = '(127.0.0.1) Sending LAMP command' |
472 | + |
473 | + # WHEN: get_lamp_status is called |
474 | + pjlink.get_lamp_status() |
475 | + |
476 | + # THEN: log data and send_command should have been called |
477 | + mock_log.debug.assert_called_once_with(test_log) |
478 | + mock_send_command.assert_called_once_with(cmd=test_data) |
479 | + |
480 | + @patch.object(pjlink_test, 'send_command') |
481 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
482 | + def test_projector_get_manufacturer(self, mock_log, mock_send_command): |
483 | + """ |
484 | + Test sending command to retrieve manufacturer name |
485 | + """ |
486 | + # GIVEN: Test object |
487 | + pjlink = pjlink_test |
488 | + mock_log.reset_mock() |
489 | + mock_send_command.reset_mock() |
490 | + test_data = 'INF1' |
491 | + test_log = '(127.0.0.1) Sending INF1 command' |
492 | + |
493 | + # WHEN: get_manufacturer is called |
494 | + pjlink.get_manufacturer() |
495 | + |
496 | + # THEN: log data and send_command should have been called |
497 | + mock_log.debug.assert_called_once_with(test_log) |
498 | + mock_send_command.assert_called_once_with(cmd=test_data) |
499 | + |
500 | + @patch.object(pjlink_test, 'send_command') |
501 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
502 | + def test_projector_get_model(self, mock_log, mock_send_command): |
503 | + """ |
504 | + Test sending command to get model information |
505 | + """ |
506 | + # GIVEN: Test object |
507 | + pjlink = pjlink_test |
508 | + mock_log.reset_mock() |
509 | + mock_send_command.reset_mock() |
510 | + test_data = 'INF2' |
511 | + test_log = '(127.0.0.1) Sending INF2 command' |
512 | + |
513 | + # WHEN: get_model is called |
514 | + pjlink.get_model() |
515 | + |
516 | + # THEN: log data and send_command should have been called |
517 | + mock_log.debug.assert_called_once_with(test_log) |
518 | + mock_send_command.assert_called_once_with(cmd=test_data) |
519 | + |
520 | + @patch.object(pjlink_test, 'send_command') |
521 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
522 | + def test_projector_get_name(self, mock_log, mock_send_command): |
523 | + """ |
524 | + Test sending command to get user-assigned name |
525 | + """ |
526 | + # GIVEN: Test object |
527 | + pjlink = pjlink_test |
528 | + mock_log.reset_mock() |
529 | + mock_send_command.reset_mock() |
530 | + test_data = 'NAME' |
531 | + test_log = '(127.0.0.1) Sending NAME command' |
532 | + |
533 | + # WHEN: get_name is called |
534 | + pjlink.get_name() |
535 | + |
536 | + # THEN: log data and send_command should have been called |
537 | + mock_log.debug.assert_called_once_with(test_log) |
538 | + mock_send_command.assert_called_once_with(cmd=test_data) |
539 | + |
540 | + @patch.object(pjlink_test, 'send_command') |
541 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
542 | + def test_projector_get_other_info(self, mock_log, mock_send_command): |
543 | + """ |
544 | + Test sending command to retrieve other information |
545 | + """ |
546 | + # GIVEN: Test object |
547 | + pjlink = pjlink_test |
548 | + mock_log.reset_mock() |
549 | + mock_send_command.reset_mock() |
550 | + test_data = 'INFO' |
551 | + test_log = '(127.0.0.1) Sending INFO command' |
552 | + |
553 | + # WHEN: get_other_info is called |
554 | + pjlink.get_other_info() |
555 | + |
556 | + # THEN: log data and send_command should have been called |
557 | + mock_log.debug.assert_called_once_with(test_log) |
558 | + mock_send_command.assert_called_once_with(cmd=test_data) |
559 | + |
560 | + @patch.object(pjlink_test, 'send_command') |
561 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
562 | + def test_projector_get_power_status(self, mock_log, mock_send_command): |
563 | + """ |
564 | + Test sending command to retrieve current power state |
565 | + """ |
566 | + # GIVEN: Test object |
567 | + pjlink = pjlink_test |
568 | + mock_log.reset_mock() |
569 | + mock_send_command.reset_mock() |
570 | + test_data = 'POWR' |
571 | + test_log = '(127.0.0.1) Sending POWR command' |
572 | + |
573 | + # WHEN: get_power_status called |
574 | + pjlink.get_power_status() |
575 | + |
576 | + # THEN: log data and send_command should have been called |
577 | + mock_log.debug.assert_called_once_with(test_log) |
578 | + mock_send_command.assert_called_once_with(cmd=test_data) |
579 | + |
580 | + def test_projector_get_status_error(self): |
581 | + """ |
582 | + Test to check returned information for error code |
583 | + """ |
584 | + # GIVEN: Test object |
585 | + pjlink = pjlink_test |
586 | + test_string = 'E_SOCKET_ADDRESS_NOT_AVAILABLE' |
587 | + test_message = 'The address specified to socket.bind() does not belong to the host' |
588 | + |
589 | + # WHEN: get_status called |
590 | + string, message = pjlink._get_status(status=E_SOCKET_ADDRESS_NOT_AVAILABLE) |
591 | + |
592 | + # THEN: Proper strings should have been returned |
593 | + self.assertEqual(string, test_string, 'Code as string should have been returned') |
594 | + self.assertEqual(message, test_message, 'Description of code should have been returned') |
595 | + |
596 | + def test_projector_get_status_invalid(self): |
597 | + """ |
598 | + Test to check returned information for error code |
599 | + """ |
600 | + # GIVEN: Test object |
601 | + pjlink = pjlink_test |
602 | + test_string = 'Test string since get_status will only work with int' |
603 | + test_message = 'Invalid status code' |
604 | + |
605 | + # WHEN: get_status called |
606 | + string, message = pjlink._get_status(status=test_string) |
607 | + |
608 | + # THEN: Proper strings should have been returned |
609 | + self.assertEqual(string, -1, 'Should have returned -1 as a bad status check') |
610 | + self.assertEqual(message, test_message, 'Error message should have been returned') |
611 | + |
612 | + def test_projector_get_status_status(self): |
613 | + """ |
614 | + Test to check returned information for status codes |
615 | + """ |
616 | + # GIVEN: Test object |
617 | + pjlink = pjlink_test |
618 | + test_string = 'S_NOT_CONNECTED' |
619 | + test_message = 'Not connected' |
620 | + |
621 | + # WHEN: get_status called |
622 | + string, message = pjlink._get_status(status=S_NOT_CONNECTED) |
623 | + |
624 | + # THEN: Proper strings should have been returned |
625 | + self.assertEqual(string, test_string, 'Code as string should have been returned') |
626 | + self.assertEqual(message, test_message, 'Description of code should have been returned') |
627 | + |
628 | + def test_projector_get_status_unknown(self): |
629 | + """ |
630 | + Test to check returned information for unknown code |
631 | + """ |
632 | + # GIVEN: Test object |
633 | + pjlink = pjlink_test |
634 | + test_string = 999999 |
635 | + test_message = 'Unknown status' |
636 | + |
637 | + # WHEN: get_status called |
638 | + string, message = pjlink._get_status(status=test_string) |
639 | + |
640 | + # THEN: Proper strings should have been returned |
641 | + self.assertEqual(string, test_string, 'Received code should have been returned') |
642 | + self.assertEqual(message, test_message, 'Unknown status string should have been returned') |
643 | + |
644 | + def test_projector_process_inf1(self): |
645 | + """ |
646 | + Test saving INF1 data (manufacturer) |
647 | + """ |
648 | + # GIVEN: Test object |
649 | + pjlink = pjlink_test |
650 | + pjlink.manufacturer = None |
651 | + test_data = 'TEst INformation MultiCase' |
652 | + |
653 | + # WHEN: process_inf called with test data |
654 | + pjlink.process_inf1(data=test_data) |
655 | + |
656 | + # THEN: Data should be saved |
657 | + self.assertEqual(pjlink.manufacturer, test_data, 'Test data should have been saved') |
658 | + |
659 | + def test_projector_process_inf2(self): |
660 | + """ |
661 | + Test saving INF2 data (model) |
662 | + """ |
663 | + # GIVEN: Test object |
664 | + pjlink = pjlink_test |
665 | + pjlink.model = None |
666 | + test_data = 'TEst moDEl MultiCase' |
667 | + |
668 | + # WHEN: process_inf called with test data |
669 | + pjlink.process_inf2(data=test_data) |
670 | + |
671 | + # THEN: Data should be saved |
672 | + self.assertEqual(pjlink.model, test_data, 'Test data should have been saved') |
673 | + |
674 | + def test_projector_process_info(self): |
675 | + """ |
676 | + Test saving INFO data (other information) |
677 | + """ |
678 | + # GIVEN: Test object |
679 | + pjlink = pjlink_test |
680 | + pjlink.other_info = None |
681 | + test_data = 'TEst ExtrANEous MultiCase INformatoin that MFGR might Set' |
682 | + |
683 | + # WHEN: process_inf called with test data |
684 | + pjlink.process_info(data=test_data) |
685 | + |
686 | + # THEN: Data should be saved |
687 | + self.assertEqual(pjlink.other_info, test_data, 'Test data should have been saved') |
688 | |
689 | @patch.object(pjlink_test, 'projectorUpdateIcons') |
690 | def test_projector_process_avmt_bad_data(self, mock_UpdateIcons): |
691 | @@ -245,12 +607,12 @@ |
692 | |
693 | # WHEN: Process invalid reply |
694 | pjlink.process_clss('Z') |
695 | - log_warn_text = "(127.0.0.1) NAN clss version reply 'Z' - defaulting to class '1'" |
696 | + log_text = "(127.0.0.1) NAN clss version reply 'Z' - defaulting to class '1'" |
697 | |
698 | # THEN: Projector class should be set with default value |
699 | self.assertEqual(pjlink.pjlink_class, '1', |
700 | 'Non-standard class reply should have set class=1') |
701 | - mock_log.error.assert_called_once_with(log_warn_text) |
702 | + mock_log.error.assert_called_once_with(log_text) |
703 | |
704 | @patch.object(openlp.core.lib.projector.pjlink, 'log') |
705 | def test_projector_process_clss_invalid_no_version(self, mock_log): |
706 | @@ -262,12 +624,12 @@ |
707 | |
708 | # WHEN: Process invalid reply |
709 | pjlink.process_clss('Invalid') |
710 | - log_warn_text = "(127.0.0.1) No numbers found in class version reply 'Invalid' - defaulting to class '1'" |
711 | + log_text = "(127.0.0.1) No numbers found in class version reply 'Invalid' - defaulting to class '1'" |
712 | |
713 | # THEN: Projector class should be set with default value |
714 | self.assertEqual(pjlink.pjlink_class, '1', |
715 | 'Non-standard class reply should have set class=1') |
716 | - mock_log.error.assert_called_once_with(log_warn_text) |
717 | + mock_log.error.assert_called_once_with(log_text) |
718 | |
719 | def test_projector_process_erst_all_ok(self): |
720 | """ |
721 | @@ -292,15 +654,15 @@ |
722 | # GIVEN: Test object |
723 | pjlink = pjlink_test |
724 | pjlink.projector_errors = None |
725 | - log_warn_text = "127.0.0.1) Invalid error status response '11111111': length != 6" |
726 | + log_text = "127.0.0.1) Invalid error status response '11111111': length != 6" |
727 | |
728 | # WHEN: process_erst called with invalid data (too many values |
729 | pjlink.process_erst('11111111') |
730 | |
731 | # THEN: pjlink.projector_errors should be empty and warning logged |
732 | self.assertIsNone(pjlink.projector_errors, 'There should be no errors') |
733 | - self.assertTrue(mock_log.warn.called, 'Warning should have been logged') |
734 | - mock_log.warn.assert_called_once_with(log_warn_text) |
735 | + self.assertTrue(mock_log.warning.called, 'Warning should have been logged') |
736 | + mock_log.warning.assert_called_once_with(log_text) |
737 | |
738 | @patch.object(openlp.core.lib.projector.pjlink, 'log') |
739 | def test_projector_process_erst_data_invalid_nan(self, mock_log): |
740 | @@ -310,15 +672,15 @@ |
741 | # GIVEN: Test object |
742 | pjlink = pjlink_test |
743 | pjlink.projector_errors = None |
744 | - log_warn_text = "(127.0.0.1) Invalid error status response '1111Z1'" |
745 | + log_text = "(127.0.0.1) Invalid error status response '1111Z1'" |
746 | |
747 | # WHEN: process_erst called with invalid data (too many values |
748 | pjlink.process_erst('1111Z1') |
749 | |
750 | # THEN: pjlink.projector_errors should be empty and warning logged |
751 | self.assertIsNone(pjlink.projector_errors, 'There should be no errors') |
752 | - self.assertTrue(mock_log.warn.called, 'Warning should have been logged') |
753 | - mock_log.warn.assert_called_once_with(log_warn_text) |
754 | + self.assertTrue(mock_log.warning.called, 'Warning should have been logged') |
755 | + mock_log.warning.assert_called_once_with(log_text) |
756 | |
757 | def test_projector_process_erst_all_warn(self): |
758 | """ |
759 | @@ -399,33 +761,67 @@ |
760 | # THEN: Input selected should reflect current input |
761 | self.assertEqual(pjlink.source, '1', 'Input source should be set to "1"') |
762 | |
763 | - @patch.object(pjlink_test, 'projectorReceivedData') |
764 | - def test_projector_process_lamp_single(self, mock_projectorReceivedData): |
765 | - """ |
766 | - Test status lamp on/off and hours |
767 | - """ |
768 | - # GIVEN: Test object |
769 | - pjlink = pjlink_test |
770 | - |
771 | - # WHEN: Call process_command with lamp data |
772 | - pjlink.process_command('LAMP', '22222 1') |
773 | - |
774 | - # THEN: Lamp should have been set with status=ON and hours=22222 |
775 | + @patch.object(pjlink_test, 'projectorUpdateIcons') |
776 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
777 | + def test_projector_process_inst(self, mock_log, mock_UpdateIcons): |
778 | + """ |
779 | + Test saving video source available information |
780 | + """ |
781 | + # GIVEN: Test object |
782 | + pjlink = pjlink_test |
783 | + pjlink.source_available = [] |
784 | + test_data = '21 10 30 31 11 20' |
785 | + test_saved = ['10', '11', '20', '21', '30', '31'] |
786 | + log_data = '(127.0.0.1) Setting projector sources_available to ' \ |
787 | + '"[\'10\', \'11\', \'20\', \'21\', \'30\', \'31\']"' |
788 | + mock_UpdateIcons.reset_mock() |
789 | + mock_log.reset_mock() |
790 | + |
791 | + # WHEN: process_inst called with test data |
792 | + pjlink.process_inst(data=test_data) |
793 | + |
794 | + # THEN: Data should have been sorted and saved properly |
795 | + self.assertEqual(pjlink.source_available, test_saved, "Sources should have been sorted and saved") |
796 | + mock_log.debug.assert_called_once_with(log_data) |
797 | + self.assertTrue(mock_UpdateIcons.emit.called, 'Update Icons should have been called') |
798 | + |
799 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
800 | + def test_projector_process_lamp_invalid(self, mock_log): |
801 | + """ |
802 | + Test status multiple lamp on/off and hours |
803 | + """ |
804 | + # GIVEN: Test object |
805 | + pjlink = pjlink_test |
806 | + pjlink.lamp = [{'Hours': 00000, 'On': True}, |
807 | + {'Hours': 11111, 'On': False}] |
808 | + log_data = '(127.0.0.1) process_lamp(): Invalid data "11111 1 22222 0 333A3 1"' |
809 | + |
810 | + # WHEN: Call process_command with invalid lamp data |
811 | + pjlink.process_lamp('11111 1 22222 0 333A3 1') |
812 | + |
813 | + # THEN: lamps should not have changed |
814 | + self.assertEqual(len(pjlink.lamp), 2, |
815 | + 'Projector should have kept 2 lamps specified') |
816 | self.assertEqual(pjlink.lamp[0]['On'], True, |
817 | - 'Lamp power status should have been set to TRUE') |
818 | - self.assertEqual(pjlink.lamp[0]['Hours'], 22222, |
819 | - 'Lamp hours should have been set to 22222') |
820 | + 'Lamp 1 power status should have been set to TRUE') |
821 | + self.assertEqual(pjlink.lamp[0]['Hours'], 00000, |
822 | + 'Lamp 1 hours should have been left at 00000') |
823 | + self.assertEqual(pjlink.lamp[1]['On'], False, |
824 | + 'Lamp 2 power status should have been set to FALSE') |
825 | + self.assertEqual(pjlink.lamp[1]['Hours'], 11111, |
826 | + 'Lamp 2 hours should have been left at 11111') |
827 | + mock_log.warning.assert_called_once_with(log_data) |
828 | |
829 | - @patch.object(pjlink_test, 'projectorReceivedData') |
830 | - def test_projector_process_lamp_multiple(self, mock_projectorReceivedData): |
831 | + def test_projector_process_lamp_multiple(self): |
832 | """ |
833 | Test status multiple lamp on/off and hours |
834 | """ |
835 | # GIVEN: Test object |
836 | pjlink = pjlink_test |
837 | + pjlink.lamps = [] |
838 | |
839 | # WHEN: Call process_command with lamp data |
840 | - pjlink.process_command('LAMP', '11111 1 22222 0 33333 1') |
841 | + pjlink.process_lamp('11111 1 22222 0 33333 1') |
842 | |
843 | # THEN: Lamp should have been set with proper lamp status |
844 | self.assertEqual(len(pjlink.lamp), 3, |
845 | @@ -443,53 +839,112 @@ |
846 | self.assertEqual(pjlink.lamp[2]['Hours'], 33333, |
847 | 'Lamp 3 hours should have been set to 33333') |
848 | |
849 | - @patch.object(pjlink_test, 'projectorReceivedData') |
850 | + def test_projector_process_lamp_single(self): |
851 | + """ |
852 | + Test status lamp on/off and hours |
853 | + """ |
854 | + # GIVEN: Test object |
855 | + pjlink = pjlink_test |
856 | + pjlink.lamps = [] |
857 | + |
858 | + # WHEN: Call process_command with lamp data |
859 | + pjlink.process_lamp('22222 1') |
860 | + |
861 | + # THEN: Lamp should have been set with status=ON and hours=22222 |
862 | + self.assertEqual(pjlink.lamp[0]['On'], True, |
863 | + 'Lamp power status should have been set to TRUE') |
864 | + self.assertEqual(pjlink.lamp[0]['Hours'], 22222, |
865 | + 'Lamp hours should have been set to 22222') |
866 | + |
867 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
868 | + def test_projector_process_name(self, mock_log): |
869 | + """ |
870 | + Test saving NAME data from projector |
871 | + """ |
872 | + # GIVEN: Test data |
873 | + pjlink = pjlink_test |
874 | + test_data = "Some Name the End-User Set IN Projector" |
875 | + test_log = '(127.0.0.1) Setting projector PJLink name to "Some Name the End-User Set IN Projector"' |
876 | + mock_log.reset_mock() |
877 | + |
878 | + # WHEN: process_name called with test data |
879 | + pjlink.process_name(data=test_data) |
880 | + |
881 | + # THEN: name should be set and logged |
882 | + self.assertEqual(pjlink.pjlink_name, test_data, 'Name test data should have been saved') |
883 | + mock_log.debug.assert_called_once_with(test_log) |
884 | + |
885 | @patch.object(pjlink_test, 'projectorUpdateIcons') |
886 | @patch.object(pjlink_test, 'send_command') |
887 | @patch.object(pjlink_test, 'change_status') |
888 | def test_projector_process_powr_on(self, |
889 | mock_change_status, |
890 | mock_send_command, |
891 | - mock_UpdateIcons, |
892 | - mock_ReceivedData): |
893 | + mock_UpdateIcons): |
894 | """ |
895 | Test status power to ON |
896 | """ |
897 | # GIVEN: Test object and preset |
898 | pjlink = pjlink_test |
899 | pjlink.power = S_STANDBY |
900 | + test_data = PJLINK_POWR_STATUS[S_ON] |
901 | |
902 | # WHEN: Call process_command with turn power on command |
903 | - pjlink.process_command('POWR', PJLINK_POWR_STATUS[S_ON]) |
904 | + pjlink.process_command(cmd='POWR', data=test_data) |
905 | |
906 | # THEN: Power should be set to ON |
907 | self.assertEqual(pjlink.power, S_ON, 'Power should have been set to ON') |
908 | mock_send_command.assert_called_once_with('INST') |
909 | + mock_change_status.assert_called_once_with(PJLINK_POWR_STATUS[test_data]) |
910 | self.assertEqual(mock_UpdateIcons.emit.called, True, 'projectorUpdateIcons should have been called') |
911 | |
912 | - @patch.object(pjlink_test, 'projectorReceivedData') |
913 | + @patch.object(pjlink_test, 'projectorUpdateIcons') |
914 | + @patch.object(pjlink_test, 'send_command') |
915 | + @patch.object(pjlink_test, 'change_status') |
916 | + def test_projector_process_powr_invalid(self, |
917 | + mock_change_status, |
918 | + mock_send_command, |
919 | + mock_UpdateIcons): |
920 | + """ |
921 | + Test process_powr invalid call |
922 | + """ |
923 | + # GIVEN: Test object and preset |
924 | + pjlink = pjlink_test |
925 | + pjlink.power = S_STANDBY |
926 | + test_data = '99' |
927 | + |
928 | + # WHEN: Call process_command with turn power on command |
929 | + pjlink.process_command(cmd='POWR', data=test_data) |
930 | + |
931 | + # THEN: Power should be set to ON |
932 | + self.assertEqual(pjlink.power, S_STANDBY, 'Power should not have changed') |
933 | + self.assertFalse(mock_change_status.called, 'Change status should not have been called') |
934 | + self.assertFalse(mock_send_command.called, 'send_command("INST") should not have been called') |
935 | + self.assertFalse(mock_UpdateIcons.emit.called, 'projectorUpdateIcons should not have been called') |
936 | + |
937 | @patch.object(pjlink_test, 'projectorUpdateIcons') |
938 | @patch.object(pjlink_test, 'send_command') |
939 | @patch.object(pjlink_test, 'change_status') |
940 | def test_projector_process_powr_off(self, |
941 | mock_change_status, |
942 | mock_send_command, |
943 | - mock_UpdateIcons, |
944 | - mock_ReceivedData): |
945 | + mock_UpdateIcons): |
946 | """ |
947 | Test status power to STANDBY |
948 | """ |
949 | # GIVEN: Test object and preset |
950 | pjlink = pjlink_test |
951 | pjlink.power = S_ON |
952 | + test_data = PJLINK_POWR_STATUS[S_STANDBY] |
953 | |
954 | # WHEN: Call process_command with turn power on command |
955 | - pjlink.process_command('POWR', PJLINK_POWR_STATUS[S_STANDBY]) |
956 | + pjlink.process_command(cmd='POWR', data=test_data) |
957 | |
958 | # THEN: Power should be set to STANDBY |
959 | self.assertEqual(pjlink.power, S_STANDBY, 'Power should have been set to STANDBY') |
960 | - self.assertEqual(mock_send_command.called, False, 'send_command should not have been called') |
961 | self.assertEqual(mock_UpdateIcons.emit.called, True, 'projectorUpdateIcons should have been called') |
962 | + mock_change_status.assert_called_once_with(PJLINK_POWR_STATUS[test_data]) |
963 | + self.assertFalse(mock_send_command.called, "send_command['INST'] should not have been called") |
964 | |
965 | def test_projector_process_rfil_save(self): |
966 | """ |
967 | @@ -582,3 +1037,111 @@ |
968 | # THEN: Serial number should be set |
969 | self.assertNotEquals(pjlink.serial_no, test_number, |
970 | 'Projector serial number should NOT have been set') |
971 | + |
972 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
973 | + def test_projector_process_sver(self, mock_log): |
974 | + """ |
975 | + Test invalid software version information - too long |
976 | + """ |
977 | + # GIVEN: Test object |
978 | + pjlink = pjlink_test |
979 | + pjlink.sw_version = None |
980 | + pjlink.sw_version_received = None |
981 | + test_data = 'Test 1 Subtest 1' |
982 | + test_log = "(127.0.0.1) Setting projector software version to 'Test 1 Subtest 1'" |
983 | + mock_log.reset_mock() |
984 | + |
985 | + # WHEN: process_sver called with invalid data |
986 | + pjlink.process_sver(data=test_data) |
987 | + |
988 | + # THEN: Version information should not change |
989 | + self.assertEqual(pjlink.sw_version, test_data, 'Software version should have been updated') |
990 | + self.assertIsNone(pjlink.sw_version_received, 'Received software version should not have changed') |
991 | + mock_log.debug.assert_called_once_with(test_log) |
992 | + |
993 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
994 | + def test_projector_process_sver_changed(self, mock_log): |
995 | + """ |
996 | + Test invalid software version information - Received different than saved |
997 | + """ |
998 | + # GIVEN: Test object |
999 | + pjlink = pjlink_test |
1000 | + test_data_new = 'Test 1 Subtest 2' |
1001 | + test_data_old = 'Test 1 Subtest 1' |
1002 | + pjlink.sw_version = test_data_old |
1003 | + pjlink.sw_version_received = None |
1004 | + test_log = '(127.0.0.1) Saving new serial number as sw_version_received' |
1005 | + mock_log.reset_mock() |
1006 | + |
1007 | + # WHEN: process_sver called with invalid data |
1008 | + pjlink.process_sver(data=test_data_new) |
1009 | + |
1010 | + # THEN: Version information should not change |
1011 | + self.assertEqual(pjlink.sw_version, test_data_old, 'Software version should not have been updated') |
1012 | + self.assertEqual(pjlink.sw_version_received, test_data_new, |
1013 | + 'Received software version should have been changed') |
1014 | + self.assertEqual(mock_log.warning.call_count, 4, 'log.warn should have been called 4 times') |
1015 | + # There was 4 calls, but only the last one is checked with this method |
1016 | + mock_log.warning.assert_called_with(test_log) |
1017 | + |
1018 | + @patch.object(openlp.core.lib.projector.pjlink, 'log') |
1019 | + def test_projector_process_sver_invalid(self, mock_log): |
1020 | + """ |
1021 | + Test invalid software version information - too long |
1022 | + """ |
1023 | + # GIVEN: Test object |
1024 | + pjlink = pjlink_test |
1025 | + pjlink.sw_version = None |
1026 | + pjlink.sw_version_received = None |
1027 | + test_data = 'This is a test software version line that is too long based on PJLink version 2 specs' |
1028 | + test_log = "Invalid software version - too long" |
1029 | + mock_log.reset_mock() |
1030 | + |
1031 | + # WHEN: process_sver called with invalid data |
1032 | + pjlink.process_sver(data=test_data) |
1033 | + |
1034 | + # THEN: Version information should not change |
1035 | + self.assertIsNone(pjlink.sw_version, 'Software version should not have changed') |
1036 | + self.assertIsNone(pjlink.sw_version_received, 'Received software version should not have changed') |
1037 | + mock_log.warning.assert_called_once_with(test_log) |
1038 | + |
1039 | + def test_projector_reset_information(self): |
1040 | + """ |
1041 | + Test reset_information() resets all information and stops timers |
1042 | + """ |
1043 | + # GIVEN: Test object and test data |
1044 | + pjlink = pjlink_test |
1045 | + pjlink.power = S_ON |
1046 | + pjlink.pjlink_name = 'OPENLPTEST' |
1047 | + pjlink.manufacturer = 'PJLINK' |
1048 | + pjlink.model = '1' |
1049 | + pjlink.shutter = True |
1050 | + pjlink.mute = True |
1051 | + pjlink.lamp = True |
1052 | + pjlink.fan = True |
1053 | + pjlink.source_available = True |
1054 | + pjlink.other_info = 'ANOTHER TEST' |
1055 | + pjlink.send_queue = True |
1056 | + pjlink.send_busy = True |
1057 | + |
1058 | + # WHEN: reset_information() is called |
1059 | + with patch.object(pjlink, 'timer') as mock_timer: |
1060 | + with patch.object(pjlink, 'socket_timer') as mock_socket_timer: |
1061 | + pjlink.reset_information() |
1062 | + |
1063 | + # THEN: All information should be reset and timers stopped |
1064 | + self.assertEqual(pjlink.power, S_OFF, 'Projector power should be OFF') |
1065 | + self.assertIsNone(pjlink.pjlink_name, 'Projector pjlink_name should be None') |
1066 | + self.assertIsNone(pjlink.manufacturer, 'Projector manufacturer should be None') |
1067 | + self.assertIsNone(pjlink.model, 'Projector model should be None') |
1068 | + self.assertIsNone(pjlink.shutter, 'Projector shutter should be None') |
1069 | + self.assertIsNone(pjlink.mute, 'Projector shuttter should be None') |
1070 | + self.assertIsNone(pjlink.lamp, 'Projector lamp should be None') |
1071 | + self.assertIsNone(pjlink.fan, 'Projector fan should be None') |
1072 | + self.assertIsNone(pjlink.source_available, 'Projector source_available should be None') |
1073 | + self.assertIsNone(pjlink.source, 'Projector source should be None') |
1074 | + self.assertIsNone(pjlink.other_info, 'Projector other_info should be None') |
1075 | + self.assertEqual(pjlink.send_queue, [], 'Projector send_queue should be an empty list') |
1076 | + self.assertFalse(pjlink.send_busy, 'Projector send_busy should be False') |
1077 | + self.assertTrue(mock_timer.stop.called, 'Projector timer.stop() should have been called') |
1078 | + self.assertTrue(mock_socket_timer.stop.called, 'Projector socket_timer.stop() should have been called') |
See inline