Merge lp:~alisonken1/openlp/pjlink2-c into lp:openlp

Proposed by Ken Roberts
Status: Merged
Merged at revision: 2740
Proposed branch: lp:~alisonken1/openlp/pjlink2-c
Merge into: lp:openlp
Prerequisite: lp:~alisonken1/openlp/pjlink2-c-resources
Diff against target: 496 lines (+122/-63)
8 files modified
openlp/core/lib/__init__.py (+1/-1)
openlp/core/lib/projector/db.py (+36/-19)
openlp/core/lib/projector/pjlink1.py (+11/-9)
openlp/core/ui/projector/manager.py (+13/-13)
tests/functional/openlp_core_lib/test_projector_constants.py (+0/-1)
tests/functional/openlp_core_lib/test_projector_pjlink1.py (+27/-12)
tests/functional/openlp_core_lib/test_projectordb.py (+17/-5)
tests/resources/projector/data.py (+17/-3)
To merge this branch: bzr merge lp:~alisonken1/openlp/pjlink2-c
Reviewer Review Type Date Requested Status
Tomas Groth Approve
Tim Bentley Approve
Review via email: mp+324360@code.launchpad.net

Description of the change

-- Update test data for Class 2 tests
-- Update Projector() db class with new data
-- Update test_projectordb tests
-- Rename PJLink1 class to PJLink
-- Fix/update power on/off tests (Qt error not caught properly during test)
-- Remove skip from projector constants test

--------------------------------
lp:~alisonken1/openlp/pjlink2-c (revision 2739)
[SUCCESS] https://ci.openlp.io/job/Branch-01-Pull/2020/
[SUCCESS] https://ci.openlp.io/job/Branch-02-Functional-Tests/1930/
[SUCCESS] https://ci.openlp.io/job/Branch-03-Interface-Tests/1865/
[SUCCESS] https://ci.openlp.io/job/Branch-04a-Code_Analysis/1245/
[SUCCESS] https://ci.openlp.io/job/Branch-04b-Test_Coverage/1103/
[SUCCESS] https://ci.openlp.io/job/Branch-04c-Code_Analysis2/232/
[FAILURE] https://ci.openlp.io/job/Branch-05-AppVeyor-Tests/80/

