# -*- coding: utf-8 -*- """novelWriter Project Settings Dialog Class Tester """ import pytest import os from shutil import copyfile from tools import cmpFiles, getGuiItem from PyQt5.QtGui import QColor from PyQt5.QtCore import Qt from PyQt5.QtWidgets import ( QDialog, QAction, QMessageBox, QColorDialog, QListWidgetItem ) from nw.gui import GuiProjectSettings keyDelay = 2 typeDelay = 1 stepDelay = 20 @pytest.mark.gui def testGuiProjSettings_Dialog(qtbot, monkeypatch, nwGUI, fncDir, fncProj, outDir, refDir): """Test the full project settings dialog. """ projFile = os.path.join(fncProj, "nwProject.nwx") testFile = os.path.join(outDir, "guiProjSettings_Dialog_nwProject.nwx") compFile = os.path.join(refDir, "guiProjSettings_Dialog_nwProject.nwx") # Block message box monkeypatch.setattr(QMessageBox, "question", lambda *args: QMessageBox.Yes) # Check that we cannot open when there is no project nwGUI.mainMenu.aProjectSettings.activate(QAction.Trigger) assert getGuiItem("GuiProjectSettings") is None # Create new project nwGUI.theProject.projTree.setSeed(42) assert nwGUI.newProject({"projPath": fncProj}) nwGUI.mainConf.backupPath = fncDir nwGUI.theProject.setSpellLang("en") nwGUI.theProject.setBookAuthors("Jane Smith\nJohn Smith") nwGUI.theProject.setAutoReplace({"A": "B", "C": "D"}) # Get the dialog object monkeypatch.setattr(GuiProjectSettings, "exec_", lambda *args: None) monkeypatch.setattr(GuiProjectSettings, "result", lambda *args: QDialog.Accepted) nwGUI.mainMenu.aProjectSettings.activate(QAction.Trigger) qtbot.waitUntil(lambda: getGuiItem("GuiProjectSettings") is not None, timeout=1000) projEdit = getGuiItem("GuiProjectSettings") assert isinstance(projEdit, GuiProjectSettings) projEdit.show() qtbot.addWidget(projEdit) # Settings Tab # ============ assert projEdit.tabMain.editName.text() == "New Project" assert projEdit.tabMain.editTitle.text() == "" assert projEdit.tabMain.editAuthors.toPlainText() == "Jane Smith\nJohn Smith\n" assert projEdit.tabMain.spellLang.currentData() == "en" assert projEdit.tabMain.doBackup.isChecked() is False qtbot.wait(stepDelay) projEdit.tabMain.editName.setText("") for c in "Project Name": qtbot.keyClick(projEdit.tabMain.editName, c, delay=typeDelay) for c in "Project Title": qtbot.keyClick(projEdit.tabMain.editTitle, c, delay=typeDelay) projEdit.tabMain.editAuthors.clear() for c in "Jane Doe": qtbot.keyClick(projEdit.tabMain.editAuthors, c, delay=typeDelay) qtbot.keyClick(projEdit.tabMain.editAuthors, Qt.Key_Return, delay=keyDelay) for c in "John Doh": qtbot.keyClick(projEdit.tabMain.editAuthors, c, delay=typeDelay) qtbot.keyClick(projEdit.tabMain.editAuthors, Qt.Key_Return, delay=keyDelay) qtbot.wait(stepDelay) assert projEdit.tabMain.editName.text() == "Project Name" assert projEdit.tabMain.editTitle.text() == "Project Title" assert projEdit.tabMain.editAuthors.toPlainText() == "Jane Doe\nJohn Doh\n" # Status Tab # ========== projEdit._tabBox.setCurrentWidget(projEdit.tabStatus) assert projEdit.tabStatus.colChanged is False assert projEdit.tabStatus.getNewList() is None assert projEdit.tabStatus.listBox.count() == 4 # Fake drag'n'drop should change changed status projEdit.tabStatus._rowsMoved() assert projEdit.tabStatus.colChanged is True projEdit.tabStatus.colChanged = False projEdit.tabStatus.listBox.clearSelection() assert projEdit.tabStatus._getSelectedItem() is None projEdit.tabStatus.listBox.item(0).setSelected(True) assert isinstance(projEdit.tabStatus._getSelectedItem(), QListWidgetItem) # Can't delete the first item (it's in use) projEdit.tabStatus.listBox.item(0).setSelected(True) qtbot.mouseClick(projEdit.tabStatus.delButton, Qt.LeftButton) assert projEdit.tabStatus.listBox.count() == 4 # Can delete the third item projEdit.tabStatus.listBox.item(2).setSelected(True) qtbot.mouseClick(projEdit.tabStatus.delButton, Qt.LeftButton) assert projEdit.tabStatus.listBox.count() == 3 # Add a new item monkeypatch.setattr(QColorDialog, "getColor", lambda *args: QColor(20, 30, 40)) qtbot.mouseClick(projEdit.tabStatus.newButton, Qt.LeftButton) projEdit.tabStatus.listBox.item(3).setSelected(True) for n in range(8): qtbot.keyClick(projEdit.tabStatus.editName, Qt.Key_Backspace, delay=typeDelay) for c in "Final": qtbot.keyClick(projEdit.tabStatus.editName, c, delay=typeDelay) qtbot.mouseClick(projEdit.tabStatus.colButton, Qt.LeftButton) qtbot.mouseClick(projEdit.tabStatus.saveButton, Qt.LeftButton) assert projEdit.tabStatus.listBox.count() == 4 qtbot.wait(stepDelay) assert projEdit.tabStatus.colChanged is True assert projEdit.tabStatus.getNewList() == [ ("New", 100, 100, 100, "New"), ("Note", 200, 50, 0, "Note"), ("Finished", 50, 200, 0, "Finished"), ("Final", 20, 30, 40, None) ] # Importance Tab # ============== projEdit._tabBox.setCurrentWidget(projEdit.tabImport) projEdit.tabImport.listBox.item(3).setSelected(True) qtbot.mouseClick(projEdit.tabImport.delButton, Qt.LeftButton) qtbot.mouseClick(projEdit.tabImport.newButton, Qt.LeftButton) projEdit.tabImport.listBox.item(3).setSelected(True) for n in range(8): qtbot.keyClick(projEdit.tabImport.editName, Qt.Key_Backspace, delay=typeDelay) for c in "Final": qtbot.keyClick(projEdit.tabImport.editName, c, delay=typeDelay) qtbot.mouseClick(projEdit.tabImport.saveButton, Qt.LeftButton) qtbot.wait(stepDelay) # Auto-Replace Tab # ================ qtbot.wait(stepDelay) projEdit._tabBox.setCurrentWidget(projEdit.tabReplace) assert projEdit.tabReplace.listBox.topLevelItem(0).text(0) == "" assert projEdit.tabReplace.listBox.topLevelItem(0).text(1) == "B" assert projEdit.tabReplace.listBox.topLevelItem(1).text(0) == "" assert projEdit.tabReplace.listBox.topLevelItem(1).text(1) == "D" qtbot.mouseClick(projEdit.tabReplace.addButton, Qt.LeftButton) projEdit.tabReplace.listBox.topLevelItem(2).setSelected(True) projEdit.tabReplace.editKey.setText("") for c in "Th is ": qtbot.keyClick(projEdit.tabReplace.editKey, c, delay=typeDelay) projEdit.tabReplace.editValue.setText("") for c in "With This Stuff ": qtbot.keyClick(projEdit.tabReplace.editValue, c, delay=typeDelay) qtbot.mouseClick(projEdit.tabReplace.saveButton, Qt.LeftButton) qtbot.wait(stepDelay) projEdit.tabReplace.listBox.clearSelection() assert not projEdit.tabReplace._saveEntry() assert not projEdit.tabReplace._delEntry() qtbot.mouseClick(projEdit.tabReplace.addButton, Qt.LeftButton) newIdx = -1 for i in range(projEdit.tabReplace.listBox.topLevelItemCount()): if projEdit.tabReplace.listBox.topLevelItem(i).text(0) == "": newIdx = i break assert newIdx >= 0 newItem = projEdit.tabReplace.listBox.topLevelItem(newIdx) projEdit.tabReplace.listBox.setCurrentItem(newItem) qtbot.mouseClick(projEdit.tabReplace.delButton, Qt.LeftButton) qtbot.wait(stepDelay) # Save & Check # ============ projEdit._doSave() # Open again, and check project settings nwGUI.mainMenu.aProjectSettings.activate(QAction.Trigger) qtbot.waitUntil(lambda: getGuiItem("GuiProjectSettings") is not None, timeout=1000) projEdit = getGuiItem("GuiProjectSettings") assert isinstance(projEdit, GuiProjectSettings) qtbot.addWidget(projEdit) assert projEdit.tabMain.editName.text() == "Project Name" assert projEdit.tabMain.editTitle.text() == "Project Title" theAuth = projEdit.tabMain.editAuthors.toPlainText().strip().splitlines() assert len(theAuth) == 2 assert theAuth[0] == "Jane Doe" assert theAuth[1] == "John Doh" projEdit._doClose() qtbot.wait(stepDelay) assert nwGUI.saveProject() qtbot.wait(stepDelay) # Check the files copyfile(projFile, testFile) assert cmpFiles(testFile, compFile, [2, 8, 9, 10]) # qtbot.stopForInteraction() # END Test testGuiProjSettings_Dialog