Source code for schrodinger.test.ld_base_test_classes

from unittest.mock import Mock
from unittest.mock import patch

import pytest

from schrodinger.application.livedesign import live_report_widget
from schrodinger.application.livedesign import login
from schrodinger.Qt.QtGui import QColor
from schrodinger.test import custom_test_classes
from schrodinger.test import ld_mock_modules
from schrodinger.test import mock_ld_models
from schrodinger.ui.qt.appframework2 import tasks

LIVEDESIGN = 'schrodinger.application.livedesign'
LD_BASE_CLASSES = f'{LIVEDESIGN}.ld_base_classes'
LOGIN = f'{LIVEDESIGN}.login'
EMM = f'{LIVEDESIGN}.export_map_manager'
LD_IMPORT = f'{LIVEDESIGN}.ld_import'
LD_EXPORT = f'{LIVEDESIGN}.ld_export'
IE_BASE_PANEL = LD_BASE_CLASSES + '.ImportExportBasePanel'
MBM = 'schrodinger.ui.qt.widgetmixins.basicmixins.MessageBoxMixin'
WARNING = f'{MBM}.warning'


[docs]class MockBaseLDTreeItemWrapper(mock_ld_models.MockNameAndID):
[docs] def __init__(self, name=None, id_=None, title=None, live_report=None): if live_report is not None: id_ = live_report.id name = live_report.title title = live_report.title super().__init__(name, id_) self.title = title
[docs]class BaseTestCases:
[docs] class ExportBasePanelTest(custom_test_classes.MultiModulePatchMixin): MODULE_MAP = {'login': [LD_EXPORT], 'get_ld_client_and_models': LOGIN} PANEL_CLASS = NotImplemented
[docs] def setup(self): super().setup() self.panel = self.PANEL_CLASS() mock_login = self._getLogin() model = self.panel.model model.ld_client = self.mock_ldclient model.ld_models = self.mock_models model.ld_destination.host = mock_login.get_host()
def _getLogin(self): """ :return: an instance of the class used to mock the `login` module :rtype: ld_mock_modules.MockLogin """ return self._mock_module_map['login'] def _setupMockedModules(self): mock_login = ld_mock_modules.MockLogin() self._mock_module_map['login'] = mock_login _, self.mock_ldclient, self.mock_models = mock_login.get_ld_client_and_models( ) mock_GLDCAM = Mock() mock_GLDCAM.return_value = mock_login.get_ld_client_and_models() self._mock_module_map['get_ld_client_and_models'] = mock_GLDCAM
[docs] def test_setStatus(self): """ Verify that the `setStatus()` method properly alters the task bar. """ panel = self.panel bar = panel.status_bar # Test 1: Text only text = 'test 1' panel.setStatus(text) assert bar.currentMessage() == text # TODO: test color from the style sheet. Should look something like: # sheet_txt = (f'QStatusBar{{color: rgb({color.red()},{color.green()},' # f'{color.blue()}); font:bold}}') # Test 2: Text and color text = 'test 2' red = QColor(255, 0, 0, 0) panel.setStatus(text, color=red) assert bar.currentMessage() == text
# TODO: test for red
[docs] @patch(f'{EMM}.ExportMapManager.getAvailableMappings') def test__onLiveReportTextEdited(self, mock_avail_maps): """ Verify that the panel responds appropriately when the user finishes editing the live report line edit. This should update relevant instance variables of the panel and attempt to retrieve information from the LiveDesign server. `mock_avail_maps` is necessary to avoid any actual directories being accessed (PANEL-15417). """ mock_avail_maps.return_value = [] panel = self.panel ld_dest = panel.model.ld_destination ld_client = panel.model.ld_client lr_widget = panel.lr_widget lrw_model = lr_widget.model login = self._getLogin() orig_host = login.get_host() # Establish default values assert ld_dest.host == orig_host assert ld_dest.proj_name == '' assert ld_dest.lr_name == '' assert ld_dest.lr_id == '' assert lrw_model.previous_lr_user_text == '' # Set up mocks exp_lr_name = 'FernGully: The Last Rainforest' exp_proj_id = mock_ld_models.DEFAULT_PROJ_ID exp_proj_name = None for project in ld_client.projects(): if project.id == exp_proj_id: exp_proj_name = project.name break mock_lr = mock_ld_models.MockLiveReport(title=exp_lr_name, project_id=exp_proj_id) mock_lr = ld_client.create_live_report(mock_lr) exp_lr_id = mock_lr.id # If a new URL is entered, the panel model should update lr_url = (f'{orig_host}/livedesign/#/projects/{exp_proj_id}/' f'livereports/{exp_lr_id}') lrw_model.lr_user_text = lr_url # The panel model should not update until the user has finished # editing the text in the line edit assert ld_dest.host == orig_host assert ld_dest.proj_name == '' assert ld_dest.lr_name == '' assert ld_dest.lr_id == '' assert lrw_model.previous_lr_user_text == '' # Once this occurs, relevant model data will be assigned lr_widget._onLiveReportURLLoad() assert ld_dest.host == orig_host assert ld_dest.proj_name == exp_proj_name assert ld_dest.lr_name == exp_lr_name assert ld_dest.lr_id == exp_lr_id assert lrw_model.previous_lr_user_text == lr_url # If the text is edited but the value is unchanged, do nothing lr_widget._onLiveReportURLLoad() assert ld_dest.host == orig_host assert ld_dest.proj_name == exp_proj_name assert ld_dest.lr_name == exp_lr_name assert ld_dest.lr_id == exp_lr_id assert lrw_model.previous_lr_user_text == lr_url # If an invalid string is entered, clear everything lrw_model.lr_user_text = 'an invalid URL' with patch(WARNING) as mock_warning: lr_widget._onLiveReportURLLoad() assert mock_warning.call_count == 1 # After the warning is displayed, clear everything in the widget, # including the "last_lr_text" value; otherwise, if the user enters # the same bad value, they will not be presented with the same # warning. assert ld_dest.host == orig_host assert ld_dest.proj_name == '' assert ld_dest.lr_name == '' assert ld_dest.lr_id == '' assert lrw_model.previous_lr_user_text == ''
[docs] class ImportBasePanelTest(custom_test_classes.MultiModulePatchMixin): MODULE_MAP = { 'login': [LD_BASE_CLASSES, LD_IMPORT], 'get_ld_client_and_models': LOGIN } PANEL_CLASS = None
[docs] def setup(self): super().setup() self.panel = self.PANEL_CLASS() mock_login = self._getLogin() host = mock_login.get_host() print(f'setup() host: {host}') mock_state = { login.CLIENT: self.mock_ldclient, login.MODELS: self.mock_models, login.HOST: host } self.panel.loadLDClient() print(f'host 1: {self.panel.lr_widget.model.ld_destination.host}') self.panel.processPrevPanel(mock_state) print(f'host 2: {self.panel.lr_widget.model.ld_destination.host}')
def _getLogin(self): return self._mock_module_map['login'] def _setupMockedModules(self): mock_login = ld_mock_modules.MockLogin() self._mock_module_map['login'] = mock_login _, self.mock_ldclient, self.mock_models = mock_login.get_ld_client_and_models( ) mock_GLDCAM = Mock() mock_GLDCAM.return_value = mock_login.get_ld_client_and_models() self._mock_module_map['get_ld_client_and_models'] = mock_GLDCAM
[docs] def testInstantiation(self): """ Make sure that the panel can be instantiated """ assert isinstance(self.panel, self.PANEL_CLASS)
[docs] @patch(WARNING) @patch(IE_BASE_PANEL + '.error') @patch(IE_BASE_PANEL + '.info') @patch(IE_BASE_PANEL + '.question') def test_processTaskMessage(self, mock_question, mock_info, mock_error, mock_warning): """ Test if all messaging signals for the Task Runner are connected to the GUI. """ panel = self.panel # Test 1: Warning msg panel.processTaskMessage(tasks.WARNING, 'testing') mock_warning.assert_called_once_with('testing', '') # Test 2: Critical msg panel.processTaskMessage(tasks.ERROR, 'testing2') mock_error.assert_called_once_with('testing2', '') # Test 3: Information msg panel.processTaskMessage(tasks.INFO, 'testing3') mock_info.assert_called_once_with('testing3', '') # Test 4: Question panel.processTaskMessage(tasks.QUESTION, 'testing4') mock_question.assert_called_once_with('testing4', '') # Test 5: Invalid msg with pytest.raises(ValueError): panel.processTaskMessage(1837, 'testing5') # Test 6: Status bar msg panel.processTaskMessage(tasks.STATUS, 'testing2') assert panel.status_bar.currentMessage() == 'testing2' # Test 7: Status bar msg that should be ignored by # processTaskMessage() panel.processTaskMessage(tasks.STATUS, 'Task completed') assert panel.status_bar.currentMessage() == 'testing2' # Test 7: Second status bar msg that should be ignored by # processTaskMessage() panel.processTaskMessage(tasks.STATUS, 'Task status: Finished') assert panel.status_bar.currentMessage() == 'testing2'
[docs] @patch(f'{EMM}.ExportMapManager.getAvailableMappings') def test__onLiveReportURLLoad(self, mock_avail_maps): """ Verify that the panel responds appropriately when the user finishes editing the live report line edit and clicks the confirm button. This should update relevant instance variables of the panel and attempt to retrieve information from the LiveDesign server. """ # PANEL-15417 Added mock_avail_maps patch to avoid actual directory being called mock_avail_maps.return_value = [] panel = self.panel lr_widget, lrw_ui = panel.lr_widget, panel.lr_widget.ui # Establish default values assert panel.project_id == '' assert panel.live_report_id == '' assert lrw_ui.project_state_lbl.text( ) == live_report_widget.NONE_SELECTED assert lrw_ui.lr_state_lbl.text( ) == live_report_widget.NONE_SELECTED # Set up mocks mock_ld_client = panel.ld_client exp_title = 'FernGully: The Last Rainforest' exp_proj_id = mock_ld_models.DEFAULT_PROJ_ID exp_proj_name = None for project in mock_ld_client.projects(): if project.id == exp_proj_id: exp_proj_name = project.name break mock_lr = mock_ld_models.MockLiveReport(title=exp_title, project_id=exp_proj_id) mock_lr = mock_ld_client.create_live_report(mock_lr) exp_lr_id = mock_lr.id # If a new URL is entered, instance variables should be changed login = self._getLogin() host = login.get_host() lr_url = (f'{host}/livedesign/#/projects/{exp_proj_id}/livereports/' f'{exp_lr_id}') lrw_ui.lr_text_le.setText(lr_url) lr_widget._onLiveReportURLLoad() assert panel.project_id == exp_proj_id assert panel.live_report_id == exp_lr_id assert panel.project_name == exp_proj_name assert lrw_ui.project_state_lbl.text() == get_bolded_text( exp_proj_name) assert lrw_ui.lr_state_lbl.text() == get_bolded_text(exp_title) # If the text is edited but the value is unchanged, do nothing lr_widget._onLiveReportURLLoad() assert panel.project_id == exp_proj_id assert panel.live_report_id == exp_lr_id assert panel.project_name == exp_proj_name assert lrw_ui.project_state_lbl.text() == get_bolded_text( exp_proj_name) assert lrw_ui.lr_state_lbl.text() == get_bolded_text(exp_title) # If an invalid string is entered, clear everything bad_lr_text = 'no scrubs' lrw_ui.lr_text_le.setText(bad_lr_text) with patch(WARNING) as mock_warning: lr_widget._onLiveReportURLLoad() assert mock_warning.call_count == 1 # After the warning is displayed, clear everything in the widget assert panel.project_id == '' assert panel.live_report_id == '' assert lrw_ui.project_state_lbl.text( ) == live_report_widget.NONE_SELECTED assert lrw_ui.lr_state_lbl.text( ) == live_report_widget.NONE_SELECTED
[docs]def get_bolded_text(text): """ Returns the text with HTML bold tags applied :param text: text to bold :type text: str :return: bolded text :rtype: str """ return f'<b>{text}</b>'