Merge branch 'read-remote-version-from-file' into 'master'

Update the remote settings to use the remote's version.js file

See merge request openlp/openlp!421
This commit is contained in:
Tomas Groth 2022-02-18 16:24:22 +00:00
commit 962f36967a
6 changed files with 364 additions and 77 deletions

View File

@ -23,6 +23,7 @@ Download and "install" the remote web client
"""
import json
import logging
import re
from datetime import date
from zipfile import ZipFile
@ -34,6 +35,7 @@ from openlp.core.common.registry import Registry
from openlp.core.threading import ThreadWorker, run_thread
REMOTE_URL = 'https://get.openlp.org/remote/'
LOCAL_VERSION = re.compile(r'appVersion.*=.*\'(.*?)\';')
log = logging.getLogger(__name__)
@ -117,7 +119,7 @@ def get_latest_size():
return version_info['latest']['size']
def download_and_check(callback=None, can_update_range=True):
def download_and_install(callback=None, can_update_range=True):
"""
Download the web site and deploy it.
"""
@ -151,3 +153,18 @@ def check_for_remote_update(main_window):
# TODO: Use this to figure out if there's an Internet connection?
# worker.no_internet.connect(main_window.on_no_internet)
run_thread(worker, 'remote-version')
def get_installed_version():
"""
Get the version of the remote that is installed, or None if there is no remote
"""
version_file = AppLocation.get_section_data_path('remotes') / 'assets' / 'version.js'
if not version_file.exists():
return None
version_read = version_file.read()
print(version_read)
match = LOCAL_VERSION.search(version_read)
if not match:
return None
return match.group(1)

View File

@ -30,7 +30,7 @@ from time import sleep
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.api.deploy import download_and_check, download_version_info
from openlp.core.api.deploy import download_and_install, download_version_info, get_installed_version
from openlp.core.common import get_network_interfaces
from openlp.core.common.i18n import translate
from openlp.core.common.registry import Registry
@ -50,7 +50,8 @@ class ApiTab(SettingsTab):
def __init__(self, parent):
self.icon_path = UiIcons().remote
advanced_translated = translate('OpenLP.APITab', 'API')
self._master_version = None
self._available_version = None
self._installed_version = None
super(ApiTab, self).__init__(parent, 'api', advanced_translated)
def setup_ui(self):
@ -138,25 +139,25 @@ class ApiTab(SettingsTab):
self.web_remote_group_box.setObjectName('web_remote_group_box')
self.web_remote_layout = QtWidgets.QGridLayout(self.web_remote_group_box)
self.web_remote_layout.setObjectName('web_remote_layout')
self.current_version_label = QtWidgets.QLabel(self.web_remote_group_box)
self.web_remote_layout.addWidget(self.current_version_label, 0, 0)
self.current_version_label.setObjectName('current_version_label')
self.current_version_value = QtWidgets.QLabel(self.web_remote_group_box)
self.current_version_value.setObjectName('current_version_value')
self.web_remote_layout.addWidget(self.current_version_value, 0, 1)
self.upgrade_button = QtWidgets.QPushButton(self.web_remote_group_box)
self.upgrade_button.setEnabled(False)
self.upgrade_button.setObjectName('upgrade_button')
self.web_remote_layout.addWidget(self.upgrade_button, 0, 2)
self.master_version_label = QtWidgets.QLabel(self.web_remote_group_box)
self.master_version_label.setObjectName('master_version_label')
self.web_remote_layout.addWidget(self.master_version_label, 1, 0)
self.master_version_value = QtWidgets.QLabel(self.web_remote_group_box)
self.master_version_value.setObjectName('master_version_value')
self.web_remote_layout.addWidget(self.master_version_value, 1, 1)
self.check_version_button = QtWidgets.QPushButton(self.web_remote_group_box)
self.check_version_button.setObjectName('check_version_button')
self.web_remote_layout.addWidget(self.check_version_button, 1, 2)
self.installed_version_label = QtWidgets.QLabel(self.web_remote_group_box)
self.web_remote_layout.addWidget(self.installed_version_label, 0, 0)
self.installed_version_label.setObjectName('installed_version_label')
self.installed_version_value = QtWidgets.QLabel(self.web_remote_group_box)
self.installed_version_value.setObjectName('installed_version_value')
self.web_remote_layout.addWidget(self.installed_version_value, 0, 1)
self.check_for_updates_button = QtWidgets.QPushButton(self.web_remote_group_box)
self.check_for_updates_button.setObjectName('check_for_updates_button')
self.web_remote_layout.addWidget(self.check_for_updates_button, 0, 2)
self.available_version_label = QtWidgets.QLabel(self.web_remote_group_box)
self.available_version_label.setObjectName('available_version_label')
self.web_remote_layout.addWidget(self.available_version_label, 1, 0)
self.available_version_value = QtWidgets.QLabel(self.web_remote_group_box)
self.available_version_value.setObjectName('available_version_value')
self.web_remote_layout.addWidget(self.available_version_value, 1, 1)
self.install_button = QtWidgets.QPushButton(self.web_remote_group_box)
self.install_button.setEnabled(False)
self.install_button.setObjectName('install_button')
self.web_remote_layout.addWidget(self.install_button, 1, 2)
self.left_layout.addWidget(self.web_remote_group_box)
self.app_group_box = QtWidgets.QGroupBox(self.right_column)
self.app_group_box.setObjectName('app_group_box')
@ -199,8 +200,8 @@ class ApiTab(SettingsTab):
self.twelve_hour_check_box.stateChanged.connect(self.on_twelve_hour_check_box_changed)
self.thumbnails_check_box.stateChanged.connect(self.on_thumbnails_check_box_changed)
self.address_edit.textChanged.connect(self.set_urls)
self.upgrade_button.clicked.connect(self.on_upgrade_button_clicked)
self.check_version_button.clicked.connect(self.on_check_version_button_clicked)
self.install_button.clicked.connect(self.on_install_button_clicked)
self.check_for_updates_button.clicked.connect(self.on_check_for_updates_button_clicked)
def retranslate_ui(self):
self.tab_title_visible = translate('RemotePlugin.RemoteTab', 'Remote Interface')
@ -221,12 +222,13 @@ class ApiTab(SettingsTab):
translate('RemotePlugin.RemoteTab', 'Scan the QR code to open the remote view on your mobile device'))
self.user_login_group_box.setTitle(translate('RemotePlugin.RemoteTab', 'User Authentication'))
self.web_remote_group_box.setTitle(translate('RemotePlugin.RemoteTab', 'Web Remote'))
self.check_version_button.setText(translate('RemotePlugin.RemoteTab', 'Check for Updates'))
self.upgrade_button.setText(translate('RemotePlugin.RemoteTab', 'Upgrade'))
self.check_for_updates_button.setText(translate('RemotePlugin.RemoteTab', 'Check for Updates'))
self.install_button.setText(translate('RemotePlugin.RemoteTab', 'Install'))
self.user_id_label.setText(translate('RemotePlugin.RemoteTab', 'User id:'))
self.password_label.setText(translate('RemotePlugin.RemoteTab', 'Password:'))
self.current_version_label.setText(translate('RemotePlugin.RemoteTab', 'Current version:'))
self.master_version_label.setText(translate('RemotePlugin.RemoteTab', 'Latest version:'))
self.installed_version_label.setText(translate('RemotePlugin.RemoteTab', 'Installed version:'))
self._not_installed_version = translate('RemotePlugin.RemoteTab', '(not installed)')
self.available_version_label.setText(translate('RemotePlugin.RemoteTab', 'Latest version:'))
self._unknown_version = translate('RemotePlugin.RemoteTab', '(unknown)')
self.server_state_group_box.setTitle(translate('RemotePlugin.RemoteTab', 'Server Status'))
self.server_http_state_title.setText(translate('RemotePlugin.RemoteTab', 'HTTP Server:'))
@ -237,34 +239,49 @@ class ApiTab(SettingsTab):
self._server_disabled = translate('RemotePlugin.RemoteTab', 'Disabled', 'Server is disabled')
@property
def master_version(self):
def available_version(self):
"""
Property getter for the remote master version
Property getter for the available version
"""
return self._master_version
return self._available_version
@master_version.setter
def master_version(self, value):
@available_version.setter
def available_version(self, value):
"""
Property setter for the remote master version
Property setter for the available version
"""
self._master_version = value
self.master_version_value.setText(self._master_version or self._unknown_version)
self.upgrade_button.setEnabled(self.can_enable_upgrade_button())
self._available_version = value
self.available_version_value.setText(self._available_version or self._unknown_version)
self.install_button.setEnabled(self.can_enable_install_button())
def can_enable_upgrade_button(self):
@property
def installed_version(self):
"""
Do a couple checks to set the upgrade button state
Property getter for the installed version
"""
return self.master_version_value.text() != self._unknown_version and \
self.master_version_value.text() != self.current_version_value.text()
return self._installed_version
def set_master_version(self):
@installed_version.setter
def installed_version(self, value):
"""
Property setter for the installed version
"""
self._installed_version = value
self.installed_version_value.setText(self._installed_version or self._not_installed_version)
def can_enable_install_button(self):
"""
Do a couple checks to set the install button state
"""
return self.available_version_value.text() != self._unknown_version and \
self.available_version_value.text() != self.installed_version_value.text()
def validate_available_version(self):
"""
Check if the master version is not set, and set it to None to invoke the "unknown version" label
"""
if not self._master_version:
self.master_version = None
if not self._available_version:
self.available_version = None
def set_urls(self):
"""
@ -281,7 +298,7 @@ class ApiTab(SettingsTab):
image = QtGui.QPixmap.fromImage(img)
self.app_qr_code_label.setPixmap(image)
def get_server_states(self):
def set_server_states(self):
"""
Update the display with the current state of the servers
"""
@ -333,10 +350,13 @@ class ApiTab(SettingsTab):
self.user_login_group_box.setChecked(self.settings.value('api/authentication enabled'))
self.user_id.setText(self.settings.value('api/user id'))
self.password.setText(self.settings.value('api/password'))
self.current_version_value.setText(self.settings.value('api/download version'))
self.set_master_version()
self.installed_version = get_installed_version()
# TODO: Left in for backwards compatibilty, remove eventually
if not self.installed_version:
self.installed_version = self.settings.value('api/download version')
self.validate_available_version()
self.set_urls()
self.get_server_states()
self.set_server_states()
def save(self):
"""
@ -376,7 +396,7 @@ class ApiTab(SettingsTab):
if check_state == QtCore.Qt.Checked:
self.thumbnails = True
def on_check_version_button_clicked(self):
def on_check_for_updates_button_clicked(self):
"""
Check for the latest version on the server
"""
@ -385,28 +405,31 @@ class ApiTab(SettingsTab):
app.process_events()
version_info = download_version_info()
app.process_events()
self.master_version = version_info['latest']['version']
self.available_version = version_info['latest']['version']
app.process_events()
app.set_normal_cursor()
app.process_events()
if self.can_enable_upgrade_button():
Registry().get('main_window').information_message('New version available!',
'There\'s a new version of the web remote available.')
if self.can_enable_install_button():
Registry().get('main_window').information_message(
translate('OpenLP.APITab', 'New version available!'),
translate('OpenLP.APITab', 'There\'s a new version of the web remote available.')
)
def on_upgrade_button_clicked(self):
def on_install_button_clicked(self):
"""
Download/upgrade the web remote
Download/install the web remote
"""
app = Registry().get('application')
progress = DownloadProgressDialog(self, app)
progress.show()
app.process_events()
sleep(0.5)
downloaded_version = download_and_check(progress)
downloaded_version = download_and_install(progress)
app.process_events()
sleep(0.5)
progress.close()
app.process_events()
self.current_version_value.setText(downloaded_version)
self.installed_version = downloaded_version
# TODO: Left in for backwards compatibilty for versions of the remote prior to 0.9.8, and versions
# of OpenLP prior to 2.9.5. We need to remove this eventually.
self.settings.setValue('api/download version', downloaded_version)
self.upgrade_button.setEnabled(self.can_enable_upgrade_button())

View File

@ -208,7 +208,7 @@ class Settings(QtCore.QSettings):
'api/authentication enabled': False,
'api/ip address': '0.0.0.0',
'api/thumbnails': True,
'api/download version': '0.0',
'api/download version': None,
'api/last version test': '',
'api/update check': True,
'bibles/db type': 'sqlite',

View File

@ -32,7 +32,7 @@ from tempfile import gettempdir
from PyQt5 import QtCore, QtWidgets, QtGui
from openlp.core.api.deploy import get_latest_size, download_and_check
from openlp.core.api.deploy import get_latest_size, download_and_install
from openlp.core.common import trace_error_handler
from openlp.core.common.applocation import AppLocation
from openlp.core.common.httputils import DownloadWorker, download_file, get_url_file_size, get_web_page
@ -539,7 +539,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
if self.remote_page.can_download_remote:
self._increment_progress_bar(self.downloading.format(name='Web Remote'), 0)
self.previous_size = 0
remote_version = download_and_check(self, can_update_range=False)
remote_version = download_and_install(self, can_update_range=False)
if remote_version:
self.settings.setValue('api/download version', remote_version)
else:

View File

@ -22,7 +22,8 @@ import json
from pathlib import Path
from unittest.mock import MagicMock, patch
from openlp.core.api.deploy import REMOTE_URL, deploy_zipfile, download_version_info, download_and_check
from openlp.core.api.deploy import REMOTE_URL, deploy_zipfile, download_version_info, download_and_install, \
get_installed_version
CONFIG_FILE = '{"latest": {"version": "0.1", "filename": "remote-0.1.zip", "sha256": "", "size": 854039}}'
@ -100,15 +101,15 @@ def test_download_version_info(mocked_get_web_page, mocked_get_openlp_user_agent
@patch('openlp.core.api.deploy.log.warning')
@patch('openlp.core.api.deploy.download_version_info')
def test_download_and_check_log_warning(mocked_download_version_info, mocked_warning):
def test_download_and_install_log_warning(mocked_download_version_info, mocked_warning):
"""
Test that when the version info fails, a warning is logged
"""
# GIVEN: A few mocks, and a version info of None
mocked_download_version_info.return_value = None
# WHEN: download_and_check is run
result = download_and_check(None)
# WHEN: download_and_install is run
result = download_and_install(None)
# THEN: None is returned and a warning is logged
assert result is None, 'The result should be None'
@ -118,8 +119,8 @@ def test_download_and_check_log_warning(mocked_download_version_info, mocked_war
@patch('openlp.core.api.deploy.AppLocation.get_section_data_path')
@patch('openlp.core.api.deploy.download_file')
@patch('openlp.core.api.deploy.download_version_info')
def test_download_and_check_download_fails(mocked_download_version_info, mocked_download_file,
mocked_get_section_data_path):
def test_download_and_install_download_fails(mocked_download_version_info, mocked_download_file,
mocked_get_section_data_path):
"""
Test that when the version info fails, a warning is logged
"""
@ -129,8 +130,8 @@ def test_download_and_check_download_fails(mocked_download_version_info, mocked_
mocked_download_file.return_value = False
mocked_get_section_data_path.return_value = Path('.')
# WHEN: download_and_check is run
result = download_and_check(mocked_callback)
# WHEN: download_and_install is run
result = download_and_install(mocked_callback)
# THEN: None is returned and a warning is logged
assert result is None, 'The result should be None'
@ -140,8 +141,8 @@ def test_download_and_check_download_fails(mocked_download_version_info, mocked_
@patch('openlp.core.api.deploy.deploy_zipfile')
@patch('openlp.core.api.deploy.download_file')
@patch('openlp.core.api.deploy.download_version_info')
def test_download_and_check(mocked_download_version_info, mocked_download_file, mocked_deploy_zipfile,
mocked_get_section_data_path):
def test_download_and_install(mocked_download_version_info, mocked_download_file, mocked_deploy_zipfile,
mocked_get_section_data_path):
# GIVEN: A bunch of mocks
mocked_callback = MagicMock()
mocked_download_version_info.return_value = CONFIG_DICT
@ -150,10 +151,60 @@ def test_download_and_check(mocked_download_version_info, mocked_download_file,
mocked_remote_zip = mocked_remote_path / 'remote.zip'
mocked_get_section_data_path.return_value = mocked_remote_path
# WHEN: download_and_check() is called
result = download_and_check(mocked_callback)
# WHEN: download_and_install() is called
result = download_and_install(mocked_callback)
# THEN: The correct things should have been done
assert result == CONFIG_DICT['latest']['version'], 'The correct version is returned'
mocked_download_file.assert_called_once_with(mocked_callback, REMOTE_URL + '0.1/remote-0.1.zip', mocked_remote_zip)
mocked_deploy_zipfile.assert_called_once_with(mocked_remote_path, 'remote.zip')
@patch('openlp.core.api.deploy.AppLocation.get_section_data_path')
def test_get_installed_version_not_installed(mocked_get_section_data_path):
"""Test that if there is no remote installed, None is returned"""
# GIVEN: A mocked AppLocation and no file installed
mocked_version_file = MagicMock()
mocked_version_file.__truediv__.return_value = mocked_version_file
mocked_version_file.exists.return_value = False
mocked_get_section_data_path.return_value = mocked_version_file
# WHEN: get_installed_version() is called but there is no version file
result = get_installed_version()
# THEN: The result should be None
assert result is None
@patch('openlp.core.api.deploy.AppLocation.get_section_data_path')
def test_get_installed_version_no_version(mocked_get_section_data_path):
"""Test that if there is no matching version number, None is returned"""
# GIVEN: A mocked AppLocation and no file installed
mocked_version_file = MagicMock()
mocked_version_file.__truediv__.return_value = mocked_version_file
mocked_version_file.exists.return_value = True
mocked_version_file.read.return_value = 'let app_version = 0.9.7;'
mocked_get_section_data_path.return_value = mocked_version_file
# WHEN: get_installed_version() is called but there is no version in the file
result = get_installed_version()
# THEN: The result should be None
assert result is None
@patch('openlp.core.api.deploy.AppLocation.get_section_data_path')
def test_get_installed_version(mocked_get_section_data_path):
"""Test that get_installed_version returns the version number"""
# GIVEN: A mocked AppLocation and no file installed
mocked_version_file = MagicMock()
mocked_version_file.__truediv__.return_value = mocked_version_file
mocked_version_file.exists.return_value = True
mocked_version_file.read.return_value = 'let appVersion = \'0.9.7\';'
mocked_get_section_data_path.return_value = mocked_version_file
# WHEN: get_installed_version() is called but there is no version file
result = get_installed_version()
# THEN: The result should be None
assert result == '0.9.7'

View File

@ -24,6 +24,7 @@ This module contains tests for the lib submodule of the Remotes plugin.
import hashlib
import pytest
import re
from unittest.mock import MagicMock, patch
from PyQt5 import QtWidgets
@ -114,22 +115,217 @@ def test_address_revert_button_clicked(api_tab, settings):
assert api_tab.address_edit.text() == settings.get_default_value('api/ip address')
def test_save(api_tab, settings):
@patch('openlp.core.api.tab.QtWidgets.QMessageBox.information')
def test_save(mocked_information, api_tab, registry, settings):
"""
Test the IP revert function works
Test the save method works correctly
"""
# GIVEN: The ip address text set to a non default value
api_tab.address_edit.setText(settings.value('api/ip address'))
# GIVEN: Various settings are set on the form and a mocked settings form
mocked_settings_form = MagicMock()
registry.remove('settings_form')
registry.register('settings_form', mocked_settings_form)
settings.setValue('api/ip address', '0.0.0.0')
api_tab.address_edit.setText('192.168.1.1')
api_tab.twelve_hour = True
api_tab.thumbnails = True
api_tab.user_login_group_box.setChecked(True)
api_tab.user_id.setText('user id thing')
api_tab.password.setText('user password thing')
# WHEN: save is called
api_tab.save()
# THEN: The text should have been changed to the default value
mocked_information.assert_called_once_with(api_tab, 'Restart Required',
'This change will only take effect once OpenLP has been restarted.')
mocked_settings_form.register_post_process.called_once_with('remotes_config_updated')
assert settings.value('api/twelve hour') is True
assert settings.value('api/thumbnails') is True
assert settings.value('api/authentication enabled') is True
assert settings.value('api/user id') == 'user id thing'
assert settings.value('api/password') == 'user password thing'
def test_available_version_property_get_none(api_tab):
"""Test that the available version property is None on init"""
# GIVEN: An uninitialised API tab
# WHEN: the available version is GET'ed
result = api_tab.available_version
# THEN: The result is None
assert result is None
def test_available_version_property_set(api_tab):
"""Test that the available version property is set correctly"""
# GIVEN: An uninitialised API tab
available_version = '0.9.7'
# WHEN: the available version is SET
api_tab.available_version = available_version
# THEN: The internal value should be set, and the right methods should have been called
assert api_tab._available_version == available_version
assert api_tab.available_version_value.text() == available_version
def test_available_version_property_set_none(api_tab):
"""Test that the available version property is set correctly"""
# GIVEN: An uninitialised API tab
available_version = None
# WHEN: the available version is SET
api_tab.available_version = available_version
# THEN: The internal value should be set, and the right methods should have been called
assert api_tab._available_version == available_version
assert api_tab.available_version_value.text() == '(unknown)'
def test_installed_version_property_get_none(api_tab):
"""Test that the installed version property is None on init"""
# GIVEN: An uninitialised API tab
# WHEN: the installed version is GET'ed
result = api_tab.installed_version
# THEN: The result is None
assert result is None
def test_installed_version_property_set(api_tab):
"""Test that the installed version property is set correctly"""
# GIVEN: An uninitialised API tab
installed_version = '0.9.7'
# WHEN: the installed version is SET
api_tab.installed_version = installed_version
# THEN: The internal value should be set, and the right methods should have been called
assert api_tab._installed_version == installed_version
assert api_tab.installed_version_value.text() == installed_version
def test_installed_version_property_set_none(api_tab):
"""Test that the installed version property is set correctly"""
# GIVEN: An uninitialised API tab
installed_version = None
# WHEN: the installed version is SET
api_tab.installed_version = installed_version
# THEN: The internal value should be set, and the right methods should have been called
assert api_tab._installed_version == installed_version
assert api_tab.installed_version_value.text() == '(not installed)'
def test_validate_available_version(api_tab):
"""Test that the validate_available_version() method sets the label correctly"""
# GIVEN: An uninitialised API tab
# WHEN: validate_available_version() is run
api_tab.validate_available_version()
# THEN: The label should say "(unknown)"
assert api_tab.available_version_value.text() == '(unknown)'
@patch('openlp.core.api.tab.is_thread_finished')
def test_set_server_states_up(mock_is_thread_finished, registry, settings, api_tab):
"""Test getting the server states when the servers are up"""
# GIVEN: An API tab and some mocks
mock_is_thread_finished.return_value = False
# WHEN: set_server_states() is called
api_tab.set_server_states()
# THEN: The servers should all be "up"
assert api_tab.server_http_state.text() == 'Active'
assert api_tab.server_websocket_state.text() == 'Active'
assert api_tab.server_zeroconf_state.text() == 'Active'
@patch('openlp.core.api.tab.is_thread_finished')
def test_set_server_states_disabled(mock_is_thread_finished, registry, settings, api_tab):
"""Test getting the server states when the servers are disabled"""
# GIVEN: An API tab and some mocks
mock_is_thread_finished.return_value = True
registry.set_flag('no_web_server', True)
# WHEN: set_server_states() is called
api_tab.set_server_states()
# THEN: The servers should all be "up"
assert api_tab.server_http_state.text() == 'Disabled'
assert api_tab.server_websocket_state.text() == 'Disabled'
assert api_tab.server_zeroconf_state.text() == 'Disabled'
@patch('openlp.core.api.tab.is_thread_finished')
def test_set_server_states_down(mock_is_thread_finished, registry, settings, api_tab):
"""Test getting the server states when the servers are down"""
# GIVEN: An API tab and some mocks
mock_is_thread_finished.return_value = True
registry.set_flag('no_web_server', False)
# WHEN: set_server_states() is called
api_tab.set_server_states()
# THEN: The servers should all be "up"
assert api_tab.server_http_state.text() == 'Failed'
assert api_tab.server_websocket_state.text() == 'Failed'
assert api_tab.server_zeroconf_state.text() == 'Failed'
@patch('openlp.core.api.tab.download_version_info')
def test_on_check_for_updates_button_clicked(mocked_download_version_info, mocked_qapp, registry, settings, api_tab):
"""Test that the correct methods are called when the Check for Updates button is clicked"""
# GIVEN: An API tab and a couple of mocks
mocked_download_version_info.return_value = {'latest': {'version': '0.9.5'}}
mocked_main_window = MagicMock()
registry.register('main_window', mocked_main_window)
registry.remove('application')
registry.register('application', mocked_qapp)
# WHEN: The Check for Updates button is clicked
with patch.object(api_tab, 'can_enable_install_button') as mocked_can_enable_install_button:
mocked_can_enable_install_button.return_value = True
api_tab.on_check_for_updates_button_clicked()
assert mocked_can_enable_install_button.call_count == 2
# THEN: The correct methods were called
mocked_qapp.set_busy_cursor.assert_called_once()
assert mocked_qapp.process_events.call_count == 4
mocked_qapp.set_normal_cursor.assert_called_once()
mocked_download_version_info.assert_called_once()
mocked_main_window.information_message.assert_called_once_with(
'New version available!', 'There\'s a new version of the web remote available.'
)
assert api_tab.available_version == '0.9.5'
@patch('openlp.core.api.tab.DownloadProgressDialog')
@patch('openlp.core.api.tab.download_and_install')
@patch('openlp.core.api.tab.sleep')
def test_on_install_button_clicked(mocked_sleep, mocked_download_and_install, MockDownloadProgressDialog,
mocked_qapp, registry, settings, api_tab):
"""Test that the correct methods are called when the Check for Updates button is clicked"""
# GIVEN: An API tab and a couple of mocks
mocked_download_and_install.return_value = '0.9.6'
mocked_progress = MagicMock()
MockDownloadProgressDialog.return_value = mocked_progress
registry.remove('application')
registry.register('application', mocked_qapp)
# WHEN: The Check for Updates button is clicked
api_tab.on_install_button_clicked()
# THEN: The correct methods were called
assert mocked_qapp.process_events.call_count == 3
MockDownloadProgressDialog.assert_called_once_with(api_tab, mocked_qapp)
mocked_progress.show.assert_called_once()
mocked_progress.close.assert_called_once()
mocked_download_and_install.assert_called_once_with(mocked_progress)
assert api_tab.installed_version == '0.9.6'
assert settings.value('api/download version') == '0.9.6'