Merge lp:~suutari-olli/openlp/fix-advanced-bible-search-clear-button-giving-focus-to-quick into lp:openlp

Proposed by Azaziah
Status: Superseded
Proposed branch: lp:~suutari-olli/openlp/fix-advanced-bible-search-clear-button-giving-focus-to-quick
Merge into: lp:openlp
Diff against target: 151 lines (+77/-9)
4 files modified
openlp/core/ui/exceptiondialog.py (+3/-3)
openlp/plugins/bibles/lib/manager.py (+0/-1)
openlp/plugins/bibles/lib/mediaitem.py (+16/-4)
tests/functional/openlp_plugins/bibles/test_mediaitem.py (+58/-1)
To merge this branch: bzr merge lp:~suutari-olli/openlp/fix-advanced-bible-search-clear-button-giving-focus-to-quick
Reviewer Review Type Date Requested Status
Phill Pending
Raoul Snyman Pending
Tim Bentley Pending
Review via email: mp+306036@code.launchpad.net

This proposal supersedes a proposal from 2016-09-16.

This proposal has been superseded by a proposal from 2016-09-17.

Description of the change

Fixed the issue where web bible's result in traceback in "Search while typing"
(by removing one miss-placed line)

This branch also fixes the issue where the new "Clear Bible search results" and
"Lock button" give focus to Text search if it is used in "Select" tab.

lp:~suutari-olli/openlp/fix-advanced-bible-search-clear-button-giving-focus-to-quick (revision 2705)
[SUCCESS] https://ci.openlp.io/job/Branch-01-Pull/1772/
[SUCCESS] https://ci.openlp.io/job/Branch-02-Functional-Tests/1683/
[SUCCESS] https://ci.openlp.io/job/Branch-03-Interface-Tests/1621/
[SUCCESS] https://ci.openlp.io/job/Branch-04a-Windows_Functional_Tests/1377/
[SUCCESS] https://ci.openlp.io/job/Branch-04b-Windows_Interface_Tests/967/
[SUCCESS] https://ci.openlp.io/job/Branch-05a-Code_Analysis/1035/
[SUCCESS] https://ci.openlp.io/job/Branch-05b-Test_Coverage/903/
[SUCCESS] https://ci.openlp.io/job/Branch-05c-Code_Analysis2/66/

To post a comment you must log in.
Revision history for this message
Tim Bentley (trb143) wrote : Posted in a previous version of this proposal

Looks OK but needs tests!

review: Needs Fixing
Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Please see my comments.

review: Needs Fixing
Revision history for this message
Tim Bentley (trb143) wrote : Posted in a previous version of this proposal

Tests? The rest looks good though

review: Needs Fixing
Revision history for this message
Raoul Snyman (raoul-snyman) wrote : Posted in a previous version of this proposal

Please read the unittest.mock documentation, it has lots of examples on how to use it and the best way to do it.

https://docs.python.org/3/library/unittest.mock.html

Check my comments below for the best way to use the library.

review: Needs Fixing
Revision history for this message
Azaziah (suutari-olli) wrote : Posted in a previous version of this proposal

> Please read the unittest.mock documentation, it has lots of examples on how to
> use it and the best way to do it.
>
> https://docs.python.org/3/library/unittest.mock.html
>
> Check my comments below for the best way to use the library.

We tried to change this test to use @patch with phill, but failed.

Revision history for this message
Phill (phill-ridout) wrote : Posted in a previous version of this proposal

> > Please read the unittest.mock documentation, it has lots of examples on how
> to
> > use it and the best way to do it.
> >
> > https://docs.python.org/3/library/unittest.mock.html
> >
> > Check my comments below for the best way to use the library.
>
> We tried to change this test to use @patch with phill, but failed.

I spent a couple hours on this and couldn't figure it out.

media_item.list_view is set in a super class
media_item.quick_search_edit is set in a method called from _setup which is patched

All from memory that is.

Revision history for this message
Tim Bentley (trb143) : Posted in a previous version of this proposal
review: Approve
Revision history for this message
Phill (phill-ridout) wrote : Posted in a previous version of this proposal

on_lock_button_toggled is such a small method, any changes of tests for that?

Also can you include the parameters in the doc string please. (See inline comments)

review: Needs Fixing
Revision history for this message
Phill (phill-ridout) wrote : Posted in a previous version of this proposal

your test 'test_on_lock_button_toggled_search_tab' is only really testing the last two lines of on_lock_button_toggled

As, you've gone to all the trouble of setting this test up it would be easy to test the if condition which sets the appropriate icon. In your current test add:

    # GIVEN:
    self.media_item.lock_icon = 'lock icon'
    sender_instance_mock = MagicMock()
    self.media_item.sender = MagicMock(return_value=sender_instance_mock)

    # THEN:
    sender_instance_mock.setIcon.assert_called_once_with('lock icon')

