Merge lp:~alisonken1/openlp/bug-1734275 into lp:openlp

Proposed by Ken Roberts
Status: Superseded
Proposed branch: lp:~alisonken1/openlp/bug-1734275
Merge into: lp:openlp
Diff against target: 314 lines (+158/-98)
5 files modified
openlp/core/projectors/manager.py (+7/-5)
openlp/core/projectors/pjlink.py (+14/-11)
tests/functional/openlp_core/projectors/test_projector_bugfixes_01.py (+136/-0)
tests/functional/openlp_core/projectors/test_projector_pjlink_base.py (+1/-53)
tests/functional/openlp_core/projectors/test_projector_pjlink_commands.py (+0/-29)
To merge this branch: bzr merge lp:~alisonken1/openlp/bug-1734275
Reviewer Review Type Date Requested Status
Phill Needs Fixing
Review via email: mp+334224@code.launchpad.net

This proposal has been superseded by a proposal from 2017-11-24.

Commit message

Bugfix 1734275 - PJLink non-standard response to LAMP command

Description of the change

- Fix non-standard LAMP response (bug 1734275)
- Moved bugfix tests to separate file
- Added test for non-standard LAMP response

--------------------------------------------------------------------------------
lp:~alisonken1/openlp/bug-1734275 (revision 2791)
https://ci.openlp.io/job/Branch-01-Pull/2309/ [SUCCESS]
https://ci.openlp.io/job/Branch-02-Functional-Tests/2210/ [SUCCESS]
https://ci.openlp.io/job/Branch-03-Interface-Tests/2086/ [SUCCESS]
https://ci.openlp.io/job/Branch-04a-Code_Analysis/1412/ [SUCCESS]
https://ci.openlp.io/job/Branch-04b-Test_Coverage/1235/ [SUCCESS]
https://ci.openlp.io/job/Branch-04c-Code_Analysis2/365/ [SUCCESS]
https://ci.openlp.io/job/Branch-05-AppVeyor-Tests/196/ [FAILURE]

To post a comment you must log in.
Revision history for this message
Phill (phill-ridout) wrote :

A few inline comments, nothing major Sorry if it seems like I be tripping on my new status! :-p

review: Needs Fixing
lp:~alisonken1/openlp/bug-1734275 updated
2792. By Ken Roberts