To post a comment you must log in.
Revision history for this message
Tim Bentley (trb143) :
review: Approve
Revision history for this message
Tomas Groth (tomasgroth) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/core/lib/__init__.py'
2--- openlp/core/lib/__init__.py 2017-05-17 20:06:45 +0000
3+++ openlp/core/lib/__init__.py 2017-05-20 06:06:27 +0000
4@@ -621,5 +621,5 @@
5 from .renderer import Renderer
6 from .mediamanageritem import MediaManagerItem
7 from .projector.db import ProjectorDB, Projector
8-from .projector.pjlink1 import PJLink1
9+from .projector.pjlink1 import PJLink
10 from .projector.constants import PJLINK_PORT, ERROR_MSG, ERROR_STRING
11
12=== modified file 'openlp/core/lib/projector/db.py'
13--- openlp/core/lib/projector/db.py 2016-12-31 11:01:36 +0000
14+++ openlp/core/lib/projector/db.py 2017-05-20 06:06:27 +0000
15@@ -150,11 +150,15 @@
16 name: Column(String(20))
17 location: Column(String(30))
18 notes: Column(String(200))
19- pjlink_name: Column(String(128)) # From projector (future)
20- manufacturer: Column(String(128)) # From projector (future)
21- model: Column(String(128)) # From projector (future)
22- other: Column(String(128)) # From projector (future)
23- sources: Column(String(128)) # From projector (future)
24+ pjlink_name: Column(String(128)) # From projector
25+ manufacturer: Column(String(128)) # From projector
26+ model: Column(String(128)) # From projector
27+ other: Column(String(128)) # From projector
28+ sources: Column(String(128)) # From projector
29+ serial_no: Column(String(30)) # From projector (Class 2)
30+ sw_version: Column(String(30)) # From projector (Class 2)
31+ model_filter: Column(String(30)) # From projector (Class 2)
32+ model_lamp: Column(String(30)) # From projector (Class 2)
33
34 ProjectorSource relates
35 """
36@@ -164,20 +168,25 @@
37 """
38 return '< Projector(id="{data}", ip="{ip}", port="{port}", pin="{pin}", name="{name}", ' \
39 'location="{location}", notes="{notes}", pjlink_name="{pjlink_name}", ' \
40- 'manufacturer="{manufacturer}", model="{model}", other="{other}", ' \
41- 'sources="{sources}", source_list="{source_list}") >'.format(data=self.id,
42- ip=self.ip,
43- port=self.port,
44- pin=self.pin,
45- name=self.name,
46- location=self.location,
47- notes=self.notes,
48- pjlink_name=self.pjlink_name,
49- manufacturer=self.manufacturer,
50- model=self.model,
51- other=self.other,
52- sources=self.sources,
53- source_list=self.source_list)
54+ 'manufacturer="{manufacturer}", model="{model}", serial_no="{serial}", other="{other}", ' \
55+ 'sources="{sources}", source_list="{source_list}", model_filter="{mfilter}", ' \
56+ 'model_lamp="{mlamp}", sw_version="{sw_ver}") >'.format(data=self.id,
57+ ip=self.ip,
58+ port=self.port,
59+ pin=self.pin,
60+ name=self.name,
61+ location=self.location,
62+ notes=self.notes,
63+ pjlink_name=self.pjlink_name,
64+ manufacturer=self.manufacturer,
65+ model=self.model,
66+ other=self.other,
67+ sources=self.sources,
68+ source_list=self.source_list,
69+ serial=self.serial_no,
70+ mfilter=self.model_filter,
71+ mlamp=self.model_lamp,
72+ sw_ver=self.sw_version)
73 ip = Column(String(100))
74 port = Column(String(8))
75 pin = Column(String(20))
76@@ -189,6 +198,10 @@
77 model = Column(String(128))
78 other = Column(String(128))
79 sources = Column(String(128))
80+ serial_no = Column(String(30))
81+ sw_version = Column(String(30))
82+ model_filter = Column(String(30))
83+ model_lamp = Column(String(30))
84 source_list = relationship('ProjectorSource',
85 order_by='ProjectorSource.code',
86 backref='projector',
87@@ -359,6 +372,10 @@
88 old_projector.model = projector.model
89 old_projector.other = projector.other
90 old_projector.sources = projector.sources
91+ old_projector.serial_no = projector.serial_no
92+ old_projector.sw_version = projector.sw_version
93+ old_projector.model_filter = projector.model_filter
94+ old_projector.model_lamp = projector.model_lamp
95 return self.save_object(old_projector)
96
97 def delete_projector(self, projector):
98
99=== modified file 'openlp/core/lib/projector/pjlink1.py'
100--- openlp/core/lib/projector/pjlink1.py 2017-05-17 20:35:43 +0000
101+++ openlp/core/lib/projector/pjlink1.py 2017-05-20 06:06:27 +0000
102@@ -42,7 +42,7 @@
103
104 log.debug('pjlink1 loaded')
105
106-__all__ = ['PJLink1']
107+__all__ = ['PJLink']
108
109 from codecs import decode
110
111@@ -68,7 +68,7 @@
112 PJLINK_SUFFIX = CR
113
114
115-class PJLink1(QtNetwork.QTcpSocket):
116+class PJLink(QtNetwork.QTcpSocket):
117 """
118 Socket service for connecting to a PJLink-capable projector.
119 """
120@@ -129,7 +129,7 @@
121 self.ip = ip
122 self.port = port
123 self.pin = pin
124- super(PJLink1, self).__init__()
125+ super(PJLink, self).__init__()
126 self.dbid = None
127 self.location = None
128 self.notes = None
129@@ -162,7 +162,7 @@
130 # Socket timer for some possible brain-dead projectors or network cable pulled
131 self.socket_timer = None
132 # Map command to function
133- self.pjlink1_functions = {
134+ self.pjlink_functions = {
135 'AVMT': self.process_avmt,
136 'CLSS': self.process_clss,
137 'ERST': self.process_erst,
138@@ -286,7 +286,7 @@
139 elif status in STATUS_STRING:
140 return STATUS_STRING[status], ERROR_MSG[status]
141 else:
142- return status, translate('OpenLP.PJLink1', 'Unknown status')
143+ return status, translate('OpenLP.PJLink', 'Unknown status')
144
145 def change_status(self, status, msg=None):
146 """
147@@ -296,7 +296,7 @@
148 :param status: Status code
149 :param msg: Optional message
150 """
151- message = translate('OpenLP.PJLink1', 'No message') if msg is None else msg
152+ message = translate('OpenLP.PJLink', 'No message') if msg is None else msg
153 (code, message) = self._get_status(status)
154 if msg is not None:
155 message = msg
156@@ -576,7 +576,7 @@
157 if sent == -1:
158 # Network error?
159 self.change_status(E_NETWORK,
160- translate('OpenLP.PJLink1', 'Error while sending data to projector'))
161+ translate('OpenLP.PJLink', 'Error while sending data to projector'))
162
163 def process_command(self, cmd, data):
164 """
165@@ -625,8 +625,9 @@
166 self.projectorReceivedData.emit()
167 return
168
169- if cmd in self.pjlink1_functions:
170- self.pjlink1_functions[cmd](data)
171+ if cmd in self.pjlink_functions:
172+ log.debug('({ip}) Calling function for {cmd}'.format(ip=self.ip, cmd=cmd))
173+ self.pjlink_functions[cmd](data)
174 else:
175 log.warning('({ip}) Invalid command {data}'.format(ip=self.ip, data=cmd))
176 self.send_busy = False
177@@ -662,6 +663,7 @@
178
179 :param data: Power status
180 """
181+ log.debug('({ip}: Processing POWR command'.format(ip=self.ip))
182 if data in PJLINK_POWR_STATUS:
183 power = PJLINK_POWR_STATUS[data]
184 update_icons = self.power != power
185
186=== modified file 'openlp/core/ui/projector/manager.py'
187--- openlp/core/ui/projector/manager.py 2016-12-31 11:01:36 +0000
188+++ openlp/core/ui/projector/manager.py 2017-05-20 06:06:27 +0000
189@@ -38,7 +38,7 @@
190 E_NETWORK, E_NOT_CONNECTED, E_UNKNOWN_SOCKET_ERROR, STATUS_STRING, S_CONNECTED, S_CONNECTING, S_COOLDOWN, \
191 S_INITIALIZE, S_NOT_CONNECTED, S_OFF, S_ON, S_STANDBY, S_WARMUP
192 from openlp.core.lib.projector.db import ProjectorDB
193-from openlp.core.lib.projector.pjlink1 import PJLink1
194+from openlp.core.lib.projector.pjlink1 import PJLink
195 from openlp.core.ui.projector.editform import ProjectorEditForm
196 from openlp.core.ui.projector.sourceselectform import SourceSelectTabs, SourceSelectSingle
197
198@@ -690,19 +690,19 @@
199 Helper app to build a projector instance
200
201 :param projector: Dict of projector database information
202- :returns: PJLink1() instance
203+ :returns: PJLink() instance
204 """
205 log.debug('_add_projector()')
206- return PJLink1(dbid=projector.id,
207- ip=projector.ip,
208- port=int(projector.port),
209- name=projector.name,
210- location=projector.location,
211- notes=projector.notes,
212- pin=None if projector.pin == '' else projector.pin,
213- poll_time=self.poll_time,
214- socket_timeout=self.socket_timeout
215- )
216+ return PJLink(dbid=projector.id,
217+ ip=projector.ip,
218+ port=int(projector.port),
219+ name=projector.name,
220+ location=projector.location,
221+ notes=projector.notes,
222+ pin=None if projector.pin == '' else projector.pin,
223+ poll_time=self.poll_time,
224+ socket_timeout=self.socket_timeout
225+ )
226
227 def add_projector(self, projector, start=False):
228 """
229@@ -961,7 +961,7 @@
230 """
231 Initialization for ProjectorItem instance
232
233- :param link: PJLink1 instance for QListWidgetItem
234+ :param link: PJLink instance for QListWidgetItem
235 """
236 self.link = link
237 self.thread = None
238
239=== modified file 'tests/functional/openlp_core_lib/test_projector_constants.py'
240--- tests/functional/openlp_core_lib/test_projector_constants.py 2017-05-12 09:51:56 +0000
241+++ tests/functional/openlp_core_lib/test_projector_constants.py 2017-05-20 06:06:27 +0000
242@@ -29,7 +29,6 @@
243 """
244 Test specific functions in the projector constants module.
245 """
246- @skip('Waiting for merge of ~alisonken1/openlp/pjlink2-resource-data')
247 def build_pjlink_video_label_test(self):
248 """
249 Test building PJLINK_DEFAULT_CODES dictionary
250
251=== modified file 'tests/functional/openlp_core_lib/test_projector_pjlink1.py'
252--- tests/functional/openlp_core_lib/test_projector_pjlink1.py 2017-05-13 09:00:29 +0000
253+++ tests/functional/openlp_core_lib/test_projector_pjlink1.py 2017-05-20 06:06:27 +0000
254@@ -25,13 +25,13 @@
255 from unittest import TestCase
256 from unittest.mock import call, patch, MagicMock
257
258-from openlp.core.lib.projector.pjlink1 import PJLink1
259+from openlp.core.lib.projector.pjlink1 import PJLink
260 from openlp.core.lib.projector.constants import E_PARAMETER, ERROR_STRING, S_OFF, S_STANDBY, S_ON, \
261 PJLINK_POWR_STATUS, S_CONNECTED
262
263 from tests.resources.projector.data import TEST_PIN, TEST_SALT, TEST_CONNECT_AUTHENTICATE, TEST_HASH
264
265-pjlink_test = PJLink1(name='test', ip='127.0.0.1', pin=TEST_PIN, no_poll=True)
266+pjlink_test = PJLink(name='test', ip='127.0.0.1', pin=TEST_PIN, no_poll=True)
267
268
269 class TestPJLink(TestCase):
270@@ -164,23 +164,36 @@
271 'Lamp 3 hours should have been set to 33333')
272
273 @patch.object(pjlink_test, 'projectorReceivedData')
274- def test_projector_process_power_on(self, mock_projectorReceivedData):
275+ @patch.object(pjlink_test, 'projectorUpdateIcons')
276+ @patch.object(pjlink_test, 'send_command')
277+ @patch.object(pjlink_test, 'change_status')
278+ def test_projector_process_power_on(self, mock_change_status,
279+ mock_send_command,
280+ mock_UpdateIcons,
281+ mock_ReceivedData):
282 """
283 Test status power to ON
284 """
285 # GIVEN: Test object and preset
286 pjlink = pjlink_test
287 pjlink.power = S_STANDBY
288- pjlink.socket_timer = MagicMock()
289
290 # WHEN: Call process_command with turn power on command
291 pjlink.process_command('POWR', PJLINK_POWR_STATUS[S_ON])
292
293 # THEN: Power should be set to ON
294 self.assertEquals(pjlink.power, S_ON, 'Power should have been set to ON')
295+ mock_send_command.assert_called_once_with('INST')
296+ self.assertEquals(mock_UpdateIcons.emit.called, True, 'projectorUpdateIcons should have been called')
297
298 @patch.object(pjlink_test, 'projectorReceivedData')
299- def test_projector_process_power_off(self, mock_projectorReceivedData):
300+ @patch.object(pjlink_test, 'projectorUpdateIcons')
301+ @patch.object(pjlink_test, 'send_command')
302+ @patch.object(pjlink_test, 'change_status')
303+ def test_projector_process_power_off(self, mock_change_status,
304+ mock_send_command,
305+ mock_UpdateIcons,
306+ mock_ReceivedData):
307 """
308 Test status power to STANDBY
309 """
310@@ -193,6 +206,8 @@
311
312 # THEN: Power should be set to STANDBY
313 self.assertEquals(pjlink.power, S_STANDBY, 'Power should have been set to STANDBY')
314+ self.assertEquals(mock_send_command.called, False, 'send_command should not have been called')
315+ self.assertEquals(mock_UpdateIcons.emit.called, True, 'projectorUpdateIcons should have been called')
316
317 @patch.object(pjlink_test, 'projectorUpdateIcons')
318 def test_projector_process_avmt_closed_unmuted(self, mock_projectorReceivedData):
319@@ -372,7 +387,7 @@
320 @patch.object(pjlink_test, '_not_implemented')
321 def not_implemented_test(self, mock_not_implemented):
322 """
323- Test pjlink1._not_implemented method being called
324+ Test PJLink._not_implemented method being called
325 """
326 # GIVEN: test object
327 pjlink = pjlink_test
328@@ -381,13 +396,13 @@
329 # WHEN: A future command is called that is not implemented yet
330 pjlink.process_command(test_cmd, "Garbage data for test only")
331
332- # THEN: pjlink1.__not_implemented should have been called with test_cmd
333+ # THEN: PJLink.__not_implemented should have been called with test_cmd
334 mock_not_implemented.assert_called_with(test_cmd)
335
336 @patch.object(pjlink_test, 'disconnect_from_host')
337 def socket_abort_test(self, mock_disconnect):
338 """
339- Test PJLink1.socket_abort calls disconnect_from_host
340+ Test PJLink.socket_abort calls disconnect_from_host
341 """
342 # GIVEN: Test object
343 pjlink = pjlink_test
344@@ -400,7 +415,7 @@
345
346 def poll_loop_not_connected_test(self):
347 """
348- Test PJLink1.poll_loop not connected return
349+ Test PJLink.poll_loop not connected return
350 """
351 # GIVEN: Test object and mocks
352 pjlink = pjlink_test
353@@ -409,7 +424,7 @@
354 pjlink.state.return_value = False
355 pjlink.ConnectedState = True
356
357- # WHEN: PJLink1.poll_loop called
358+ # WHEN: PJLink.poll_loop called
359 pjlink.poll_loop()
360
361 # THEN: poll_loop should exit without calling any other method
362@@ -418,7 +433,7 @@
363 @patch.object(pjlink_test, 'send_command')
364 def poll_loop_start_test(self, mock_send_command):
365 """
366- Test PJLink1.poll_loop makes correct calls
367+ Test PJLink.poll_loop makes correct calls
368 """
369 # GIVEN: test object and test data
370 pjlink = pjlink_test
371@@ -450,7 +465,7 @@
372 call('NAME', queue=True),
373 ]
374
375- # WHEN: PJLink1.poll_loop is called
376+ # WHEN: PJLink.poll_loop is called
377 pjlink.poll_loop()
378
379 # THEN: proper calls were made to retrieve projector data
380
381=== modified file 'tests/functional/openlp_core_lib/test_projectordb.py'
382--- tests/functional/openlp_core_lib/test_projectordb.py 2017-04-24 05:17:55 +0000
383+++ tests/functional/openlp_core_lib/test_projectordb.py 2017-05-20 06:06:27 +0000
384@@ -26,13 +26,15 @@
385 PREREQUISITE: add_record() and get_all() functions validated.
386 """
387 import os
388+import shutil
389 from unittest import TestCase
390 from unittest.mock import MagicMock, patch
391
392 from openlp.core.lib.projector.db import Manufacturer, Model, Projector, ProjectorDB, ProjectorSource, Source
393 from openlp.core.lib.projector.constants import PJLINK_PORT
394
395-from tests.resources.projector.data import TEST_DB, TEST1_DATA, TEST2_DATA, TEST3_DATA
396+from tests.resources.projector.data import TEST_DB_PJLINK1, TEST_DB, TEST1_DATA, TEST2_DATA, TEST3_DATA
397+from tests.utils.constants import TEST_RESOURCES_PATH
398
399
400 def compare_data(one, two):
401@@ -45,7 +47,11 @@
402 one.port == two.port and \
403 one.name == two.name and \
404 one.location == two.location and \
405- one.notes == two.notes
406+ one.notes == two.notes and \
407+ one.sw_version == two.sw_version and \
408+ one.serial_no == two.serial_no and \
409+ one.model_filter == two.model_filter and \
410+ one.model_lamp == two.model_lamp
411
412
413 def compare_source(one, two):
414@@ -168,6 +174,10 @@
415 record.name = TEST3_DATA['name']
416 record.location = TEST3_DATA['location']
417 record.notes = TEST3_DATA['notes']
418+ record.sw_version = TEST3_DATA['sw_version']
419+ record.serial_no = TEST3_DATA['serial_no']
420+ record.model_filter = TEST3_DATA['model_filter']
421+ record.model_lamp = TEST3_DATA['model_lamp']
422 updated = self.projector.update_projector(record)
423 self.assertTrue(updated, 'Save updated record should have returned True')
424 record = self.projector.get_projector_by_ip(TEST3_DATA['ip'])
425@@ -246,7 +256,8 @@
426 projector = Projector()
427
428 # WHEN: projector() is populated
429- # NOTE: projector.pin, projector.other, projector.sources should all return None
430+ # NOTE: projector.[pin, other, sources, sw_version, serial_no, sw_version, model_lamp, model_filter]
431+ # should all return None.
432 # projector.source_list should return an empty list
433 projector.id = 0
434 projector.ip = '127.0.0.1'
435@@ -262,8 +273,9 @@
436 self.assertEqual(str(projector),
437 '< Projector(id="0", ip="127.0.0.1", port="4352", pin="None", name="Test One", '
438 'location="Somewhere over the rainbow", notes="Not again", pjlink_name="TEST", '
439- 'manufacturer="IN YOUR DREAMS", model="OpenLP", other="None", sources="None", '
440- 'source_list="[]") >',
441+ 'manufacturer="IN YOUR DREAMS", model="OpenLP", serial_no="None", other="None", '
442+ 'sources="None", source_list="[]", model_filter="None", model_lamp="None", '
443+ 'sw_version="None") >',
444 'Projector.__repr__() should have returned a proper representation string')
445
446 def test_projectorsource_repr(self):
447
448=== modified file 'tests/resources/projector/data.py'
449--- tests/resources/projector/data.py 2017-05-07 10:15:10 +0000
450+++ tests/resources/projector/data.py 2017-05-20 06:06:27 +0000
451@@ -27,6 +27,8 @@
452 from tempfile import gettempdir
453
454 # Test data
455+TEST_DB_PJLINK1 = 'projector_pjlink1.sqlite'
456+
457 TEST_DB = os.path.join(gettempdir(), 'openlp-test-projectordb.sql')
458
459 TEST_SALT = '498e4a67'
460@@ -44,21 +46,33 @@
461 pin='1111',
462 name='___TEST_ONE___',
463 location='location one',
464- notes='notes one')
465+ notes='notes one',
466+ serial_no='Serial Number 1',
467+ sw_version='Version 1',
468+ model_filter='Filter type 1',
469+ model_lamp='Lamp type 1')
470
471 TEST2_DATA = dict(ip='222.222.222.222',
472 port='2222',
473 pin='2222',
474 name='___TEST_TWO___',
475 location='location two',
476- notes='notes two')
477+ notes='notes one',
478+ serial_no='Serial Number 2',
479+ sw_version='Version 2',
480+ model_filter='Filter type 2',
481+ model_lamp='Lamp type 2')
482
483 TEST3_DATA = dict(ip='333.333.333.333',
484 port='3333',
485 pin='3333',
486 name='___TEST_THREE___',
487 location='location three',
488- notes='notes three')
489+ notes='notes one',
490+ serial_no='Serial Number 3',
491+ sw_version='Version 3',
492+ model_filter='Filter type 3',
493+ model_lamp='Lamp type 3')
494
495 TEST_VIDEO_CODES = {
496 '11': 'RGB 1',