Then you can just copy and paste your test, make a few modifications calling self.media_item.on_lock_button_toggled with False and you've provided 100% coverage for the on_lock_button_toggled method, for not too much extra effort.

See also my inline comment for one small issue with your current test.

Revision history for this message
Azaziah (suutari-olli) wrote : Posted in a previous version of this proposal

It was my initial thought but I failed to set up the test within a reasonable time.

Iv'e managed to increase the coverage by your instructions, thank you.

> your test 'test_on_lock_button_toggled_search_tab' is only really testing the
> last two lines of on_lock_button_toggled
>
> As, you've gone to all the trouble of setting this test up it would be easy to
> test the if condition which sets the appropriate icon. In your current test
> add:
>
> # GIVEN:
> self.media_item.lock_icon = 'lock icon'
> sender_instance_mock = MagicMock()
> self.media_item.sender = MagicMock(return_value=sender_instance_mock)
>
> # THEN:
> sender_instance_mock.setIcon.assert_called_once_with('lock icon')
>
> Then you can just copy and paste your test, make a few modifications calling
> self.media_item.on_lock_button_toggled with False and you've provided 100%
> coverage for the on_lock_button_toggled method, for not too much extra effort.
>
> See also my inline comment for one small issue with your current test.

2707. By Azaziah

