pygadmin/tests/test_connection_dialog.py
2020-11-18 11:13:49 +01:00

504 lines
24 KiB
Python

import sys
import unittest
import keyring
from PyQt5.QtWidgets import QApplication, QLineEdit, QListWidgetItem
from pygadmin.widgets.connection_dialog import ConnectionDialogWidget
from pygadmin.connectionstore import global_connection_store
class TestConnectionDialogMethods(unittest.TestCase):
"""
Test the functionality and methods of the connection dialog in some essential aspects.
"""
def test_initial_attributes(self):
"""
Test basic attributes of the class after initializing.
"""
# Create an app, because this is necessary for testing a QDialog.
app = QApplication(sys.argv)
# Create a dialog.
connection_dialog = ConnectionDialogWidget()
# Check for the connection parameter edit dictionary, which is an essential element to the dialog.
assert isinstance(connection_dialog.connection_parameter_edit_dictionary, dict)
# Check every value in the dictionary for a QLineEdit.
for value in connection_dialog.connection_parameter_edit_dictionary.values():
# The elements should be QLineEdits.
assert isinstance(value, QLineEdit)
# The label for the status for testing the given connection should have the correct text.
assert connection_dialog.test_given_connection_status_label.text() == "Not tested yet"
def test_check_for_empty_parameter_fields(self):
"""
Test the function for checking for empty parameter fields.
"""
# Create an app, because this is necessary for testing a QDialog.
app = QApplication(sys.argv)
# Create a dialog.
connection_dialog = ConnectionDialogWidget()
# Get the current result for the check of empty parameter fields. It should not be a simple boolean, so it will
# be a list.
empty_parameter_result = connection_dialog.check_for_empty_parameter_edit_fields()
# The first parameter of the result list is a boolean, which should be True in this case.
assert empty_parameter_result[0] is True
# Set to every edit field a value.
for edit_field in connection_dialog.connection_parameter_edit_dictionary.values():
edit_field.setText("42")
# After setting values to every edit field, there should not be an empty parameter edit field.
assert connection_dialog.check_for_empty_parameter_edit_fields() is False
def test_check_for_valid_port(self):
"""
Test the function for checking for a valid port in the port line edit.
"""
# Create an app, because this is necessary for testing a QDialog.
app = QApplication(sys.argv)
# Create a dialog.
connection_dialog = ConnectionDialogWidget()
# Get the port line edit.
port_line_edit = connection_dialog.connection_parameter_edit_dictionary["Port"]
# Set a string, which can not be casted to an int, as text for the port.
port_line_edit.setText("This is a triumph. I'm making a note here, huge success.")
# The check for a valid port should be False.
assert connection_dialog.check_for_valid_port() is False
# Set a string, which can be casted to an int, as text for the port. The int in this case is invalid.
port_line_edit.setText("-42")
# The check for a valid port should still be False.
assert connection_dialog.check_for_valid_port() is False
# Set a valid and an int, which can be casted to int, as port.
port_line_edit.setText("42")
# The check for a valid port should now be True.
assert connection_dialog.check_for_valid_port() is True
def test_check_for_changed_password(self):
"""
Test the method for checking for a changed password in the QLineEdit for the password compared to the password
in the password manager.
"""
# Create an app, because this is necessary for testing a QDialog.
app = QApplication(sys.argv)
# Create a dialog.
connection_dialog = ConnectionDialogWidget()
# Define the name of the service.
service = "Pygadmin"
# Define the identifier for the password
password_identifier = "testuser@random:5432"
# Choose a password.
password = "unsafe"
# Set the password in the keyring.
keyring.set_password(service, password_identifier, password)
# Get the line edit for the password.
password_line_edit = connection_dialog.connection_parameter_edit_dictionary["Password"]
# Set the currently saved password as text.
password_line_edit.setText(password)
# The function for checking for a changed password should now be False.
assert connection_dialog.check_for_changed_password(password_identifier) is False
# Change the text in the password line edit to another password.
password_line_edit.setText("unsafe again")
# Now there should be a changed password compared to the password manager, so the result should be True.
assert connection_dialog.check_for_changed_password(password_identifier) is True
# Clean up, so the password identifier and the password for testing are not a part of the password manager.
keyring.delete_password(service, password_identifier)
def test_set_password_with_identifier(self):
"""
Test the method for setting a password with its identifier.
"""
# Create an app, because this is necessary for testing a QDialog.
app = QApplication(sys.argv)
# Create a dialog.
connection_dialog = ConnectionDialogWidget()
# Define the identifier for the password
password_identifier = "testuser@random:5432"
# Get the password line edit.
password_line_edit = connection_dialog.connection_parameter_edit_dictionary["Password"]
# Set a text as password in the password line edit.
password_line_edit.setText("unsafe")
# The function for setting the password with its identifier should be True.
assert connection_dialog.set_password_with_its_identifier(password_identifier) is True
# Clean up, so the password identifier and the password for testing are not a part of the password manager.
keyring.delete_password("Pygadmin", password_identifier)
def test_valid_find_occurrence_in_list_widget_and_select_item(self):
"""
Test the method for finding the occurrence of an item in a list widget. The item should be selected after the
call of the method. Use valid connection parameters, which are also part of the connection store.
"""
# Define a connection dictionary for saving the connection data in the connection store and creating a
# connection identifier later, so the connection is part of the list widget and can be selected.
connection_dictionary = {"Host": "random",
"Username": "testuser",
"Port": 5432,
"Database": "postgres"}
# Save the connection in the connection store.
global_connection_store.save_connection_parameters_in_yaml_file(connection_dictionary)
# Save the current connections in the connection store in the yaml file.
global_connection_store.commit_current_list_to_yaml()
# Create an app, because this is necessary for testing a QDialog.
app = QApplication(sys.argv)
# Create a dialog.
connection_dialog = ConnectionDialogWidget()
# Define a connection identifier for selecting it in the list widget.
connection_identifier = "{}@{}:{}/{}".format(connection_dictionary["Username"], connection_dictionary["Host"],
connection_dictionary["Port"], connection_dictionary["Database"])
# Get the item related to the connection identifier.
item = connection_dialog.find_occurrence_in_list_widget_and_select_item(connection_identifier)
# The item should be a QListWidgetItem.
assert isinstance(item, QListWidgetItem)
# The text of the item should be the connection identifier.
assert item.text() == connection_identifier
# Get the list of selected items.
selected_items = connection_dialog.connection_parameters_list_widget.selectedItems()
# Only one item should be selected, so the list should contain only one element.
assert len(selected_items) == 1
# Get the selected item.
selected_item = selected_items[0]
# The selected item should be the item, which is returned by the function.
assert selected_item == item
# Clean up, so the test connection is no longer part of the connection store.
global_connection_store.delete_connection(connection_dictionary)
global_connection_store.commit_current_list_to_yaml()
def test_invalid_find_occurrence_in_list_widget_and_select_item(self):
"""
Test the method for finding the occurrence of an item in a list widget. Use invalid connection parameters for
testing the error case, so the connection identifier is not based on existing connection parameters in the
connection store.
"""
# Create an app, because this is necessary for testing a QDialog.
app = QApplication(sys.argv)
# Create a dialog.
connection_dialog = ConnectionDialogWidget()
# Get a non existing item in the list widget.
item = connection_dialog.find_occurrence_in_list_widget_and_select_item(None)
# The item should be None.
assert item is None
# Check for the selected items in the list widget.
selected_items = connection_dialog.connection_parameters_list_widget.selectedItems()
# The list of selected items should be empty.
assert selected_items == []
def test_get_all_item_texts_in_list_widget(self):
"""
Test the method for getting all the texts of the items/connection identifiers in the list widget.
"""
# Create a list for storing all connection identifiers.
connection_identifiers = []
# Use every dictionary of a connection in the connection store to create an identifier for the connection.
for connection_dictionary in global_connection_store.connection_parameters_yaml:
# Create the connection identifier.
identifier = "{}@{}:{}/{}".format(connection_dictionary["Username"], connection_dictionary["Host"],
connection_dictionary["Port"], connection_dictionary["Database"])
# Append the identifier to the list of connection identifiers.
connection_identifiers.append(identifier)
# Create an app, because this is necessary for testing a QDialog.
app = QApplication(sys.argv)
# Create a dialog.
connection_dialog = ConnectionDialogWidget()
# Get all item texts.
item_texts = connection_dialog.get_all_item_texts_in_list_widget()
# Iterate over every identifier for checking its existence in the item texts.
for identifier in connection_identifiers:
# The identifier should be part of the item texts.
assert identifier in item_texts
def test_method_for_testing_database_connection(self):
"""
Test the method for testing for a valid database connection based on the current text in the QLineEdits.
"""
# Create an app, because this is necessary for testing a QDialog.
app = QApplication(sys.argv)
# Create a dialog.
connection_dialog = ConnectionDialogWidget()
# The text of the connection status label should be "Not tested yet", because a connection is not tested.
assert connection_dialog.test_given_connection_status_label.text() == "Not tested yet"
# Set valid connection parameters for testing a connection.
connection_dialog.connection_parameter_edit_dictionary["Host"].setText("localhost")
connection_dialog.connection_parameter_edit_dictionary["Username"].setText("testuser")
connection_dialog.connection_parameter_edit_dictionary["Database"].setText("postgres")
connection_dialog.connection_parameter_edit_dictionary["Port"].setText("5432")
# Test the connection with the method.
connection_dialog.test_current_database_connection()
# The label should now show a valid database connection, because valid parameters are used.
assert connection_dialog.test_given_connection_status_label.text() == "Connection Valid"
# Set a new text as host, so after a new test, the connection is invalid.
connection_dialog.connection_parameter_edit_dictionary["Host"].setText("localhorst")
# After changing the text, the label should switch back to "Not tested yet"
assert connection_dialog.test_given_connection_status_label.text() == "Not tested yet"
# Test the database connection now.
connection_dialog.test_current_database_connection()
# The label should now show an invalid connection.
assert connection_dialog.test_given_connection_status_label.text() == "Connection Invalid"
def test_insert_parameters_in_edit_fields(self):
"""
Test the method for inserting parameters in the QLineEdit fields based on the signal for a change in the
selection of the list widget.
"""
# Define a connection dictionary for saving the connection data in the connection store and creating a
# connection identifier later, so the connection is part of the list widget and can be selected.
connection_dictionary = {"Host": "random",
"Username": "testuser",
"Port": 5432,
"Database": "postgres"}
# Save the connection in the connection store.
global_connection_store.save_connection_parameters_in_yaml_file(connection_dictionary)
# Save the current connections in the connection store in the yaml file.
global_connection_store.commit_current_list_to_yaml()
# Create an app, because this is necessary for testing a QDialog.
app = QApplication(sys.argv)
# Create a dialog.
connection_dialog = ConnectionDialogWidget()
# Define a connection identifier for selecting it in the list widget.
connection_identifier = "{}@{}:{}/{}".format(connection_dictionary["Username"], connection_dictionary["Host"],
connection_dictionary["Port"], connection_dictionary["Database"])
# Select the item based on the connection identifier in the list widget.
connection_dialog.find_occurrence_in_list_widget_and_select_item(connection_identifier)
# Check the correct content of the QLineEdit fields. They should contain the parameters of the connection
# dictionary.
assert connection_dictionary["Host"] == connection_dialog.connection_parameter_edit_dictionary["Host"].text()
assert connection_dictionary["Username"] \
== connection_dialog.connection_parameter_edit_dictionary["Username"].text()
# Cast the port to string, because it is saved in the dictionary as integer.
assert str(connection_dictionary["Port"]) \
== connection_dialog.connection_parameter_edit_dictionary["Port"].text()
assert connection_dictionary["Database"] \
== connection_dialog.connection_parameter_edit_dictionary["Database"].text()
# Clean up, so the test connection is no longer part of the connection store.
global_connection_store.delete_connection(connection_dictionary)
global_connection_store.commit_current_list_to_yaml()
def test_get_selected_connection(self):
"""
Test the function for getting the selected connection, which returns a boolean and sets a result as an
attribute.
"""
# Define a connection dictionary for saving the connection data in the connection store and creating a
# connection identifier later, so the connection is part of the list widget and can be selected.
connection_dictionary = {"Host": "random",
"Username": "testuser",
"Port": 5432,
"Database": "postgres"}
# Save the connection in the connection store.
global_connection_store.save_connection_parameters_in_yaml_file(connection_dictionary)
# Save the current connections in the connection store in the yaml file.
global_connection_store.commit_current_list_to_yaml()
# Create an app, because this is necessary for testing a QDialog.
app = QApplication(sys.argv)
# Create a dialog.
connection_dialog = ConnectionDialogWidget()
# A selected connection is missing, so the method should return False.
assert connection_dialog.get_selected_connection() is False
# Define a connection identifier for selecting it in the list widget.
connection_identifier = "{}@{}:{}/{}".format(connection_dictionary["Username"], connection_dictionary["Host"],
connection_dictionary["Port"], connection_dictionary["Database"])
# Select the item related to the connection identifier.
connection_dialog.find_occurrence_in_list_widget_and_select_item(connection_identifier)
# Now the method should return True, because an identifier is selected.
assert connection_dialog.get_selected_connection() is True
# The dictionary of the selected connection should be the pre-defined connection dictionary.
assert connection_dialog.selected_connection_parameters_dictionary == connection_dictionary
# Clean up, so the test connection is no longer part of the connection store.
global_connection_store.delete_connection(connection_dictionary)
global_connection_store.commit_current_list_to_yaml()
def test_valid_delete_selected_connection(self):
"""
Test the method for deleting the selected database connection with a saved database connection.
"""
# Define a connection dictionary for saving the connection data in the connection store and creating a
# connection identifier later, so the connection is part of the list widget and can be selected.
connection_dictionary = {"Host": "random",
"Username": "testuser",
"Port": 5432,
"Database": "postgres"}
# Define a password identifier for setting a password, so it can be deleted.
password_identifier = "{}@{}:{}".format(connection_dictionary["Username"], connection_dictionary["Host"],
connection_dictionary["Port"])
keyring.set_password("Pygadmin", password_identifier, "test")
# Save the connection in the connection store.
global_connection_store.save_connection_parameters_in_yaml_file(connection_dictionary)
# Save the current connections in the connection store in the yaml file.
global_connection_store.commit_current_list_to_yaml()
# Create an app, because this is necessary for testing a QDialog.
app = QApplication(sys.argv)
# Create a dialog.
connection_dialog = ConnectionDialogWidget()
# Clean up, so the test connection is no longer part of the connection store.
global_connection_store.delete_connection(connection_dictionary)
global_connection_store.commit_current_list_to_yaml()
# Define a connection identifier for selecting it in the list widget.
connection_identifier = "{}@{}:{}/{}".format(connection_dictionary["Username"], connection_dictionary["Host"],
connection_dictionary["Port"], connection_dictionary["Database"])
# Select the item related to the connection identifier.
connection_dialog.find_occurrence_in_list_widget_and_select_item(connection_identifier)
# The deletion of the selected connection should return True.
assert connection_dialog.delete_selected_connection() is True
def test_invalid_delete_selected_connection(self):
"""
Test the method for deleting the selected database connection with an unsaved database connection.
"""
# Define a connection dictionary for saving the connection data in the connection store and creating a
# connection identifier later, so the connection is part of the list widget and can be selected.
connection_dictionary = {"Host": "random",
"Username": "testuser",
"Port": 5432,
"Database": "postgres"}
# Save the connection in the connection store.
global_connection_store.save_connection_parameters_in_yaml_file(connection_dictionary)
# Save the current connections in the connection store in the yaml file.
global_connection_store.commit_current_list_to_yaml()
# Create an app, because this is necessary for testing a QDialog.
app = QApplication(sys.argv)
# Create a dialog.
connection_dialog = ConnectionDialogWidget()
# Clean up, so the test connection is no longer part of the connection store.
global_connection_store.delete_connection(connection_dictionary)
global_connection_store.commit_current_list_to_yaml()
# Define a connection identifier for selecting it in the list widget.
connection_identifier = "{}@{}:{}/{}".format(connection_dictionary["Username"], connection_dictionary["Host"],
connection_dictionary["Port"], connection_dictionary["Database"])
# Select the item related to the connection identifier.
connection_dialog.find_occurrence_in_list_widget_and_select_item(connection_identifier)
# The deletion of the selected connection should not return True.
assert connection_dialog.delete_selected_connection() is not True
def test_check_for_valid_timeout(self):
"""
Test the method for checking for a valid timeout.
"""
# Create an app, because this is necessary for testing a QDialog.
app = QApplication(sys.argv)
# Create a dialog.
connection_dialog = ConnectionDialogWidget()
# Set the text to an empty string, so a cast to an integer is not possible.
connection_dialog.timeout_line_edit.setText("")
# The timeout should be invalid.
assert connection_dialog.check_for_valid_timeout() is False
# Set the text to an invalid integer value.
connection_dialog.timeout_line_edit.setText("-42")
# The timeout should still be invalid.
assert connection_dialog.check_for_valid_timeout() is False
# Set the text to a valid integer value.
connection_dialog.timeout_line_edit.setText("42")
# The result should now be True.
assert connection_dialog.check_for_valid_timeout() is True
def test_port_checkbox(self):
"""
Test the correct behavior of the (de)activation of the checkbox for using the standard postgres port.
"""
# Create an app, because this is necessary for testing a QDialog.
app = QApplication(sys.argv)
# Create a dialog.
connection_dialog = ConnectionDialogWidget()
# Get the use postgres port checkbox of the dialog.
postgres_port_checkbox = connection_dialog.use_postgres_port_checkbox
# Get the port line edit.
port_line_edit = connection_dialog.connection_parameter_edit_dictionary["Port"]
# Set the checkbox unchecked.
postgres_port_checkbox.setChecked(False)
# Now the port line edit should be empty.
assert port_line_edit.text() == ""
# Define a port text for further testing.
port_text = "1337"
# Set the text as current text of the port line edit field.
port_line_edit.setText(port_text)
# Set the port checkbox to checked.
postgres_port_checkbox.setChecked(True)
# Now the port line edit should contain the standard postgres port as text.
assert port_line_edit.text() == "5432"
# Set the port checkbox back to unchecked.
postgres_port_checkbox.setChecked(False)
# Now the checkbox should contain the port text, which has been set earlier.
assert port_line_edit.text() == port_text