Refactor mocks

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/core/projectors/manager.py'
2--- openlp/core/projectors/manager.py 2017-11-10 11:59:38 +0000
3+++ openlp/core/projectors/manager.py 2017-11-24 16:27:30 +0000
4@@ -672,14 +672,16 @@
5 data=projector.model_filter)
6 count = 1
7 for item in projector.link.lamp:
8+ if item['On'] is None:
9+ status = translate('OpenLP.ProjectorManager', 'Unavailable')
10+ elif item['On']:
11+ status = translate('OpenLP.ProjectorManager', 'ON')
12+ else:
13+ status = translate('OpenLP.ProjectorManager', 'OFF')
14 message += '<b>{title} {count}</b> {status} '.format(title=translate('OpenLP.ProjectorManager',
15 'Lamp'),
16 count=count,
17- status=translate('OpenLP.ProjectorManager',
18- 'ON')
19- if item['On']
20- else translate('OpenLP.ProjectorManager',
21- 'OFF'))
22+ status=status)
23
24 message += '<b>{title}</b>: {hours}<br />'.format(title=translate('OpenLP.ProjectorManager', 'Hours'),
25 hours=item['Hours'])
26
27=== modified file 'openlp/core/projectors/pjlink.py'
28--- openlp/core/projectors/pjlink.py 2017-11-10 11:59:38 +0000
29+++ openlp/core/projectors/pjlink.py 2017-11-24 16:27:30 +0000
30@@ -402,17 +402,20 @@
31 :param data: Lamp(s) status.
32 """
33 lamps = []
34- data_dict = data.split()
35- while data_dict:
36- try:
37- fill = {'Hours': int(data_dict[0]), 'On': False if data_dict[1] == '0' else True}
38- except ValueError:
39- # In case of invalid entry
40- log.warning('({ip}) process_lamp(): Invalid data "{data}"'.format(ip=self.ip, data=data))
41- return
42- lamps.append(fill)
43- data_dict.pop(0) # Remove lamp hours
44- data_dict.pop(0) # Remove lamp on/off
45+ lamp_list = data.split()
46+ if len(lamp_list) < 2:
47+ lamps.append({'Hours': int(lamp_list[0]), 'On': None})
48+ else:
49+ while lamp_list:
50+ try:
51+ fill = {'Hours': int(lamp_list[0]), 'On': False if lamp_list[1] == '0' else True}
52+ except ValueError:
53+ # In case of invalid entry
54+ log.warning('({ip}) process_lamp(): Invalid data "{data}"'.format(ip=self.ip, data=data))
55+ return
56+ lamps.append(fill)
57+ lamp_list.pop(0) # Remove lamp hours
58+ lamp_list.pop(0) # Remove lamp on/off
59 self.lamp = lamps
60 return
61
62
63=== added file 'tests/functional/openlp_core/projectors/test_projector_bugfixes_01.py'
64--- tests/functional/openlp_core/projectors/test_projector_bugfixes_01.py 1970-01-01 00:00:00 +0000
65+++ tests/functional/openlp_core/projectors/test_projector_bugfixes_01.py 2017-11-24 16:27:30 +0000
66@@ -0,0 +1,136 @@
67+# -*- coding: utf-8 -*-
68+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
69+
70+###############################################################################
71+# OpenLP - Open Source Lyrics Projection #
72+# --------------------------------------------------------------------------- #
73+# Copyright (c) 2008-2015 OpenLP Developers #
74+# --------------------------------------------------------------------------- #
75+# This program is free software; you can redistribute it and/or modify it #
76+# under the terms of the GNU General Public License as published by the Free #
77+# Software Foundation; version 2 of the License. #
78+# #
79+# This program is distributed in the hope that it will be useful, but WITHOUT #
80+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
81+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
82+# more details. #
83+# #
84+# You should have received a copy of the GNU General Public License along #
85+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
86+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
87+###############################################################################
88+"""
89+Package to test the openlp.core.projectors.pjlink base package.
90+"""
91+from unittest import TestCase
92+from unittest.mock import patch
93+
94+from openlp.core.projectors.db import Projector
95+from openlp.core.projectors.pjlink import PJLink
96+
97+from tests.resources.projector.data import TEST_PIN, TEST_CONNECT_AUTHENTICATE, TEST_HASH, TEST1_DATA
98+
99+pjlink_test = PJLink(Projector(**TEST1_DATA), no_poll=True)
100+
101+
102+class TestPJLinkBugs(TestCase):
103+ """
104+ Tests for the PJLink module bugfixes
105+ """
106+ def setUp(self):
107+ '''
108+ Initialization
109+ '''
110+ self.pjlink_test = PJLink(Projector(**TEST1_DATA), no_poll=True)
111+
112+ def tearDown(self):
113+ '''
114+ Cleanups
115+ '''
116+ self.pjlink_test = None
117+
118+ def test_bug_1550891_process_clss_nonstandard_reply_1(self):
119+ """
120+ Bugfix 1550891: CLSS request returns non-standard reply with Optoma/Viewsonic projector
121+ """
122+ # GIVEN: Test object
123+ pjlink = self.pjlink_test
124+
125+ # WHEN: Process non-standard reply
126+ pjlink.process_clss('Class 1')
127+
128+ # THEN: Projector class should be set with proper value
129+ self.assertEqual(pjlink.pjlink_class, '1',
130+ 'Non-standard class reply should have set class=1')
131+
132+ def test_bug_1550891_process_clss_nonstandard_reply_2(self):
133+ """
134+ Bugfix 1550891: CLSS request returns non-standard reply with BenQ projector
135+ """
136+ # GIVEN: Test object
137+ pjlink = self.pjlink_test
138+
139+ # WHEN: Process non-standard reply
140+ pjlink.process_clss('Version2')
141+
142+ # THEN: Projector class should be set with proper value
143+ # NOTE: At this time BenQ is Class 1, but we're trying a different value to verify
144+ self.assertEqual(pjlink.pjlink_class, '2',
145+ 'Non-standard class reply should have set class=2')
146+
147+ def test_bug_1593882_no_pin_authenticated_connection(self):
148+ """
149+ Test bug 1593882 no pin and authenticated request exception
150+ """
151+ # GIVEN: Test object and mocks
152+ mock_socket_timer = patch.object(self.pjlink_test, 'socket_timer').start()
153+ mock_timer = patch.object(self.pjlink_test, 'timer').start()
154+ mock_authentication = patch.object(self.pjlink_test, 'projectorAuthentication').start()
155+ mock_ready_read = patch.object(self.pjlink_test, 'waitForReadyRead').start()
156+ mock_send_command = patch.object(self.pjlink_test, 'send_command').start()
157+ pjlink = self.pjlink_test
158+ pjlink.pin = None
159+ mock_ready_read.return_value = True
160+
161+ # WHEN: call with authentication request and pin not set
162+ pjlink.check_login(data=TEST_CONNECT_AUTHENTICATE)
163+
164+ # THEN: 'No Authentication' signal should have been sent
165+ mock_authentication.emit.assert_called_with(pjlink.ip)
166+
167+ def test_bug_1593883_pjlink_authentication(self):
168+ """
169+ Test bugfix 1593883 pjlink authentication
170+ """
171+ # GIVEN: Test object and data
172+ mock_socket_timer = patch.object(self.pjlink_test, 'socket_timer').start()
173+ mock_timer = patch.object(self.pjlink_test, 'timer').start()
174+ mock_send_command = patch.object(self.pjlink_test, 'write').start()
175+ mock_state = patch.object(self.pjlink_test, 'state').start()
176+ mock_waitForReadyRead = patch.object(self.pjlink_test, 'waitForReadyRead').start()
177+ pjlink = self.pjlink_test
178+ pjlink.pin = TEST_PIN
179+ mock_state.return_value = pjlink.ConnectedState
180+ mock_waitForReadyRead.return_value = True
181+
182+ # WHEN: Athenticated connection is called
183+ pjlink.check_login(data=TEST_CONNECT_AUTHENTICATE)
184+
185+ # THEN: send_command should have the proper authentication
186+ self.assertEqual("{test}".format(test=mock_send_command.call_args),
187+ "call(b'{hash}%1CLSS ?\\r')".format(hash=TEST_HASH))
188+
189+ def test_bug_1734275_process_lamp_nonstandard_reply(self):
190+ """
191+ Test bugfix 17342785 non-standard LAMP response
192+ """
193+ # GIVEN: Test object
194+ pjlink = self.pjlink_test
195+
196+ # WHEN: Process lamp command called with only hours and no lamp power state
197+ pjlink.process_lamp("45")
198+
199+ # THEN: Lamp should show hours as 45 and lamp power as Unavailable
200+ self.assertEqual(len(pjlink.lamp), 1, 'There should only be 1 lamp available')
201+ self.assertEqual(pjlink.lamp[0]['Hours'], 45, 'Lamp hours should have equalled 45')
202+ self.assertIsNone(pjlink.lamp[0]['On'], 'Lamp power should be "None"')
203
204=== modified file 'tests/functional/openlp_core/projectors/test_projector_pjlink_base.py'
205--- tests/functional/openlp_core/projectors/test_projector_pjlink_base.py 2017-11-16 23:53:53 +0000
206+++ tests/functional/openlp_core/projectors/test_projector_pjlink_base.py 2017-11-24 16:27:30 +0000
207@@ -29,7 +29,7 @@
208 from openlp.core.projectors.db import Projector
209 from openlp.core.projectors.pjlink import PJLink
210
211-from tests.resources.projector.data import TEST_PIN, TEST_SALT, TEST_CONNECT_AUTHENTICATE, TEST_HASH, TEST1_DATA
212+from tests.resources.projector.data import TEST_PIN, TEST_SALT, TEST_CONNECT_AUTHENTICATE, TEST1_DATA
213
214 pjlink_test = PJLink(Projector(**TEST1_DATA), no_poll=True)
215
216@@ -79,58 +79,6 @@
217 'change_status should have been called with "{}"'.format(
218 ERROR_STRING[E_PARAMETER]))
219
220- @patch.object(pjlink_test, 'send_command')
221- @patch.object(pjlink_test, 'waitForReadyRead')
222- @patch.object(pjlink_test, 'projectorAuthentication')
223- @patch.object(pjlink_test, 'timer')
224- @patch.object(pjlink_test, 'socket_timer')
225- def test_bug_1593882_no_pin_authenticated_connection(self,
226- mock_socket_timer,
227- mock_timer,
228- mock_authentication,
229- mock_ready_read,
230- mock_send_command):
231- """
232- Test bug 1593882 no pin and authenticated request exception
233- """
234- # GIVEN: Test object and mocks
235- pjlink = pjlink_test
236- pjlink.pin = None
237- mock_ready_read.return_value = True
238-
239- # WHEN: call with authentication request and pin not set
240- pjlink.check_login(data=TEST_CONNECT_AUTHENTICATE)
241-
242- # THEN: 'No Authentication' signal should have been sent
243- mock_authentication.emit.assert_called_with(pjlink.ip)
244-
245- @patch.object(pjlink_test, 'waitForReadyRead')
246- @patch.object(pjlink_test, 'state')
247- @patch.object(pjlink_test, '_send_command')
248- @patch.object(pjlink_test, 'timer')
249- @patch.object(pjlink_test, 'socket_timer')
250- def test_bug_1593883_pjlink_authentication(self,
251- mock_socket_timer,
252- mock_timer,
253- mock_send_command,
254- mock_state,
255- mock_waitForReadyRead):
256- """
257- Test bugfix 1593883 pjlink authentication
258- """
259- # GIVEN: Test object and data
260- pjlink = pjlink_test
261- pjlink.pin = TEST_PIN
262- mock_state.return_value = pjlink.ConnectedState
263- mock_waitForReadyRead.return_value = True
264-
265- # WHEN: Athenticated connection is called
266- pjlink.check_login(data=TEST_CONNECT_AUTHENTICATE)
267-
268- # THEN: send_command should have the proper authentication
269- self.assertEqual("{test}".format(test=mock_send_command.call_args),
270- "call(data='{hash}%1CLSS ?\\r')".format(hash=TEST_HASH))
271-
272 @patch.object(pjlink_test, 'disconnect_from_host')
273 def test_socket_abort(self, mock_disconnect):
274 """
275
276=== modified file 'tests/functional/openlp_core/projectors/test_projector_pjlink_commands.py'
277--- tests/functional/openlp_core/projectors/test_projector_pjlink_commands.py 2017-11-16 23:53:53 +0000
278+++ tests/functional/openlp_core/projectors/test_projector_pjlink_commands.py 2017-11-24 16:27:30 +0000
279@@ -570,35 +570,6 @@
280 self.assertEqual(pjlink.pjlink_class, '2',
281 'Projector should have set class=2')
282
283- def test_projector_process_clss_nonstandard_reply_optoma(self):
284- """
285- Bugfix 1550891: CLSS request returns non-standard reply with Optoma projector
286- """
287- # GIVEN: Test object
288- pjlink = pjlink_test
289-
290- # WHEN: Process non-standard reply
291- pjlink.process_clss('Class 1')
292-
293- # THEN: Projector class should be set with proper value
294- self.assertEqual(pjlink.pjlink_class, '1',
295- 'Non-standard class reply should have set class=1')
296-
297- def test_projector_process_clss_nonstandard_reply_benq(self):
298- """
299- Bugfix 1550891: CLSS request returns non-standard reply with BenQ projector
300- """
301- # GIVEN: Test object
302- pjlink = pjlink_test
303-
304- # WHEN: Process non-standard reply
305- pjlink.process_clss('Version2')
306-
307- # THEN: Projector class should be set with proper value
308- # NOTE: At this time BenQ is Class 1, but we're trying a different value to verify
309- self.assertEqual(pjlink.pjlink_class, '2',
310- 'Non-standard class reply should have set class=2')
311-
312 @patch.object(openlp.core.projectors.pjlink, 'log')
313 def test_projector_process_clss_invalid_nan(self, mock_log):
314 """