From ff8cedbcebd86750e90ecda3b1ee96c50112db1c Mon Sep 17 00:00:00 2001 From: Rohit prasad Date: Thu, 29 Aug 2024 17:34:28 +0530 Subject: [PATCH] test for the new features in the MFDW, topview & sideview (#2471) * MFDW test setup * set_colour test * requested way of implementation * all line style method test * get_random_colour method test * requested changes * CI fix * top_view tests * requested change in color test * test on sideview and topview complete * requested change --- mslib/msui/multiple_flightpath_dockwidget.py | 4 +- mslib/msui/sideview.py | 2 +- mslib/msui/topview.py | 2 +- mslib/utils/colordialog.py | 1 + .../test_multiple_flightpath_dockwidget.py | 240 ++++++++++++++++-- tests/_test_msui/test_sideview.py | 73 +++++- tests/_test_msui/test_topview.py | 68 ++++- 7 files changed, 349 insertions(+), 41 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index 380fb6bc8..bdaf9cfad 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -422,7 +422,7 @@ def select_color(self): else: color_dialog = CustomColorDialog(self) color_dialog.color_selected.connect(lambda color: self.apply_color(wp_model, color)) - color_dialog.exec_() + color_dialog.show() else: self.labelStatus.setText("Status: Check Mark the flighttrack to change its color.") elif self.list_operation_track.currentItem() is not None: @@ -983,7 +983,7 @@ def select_color(self): else: color_dialog = CustomColorDialog(self.parent) color_dialog.color_selected.connect(lambda color: self.apply_color(op_id, color)) - color_dialog.exec_() + color_dialog.show() else: self.parent.labelStatus.setText("Status: Check Mark the flighttrack to change its color.") diff --git a/mslib/msui/sideview.py b/mslib/msui/sideview.py index 8cb973464..8cccfbd27 100644 --- a/mslib/msui/sideview.py +++ b/mslib/msui/sideview.py @@ -172,7 +172,7 @@ def setColour(self, which): dialog = CustomColorDialog(self) dialog.color_selected.connect(lambda color: self.on_color_selected(which, color, button)) - dialog.exec_() + dialog.show() def on_color_selected(self, which, color, button): if color.isValid(): diff --git a/mslib/msui/topview.py b/mslib/msui/topview.py index 759aa2b71..8a1626cb4 100644 --- a/mslib/msui/topview.py +++ b/mslib/msui/topview.py @@ -190,7 +190,7 @@ def setColour(self, which): dialog = CustomColorDialog(self) dialog.color_selected.connect(lambda color: self.on_color_selected(which, color, button)) - dialog.exec_() + dialog.show() def on_color_selected(self, which, color, button): if color.isValid(): diff --git a/mslib/utils/colordialog.py b/mslib/utils/colordialog.py index 53ac19f27..6a2a0f0f2 100644 --- a/mslib/utils/colordialog.py +++ b/mslib/utils/colordialog.py @@ -60,6 +60,7 @@ def __init__(self, parent=None): row = i // 5 col = i % 5 swatch_layout.addWidget(button, row, col) + self.color_buttons.append(button) # Add "Pick Custom Color" button self.custom_color_button = QtWidgets.QPushButton("Pick Custom Color") diff --git a/tests/_test_msui/test_multiple_flightpath_dockwidget.py b/tests/_test_msui/test_multiple_flightpath_dockwidget.py index d25ffc3cf..bf1404912 100644 --- a/tests/_test_msui/test_multiple_flightpath_dockwidget.py +++ b/tests/_test_msui/test_multiple_flightpath_dockwidget.py @@ -25,33 +25,221 @@ limitations under the License. """ import pytest -from PyQt5 import QtTest +from PyQt5 import QtWidgets, QtCore, QtGui, QtTest +from unittest import mock + from mslib.msui import msui -from mslib.msui.multiple_flightpath_dockwidget import MultipleFlightpathControlWidget -from mslib.msui import flighttrack as ft import mslib.msui.topview as tv -class Test_MultipleFlightpathControlWidget: - @pytest.fixture(autouse=True) - def setup(self, qtbot): - self.window = msui.MSUIMainWindow() - self.window.create_new_flight_track() - - self.window.actionNewFlightTrack.trigger() - self.window.actionTopView.trigger() - initial_waypoints = [ft.Waypoint(40., 25., 0), ft.Waypoint(60., -10., 0), ft.Waypoint(40., 10, 0)] - self.waypoints_model = ft.WaypointsTableModel("myname") - self.waypoints_model.insertRows( - 0, rows=len(initial_waypoints), waypoints=initial_waypoints) - - self.widget = tv.MSUITopViewWindow(model=self.waypoints_model, mainwindow=self.window) - self.window.show() - QtTest.QTest.qWaitForWindowExposed(self.window) - yield - self.window.hide() - - def test_initialization(self): - widget = MultipleFlightpathControlWidget(parent=self.widget, - listFlightTracks=self.window.listFlightTracks) - assert widget.color == (0, 0, 1, 1) +@pytest.fixture +def main_window(qtbot): + """ + Set-up for the docking widget + """ + # Start a MSUI window + window = msui.MSUIMainWindow() + window.show() + qtbot.wait_exposed(window) + + # Create two flight tracks + window.actionNewFlightTrack.trigger() + window.actionNewFlightTrack.trigger() + + # Open a Top View window + window.actionTopView.trigger() + topview_window = window.listViews.currentItem().window + + # Switch to the Multiple Flightpath Widget + topview_window.cbTools.setCurrentIndex(6) + + # Get a reference to the created MultipleFlightpathControlWidget + multiple_flightpath_widget = topview_window.docks[tv.MULTIPLEFLIGHTPATH].widget() + + yield window, multiple_flightpath_widget + + window.hide() + + +def test_initialization(main_window): + """ + test for conforming docking widget has initialized + """ + _, multiple_flightpath_widget = main_window + + # Ensure the MultipleFlightpathControlWidget is correctly initialized + assert multiple_flightpath_widget is not None + assert multiple_flightpath_widget.color == (0, 0, 1, 1) + + +def test_setColour(main_window): + """ + test for the filghttrack colour + """ + main_window, multiple_flightpath_widget = main_window + color_button = multiple_flightpath_widget.pushButton_color + + # Activate the first flight track + activate_flight_track_at_index(main_window, 0) + + # Click on the second flight track in the docking widget + click_on_flight_track_in_docking_widget_at_index(multiple_flightpath_widget, 1) + + # Simulate clicking the button to open the color dialog + color_button.click() + + # Get a reference to the custom color dialog + color_dialog = multiple_flightpath_widget.findChild(QtWidgets.QDialog) + assert color_dialog is not None + + # Select the first color + color = QtGui.QColor(color_dialog.colors[0]) + color_dialog.color_buttons[0].click() + + # Verify that the flight track data structure was updated with the new color + wp_model = multiple_flightpath_widget.list_flighttrack.currentItem().flighttrack_model + applied_color_rgba = multiple_flightpath_widget.get_color(wp_model) + + # Convert the applied_color_rgba to a QColor object + applied_color = QtGui.QColor.fromRgbF(*applied_color_rgba) + + assert applied_color == color + + +def test_set_linewidth(main_window): + """ + test for the filghttrack line width + """ + main_window, multiple_flightpath_widget = main_window + + activate_flight_track_at_index(main_window, 0) + click_on_flight_track_in_docking_widget_at_index(multiple_flightpath_widget, 1) + + # Ensure the current item is checked + item = multiple_flightpath_widget.list_flighttrack.currentItem() + item.setCheckState(QtCore.Qt.Checked) + + # mock update_flighttrack_patch method to check if it gets called + with mock.patch.object(multiple_flightpath_widget, "update_flighttrack_patch") as mock_update_patch: + # s.et the line width + multiple_flightpath_widget.dsbx_linewidth.setValue(3.0) + mock_update_patch.assert_called_once_with(item.flighttrack_model) + + # Verify the line width has been updated in dict_flighttrack + wp_model = item.flighttrack_model + assert multiple_flightpath_widget.dict_flighttrack[wp_model]["linewidth"] == 3.0 + assert multiple_flightpath_widget.change_linewidth is True + + +def test_set_transparency(main_window): + """ + test for the filghttrack line transparency + """ + main_window, multiple_flightpath_widget = main_window + + activate_flight_track_at_index(main_window, 0) + click_on_flight_track_in_docking_widget_at_index(multiple_flightpath_widget, 1) + + item = multiple_flightpath_widget.list_flighttrack.currentItem() + item.setCheckState(QtCore.Qt.Checked) + + # Mock the update_flighttrack_patch method + with mock.patch.object(multiple_flightpath_widget, "update_flighttrack_patch") as mock_update_patch: + + multiple_flightpath_widget.hsTransparencyControl.setValue(50) + mock_update_patch.assert_called_once_with(item.flighttrack_model) + + # Verify the transparency has been updated in dict_flighttrack + wp_model = item.flighttrack_model + assert multiple_flightpath_widget.dict_flighttrack[wp_model]["line_transparency"] == (50 / 100) + assert multiple_flightpath_widget.change_line_transparency is True + + +def test_set_linestyle(main_window): + """ + test for the filghttrack line style + """ + main_window, multiple_flightpath_widget = main_window + + activate_flight_track_at_index(main_window, 0) + click_on_flight_track_in_docking_widget_at_index(multiple_flightpath_widget, 1) + + item = multiple_flightpath_widget.list_flighttrack.currentItem() + item.setCheckState(QtCore.Qt.Checked) + + # Mock the cbLineStyle setCurrentText and the update_flighttrack_patch method + with mock.patch.object(multiple_flightpath_widget, "update_flighttrack_patch") as mock_update_patch: + + multiple_flightpath_widget.cbLineStyle.setCurrentText('Dashed') + mock_update_patch.assert_called_once_with(item.flighttrack_model) + + # Verify the line style has been updated in dict_flighttrack + wp_model = item.flighttrack_model + expected_style = '--' + assert multiple_flightpath_widget.dict_flighttrack[wp_model]["line_style"] == expected_style + assert multiple_flightpath_widget.change_line_style is True + mock_update_patch.assert_called_once_with(wp_model) + + +def test_selectAll(main_window): + """ + Test the selectAll method by interacting with the UI directly. + """ + main_window, multiple_flightpath_widget = main_window + + # Check the "Select All" checkbox + select_all_checkbox = multiple_flightpath_widget.cbSlectAll1 + select_all_checkbox.setCheckState(QtCore.Qt.Checked) + + # Verify that all items in the list are checked + for i in range(multiple_flightpath_widget.list_flighttrack.count()): + item = multiple_flightpath_widget.list_flighttrack.item(i) + assert item.checkState() == QtCore.Qt.Checked + + select_all_checkbox.setCheckState(QtCore.Qt.Unchecked) + + # Verify that all items in the list are unchecked + for i in range(multiple_flightpath_widget.list_flighttrack.count()): + item = multiple_flightpath_widget.list_flighttrack.item(i) + assert item.checkState() == QtCore.Qt.Unchecked + + +def test_random_custom_color_selection(main_window): + """ + Test that a random custom color is selected automatically each time + and ensure that it is different from the previous selections. + """ + _, multiple_flightpath_widget = main_window + + # Select random colors multiple times + selected_colors = set() + for _ in range(10): # Test with 10 random selections + color = multiple_flightpath_widget.get_random_color() + normalized_color = tuple(int(c * 255) for c in color) + assert normalized_color not in selected_colors, "Duplicate color selected!" + selected_colors.add(normalized_color) + + # Check that all selected colors are from the custom_colors list + for color in selected_colors: + assert color in multiple_flightpath_widget.custom_colors + + +def activate_flight_track_at_index(main_window, index): + # The main window must be on top + main_window.activateWindow() + # get the item by its index + item = main_window.listFlightTracks.item(index) + point = main_window.listFlightTracks.visualItemRect(item).center() + QtTest.QTest.mouseClick(main_window.listFlightTracks.viewport(), QtCore.Qt.LeftButton, pos=point) + QtTest.QTest.mouseDClick(main_window.listFlightTracks.viewport(), QtCore.Qt.LeftButton, pos=point) + + +def click_on_flight_track_in_docking_widget_at_index(multiple_flightpath_widget, index): + # Activating the dock_widget window + multiple_flightpath_widget.activateWindow() + # Get the item by its index + item = multiple_flightpath_widget.list_flighttrack.item(index) + multiple_flightpath_widget.list_flighttrack.setCurrentItem(item) + # Simulate selection of the flight track by single clicking the item + point = multiple_flightpath_widget.list_flighttrack.visualItemRect(item).center() + QtTest.QTest.mouseClick(multiple_flightpath_widget.list_flighttrack.viewport(), QtCore.Qt.LeftButton, pos=point) diff --git a/tests/_test_msui/test_sideview.py b/tests/_test_msui/test_sideview.py index f57818ef7..1bb1cd828 100644 --- a/tests/_test_msui/test_sideview.py +++ b/tests/_test_msui/test_sideview.py @@ -65,18 +65,71 @@ def test_getFlightLevels(self): levels = self.window.get_flight_levels() assert all(x == y for x, y in zip(levels, [0, 300, 320, 340])) - @mock.patch("mslib.utils.colordialog.CustomColorDialog.exec_", return_value=QtWidgets.QDialog.Accepted) - @mock.patch("mslib.utils.colordialog.CustomColorDialog.color_selected", new_callable=mock.Mock) - def test_setColour(self, mock_color_selected, mockdlg): - QtTest.QTest.mouseClick(self.window.btFillColour, QtCore.Qt.LeftButton) - assert mockdlg.call_count == 1 + def test_setColour(self): + """ + Test the setColour function to ensure the color dialog opens and the correct color is set. + """ + # Simulate clicking the "Water" color button to open the color dialog + self.window.setColour("ft_vertices") + + # Get a reference to the custom color dialog + color_dialog = self.window.findChild(QtWidgets.QDialog) + assert color_dialog is not None + + # Select the first color in the color dialog (assuming color_buttons is a list of buttons) + color_dialog.color_buttons[0].click() + + # Get the selected color + selected_color = QtGui.QColor(color_dialog.colors[0]) + + # Verify that the button's color has been set correctly + button_palette = self.window.btVerticesColour.palette() + button_color = button_palette.button().color() + assert button_color.getRgbF() == selected_color.getRgbF() + + # Verify that the correct color was set in the settings + settings = self.window.get_settings() + assert settings['colour_ft_vertices'] == selected_color.getRgbF() + + def test_line_thickness_change(self): + """ + Test the thickness of the flighttrack + """ + # Verify initial value + assert self.window.line_thickness == _DEFAULT_SETTINGS_SIDEVIEW.get("line_thickness", 2) + + # Simulate changing line thickness + new_thickness = 5.00 + self.window.sbLineThickness.setValue(new_thickness) + + settings = self.window.get_settings() + assert settings['line_thickness'] == new_thickness + + def test_line_style_change(self): + """ + Test the style of the flighttrack + """ + assert self.window.line_style == _DEFAULT_SETTINGS_SIDEVIEW.get("line_style", "Solid") + + # Simulate changing line style + new_style = "Dashed" + self.window.cbLineStyle.setCurrentText(new_style) + + settings = self.window.get_settings() + assert settings['line_style'] == new_style + + def test_line_transparency_change(self): + """ + Test the transparency of the flighttrack + """ + assert self.window.line_transparency == _DEFAULT_SETTINGS_SIDEVIEW.get("line_transparency", 1.0) - # Simulate a color being selected - color = QtGui.QColor("#0000ff") # Example color - mock_color_selected.emit(color) + # Simulate changing transparency + new_transparency = 50 # == 0.5 + self.window.hsTransparencyControl.setValue(new_transparency) - # Ensure the color_selected signal was emitted - mock_color_selected.emit.assert_called_with(color) + settings = self.window.get_settings() + assert settings['line_transparency'] == new_transparency / 100 class Test_MSSSideViewWindow: diff --git a/tests/_test_msui/test_topview.py b/tests/_test_msui/test_topview.py index 88aaf5e40..e7bc2f3f3 100644 --- a/tests/_test_msui/test_topview.py +++ b/tests/_test_msui/test_topview.py @@ -31,7 +31,7 @@ import shutil import tempfile import mslib.msui.topview as tv -from PyQt5 import QtWidgets, QtCore, QtTest +from PyQt5 import QtWidgets, QtCore, QtTest, QtGui from mslib.msui import flighttrack as ft from mslib.msui.msui import MSUIMainWindow from mslib.msui.mpl_qtwidget import _DEFAULT_SETTINGS_TOPVIEW @@ -52,6 +52,72 @@ def test_show(self): def test_get(self): self.window.get_settings() + def test_setColour(self): + """ + Test the setColour function to ensure the color dialog opens and the correct color is set. + """ + # Simulate clicking the "Water" color button to open the color dialog + self.window.setColour("ft_vertices") + + # Get a reference to the custom color dialog + color_dialog = self.window.findChild(QtWidgets.QDialog) + assert color_dialog is not None + + # Select the first color in the color dialog (assuming color_buttons is a list of buttons) + color_dialog.color_buttons[0].click() + + # Get the selected color + selected_color = QtGui.QColor(color_dialog.colors[0]) + + # Verify that the button's color has been set correctly + button_palette = self.window.btVerticesColour.palette() + button_color = button_palette.button().color() + assert button_color.getRgbF() == selected_color.getRgbF() + + # Verify that the correct color was set in the settings + settings = self.window.get_settings() + assert settings['colour_ft_vertices'] == selected_color.getRgbF() + + def test_line_thickness_change(self): + """ + Test the thickness of flighttrack + """ + # Verify initial value + assert self.window.line_thickness == _DEFAULT_SETTINGS_TOPVIEW.get("line_thickness", 2) + + # Simulate changing line thickness + new_thickness = 5.00 + self.window.sbLineThickness.setValue(new_thickness) + + settings = self.window.get_settings() + assert settings['line_thickness'] == new_thickness + + def test_line_style_change(self): + """ + Test the style of flighttrack + """ + assert self.window.line_style == _DEFAULT_SETTINGS_TOPVIEW.get("line_style", "Solid") + + # Simulate changing line style + new_style = "Dashed" + self.window.cbLineStyle.setCurrentText(new_style) + + settings = self.window.get_settings() + assert settings['line_style'] == new_style + + def test_line_transparency_change(self): + """ + Test the transparency of flighttrack + """ + assert self.window.line_transparency == _DEFAULT_SETTINGS_TOPVIEW.get("line_transparency", 1.0) + + # Simulate changing transparency + new_transparency = 50 # == 0.5 + self.window.hsTransparencyControl.setValue(new_transparency) + + settings = self.window.get_settings() + assert settings['line_transparency'] == new_transparency / 100 + class Test_MSSTopViewWindow: @pytest.fixture(autouse=True)