- The checking for not_called_once does not work apparently, fails in jenkins but passes in nosetests.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/core/ui/exceptiondialog.py'
2--- openlp/core/ui/exceptiondialog.py 2016-08-03 21:19:14 +0000
3+++ openlp/core/ui/exceptiondialog.py 2016-09-17 23:08:24 +0000
4@@ -97,9 +97,9 @@
5 translate('OpenLP.ExceptionDialog', '<strong>Please describe what you were trying to do.</strong> '
6 '&nbsp;If possible, write in English.'))
7 exception_part1 = (translate('OpenLP.ExceptionDialog',
8- '<strong>Oops, OpenLP hit a problem and couldn\'t recover!</strong> <br><br>'
9- '<strong>You can help </strong> the OpenLP developers to <strong>fix this</strong>'
10- ' by<br> sending them a <strong>bug report</strong> to {email}{newlines}'
11+ '<strong>Oops, OpenLP hit a problem and couldn\'t recover!<br><br>'
12+ 'You can help </strong> the OpenLP developers to <strong>fix this</strong>'
13+ ' by<br> sending them a <strong>bug report to {email}</strong>{newlines}'
14 ).format(email='<a href = "mailto:bugs@openlp.org" > bugs@openlp.org</a>',
15 newlines='<br><br>'))
16 self.message_label.setText(
17
18=== modified file 'openlp/plugins/bibles/lib/manager.py'
19--- openlp/plugins/bibles/lib/manager.py 2016-09-04 16:15:57 +0000
20+++ openlp/plugins/bibles/lib/manager.py 2016-09-17 23:08:24 +0000
21@@ -367,7 +367,6 @@
22 second_web_bible = self.db_cache[second_bible].get_object(BibleMeta, 'download_source')
23 if web_bible or second_web_bible:
24 # If either Bible is Web, cursor is reset to normal and search ends w/o any message.
25- self.check_search_result()
26 self.application.set_normal_cursor()
27 return None
28 # Fetch the results from db. If no results are found, return None, no message is given for this.
29
30=== modified file 'openlp/plugins/bibles/lib/mediaitem.py'
31--- openlp/plugins/bibles/lib/mediaitem.py 2016-08-10 18:31:33 +0000
32+++ openlp/plugins/bibles/lib/mediaitem.py 2016-09-17 23:08:24 +0000
33@@ -254,8 +254,8 @@
34 self.quickStyleComboBox.activated.connect(self.on_quick_style_combo_box_changed)
35 self.advancedStyleComboBox.activated.connect(self.on_advanced_style_combo_box_changed)
36 # Buttons
37- self.advancedClearButton.clicked.connect(self.on_clear_button)
38- self.quickClearButton.clicked.connect(self.on_clear_button)
39+ self.advancedClearButton.clicked.connect(self.on_advanced_clear_button_clicked)
40+ self.quickClearButton.clicked.connect(self.on_clear_button_clicked)
41 self.advancedSearchButton.clicked.connect(self.on_advanced_search_button)
42 self.quickSearchButton.clicked.connect(self.on_quick_search_button)
43 # Other stuff
44@@ -548,19 +548,31 @@
45 self.advancedTab.setVisible(True)
46 self.advanced_book_combo_box.setFocus()
47
48- def on_clear_button(self):
49+ def on_clear_button_clicked(self):
50 # Clear the list, then set the "No search Results" message, then clear the text field and give it focus.
51 self.list_view.clear()
52 self.check_search_result()
53 self.quick_search_edit.clear()
54 self.quick_search_edit.setFocus()
55
56+ def on_advanced_clear_button_clicked(self):
57+ # The same as the on_clear_button_clicked, but gives focus to Book name field in "Select" (advanced).
58+ self.list_view.clear()
59+ self.check_search_result()
60+ self.advanced_book_combo_box.setFocus()
61+
62 def on_lock_button_toggled(self, checked):
63- self.quick_search_edit.setFocus()
64+ """
65+ Toggle the lock button, if Search tab is used, set focus to search field.
66+ :param checked: The state of the toggle button. bool
67+ :return: None
68+ """
69 if checked:
70 self.sender().setIcon(self.lock_icon)
71 else:
72 self.sender().setIcon(self.unlock_icon)
73+ if self.quickTab.isVisible():
74+ self.quick_search_edit.setFocus()
75
76 def on_quick_style_combo_box_changed(self):
77 self.settings.layout_style = self.quickStyleComboBox.currentIndex()
78
79=== modified file 'tests/functional/openlp_plugins/bibles/test_mediaitem.py'
80--- tests/functional/openlp_plugins/bibles/test_mediaitem.py 2016-06-14 21:55:37 +0000
81+++ tests/functional/openlp_plugins/bibles/test_mediaitem.py 2016-09-17 23:08:24 +0000
82@@ -114,7 +114,7 @@
83 self.assertEqual(self.media_item.search_results, {})
84 self.assertEqual(self.media_item.second_search_results, {})
85
86- def on_quick_search_button_general_test(self):
87+ def test_on_quick_search_button_general(self):
88 """
89 Test that general things, which should be called on all Quick searches are called.
90 """
91@@ -150,3 +150,60 @@
92 self.assertEqual(2, self.media_item.quickSearchButton.setEnabled.call_count, 'Disable and Enable the button')
93 self.assertEqual(1, self.media_item.check_search_result.call_count, 'Check results Should had been called once')
94 self.assertEqual(1, self.app.set_normal_cursor.call_count, 'Normal cursor should had been called once')
95+
96+ def test_on_clear_button_clicked(self):
97+ """
98+ Test that the on_clear_button_clicked works properly. (Used by Bible search tab)
99+ """
100+ # GIVEN: Mocked list_view, check_search_results & quick_search_edit.
101+ self.media_item.list_view = MagicMock()
102+ self.media_item.check_search_result = MagicMock()
103+ self.media_item.quick_search_edit = MagicMock()
104+
105+ # WHEN: on_clear_button_clicked is called
106+ self.media_item.on_clear_button_clicked()
107+
108+ # THEN: Search result should be reset and search field should receive focus.
109+ self.media_item.list_view.clear.assert_called_once_with(),
110+ self.media_item.check_search_result.assert_called_once_with(),
111+ self.media_item.quick_search_edit.clear.assert_called_once_with(),
112+ self.media_item.quick_search_edit.setFocus.assert_called_once_with()
113+
114+ def test_on_lock_button_toggled_search_tab_lock_icon(self):
115+ """
116+ Test that "on_lock_button_toggled" gives focus to the right field and toggles the lock properly.
117+ """
118+ # GIVEN: Mocked sender & Search edit, quickTab returning value = True on isVisible.
119+ self.media_item.sender = MagicMock()
120+ self.media_item.quick_search_edit = MagicMock()
121+ self.media_item.quickTab = MagicMock(**{'isVisible.return_value': True})
122+
123+ self.media_item.lock_icon = 'lock icon'
124+ sender_instance_mock = MagicMock()
125+ self.media_item.sender = MagicMock(return_value=sender_instance_mock)
126+
127+ # WHEN: on_lock_button_toggled is called and checked returns = True.
128+ self.media_item.on_lock_button_toggled(True)
129+
130+ # THEN: on_quick_search_edit should receive focus and Lock icon should be set.
131+ self.media_item.quick_search_edit.setFocus.assert_called_once_with()
132+ sender_instance_mock.setIcon.assert_called_once_with('lock icon')
133+
134+ def test_on_lock_button_toggled_unlock_icon(self):
135+ """
136+ Test that lock button unlocks properly and lock toggles properly.
137+ """
138+ # GIVEN: Mocked sender & Search edit, quickTab returning value = False on isVisible.
139+ self.media_item.sender = MagicMock()
140+ self.media_item.quick_search_edit = MagicMock()
141+ self.media_item.quickTab = MagicMock()
142+ self.media_item.quickTab.isVisible = MagicMock()
143+ self.media_item.unlock_icon = 'unlock icon'
144+ sender_instance_mock = MagicMock()
145+ self.media_item.sender = MagicMock(return_value=sender_instance_mock)
146+
147+ # WHEN: on_lock_button_toggled is called and checked returns = False.
148+ self.media_item.on_lock_button_toggled(False)
149+
150+ # THEN: Unlock icon should be set.
151+ sender_instance_mock.setIcon.assert_called_once_with('unlock icon')