Update tests for project tree deleting items
This commit is contained in:
@@ -602,7 +602,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
self.setTreeItemValues(tHandle)
|
self.setTreeItemValues(tHandle)
|
||||||
self._alertTreeChange(tHandle, flush=False)
|
self._alertTreeChange(tHandle, flush=False)
|
||||||
|
|
||||||
return
|
return True
|
||||||
|
|
||||||
def saveTreeOrder(self):
|
def saveTreeOrder(self):
|
||||||
"""Build a list of the items in the project tree and send them
|
"""Build a list of the items in the project tree and send them
|
||||||
@@ -657,11 +657,11 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
if self.theProject.tree.isTrash(tHandle) or nwItem.isRootType():
|
if self.theProject.tree.isTrash(tHandle) or nwItem.isRootType():
|
||||||
self.permanentlyDeleteItem(tHandle)
|
status = self.permanentlyDeleteItem(tHandle)
|
||||||
else:
|
else:
|
||||||
self.moveItemToTrash(tHandle)
|
status = self.moveItemToTrash(tHandle)
|
||||||
|
|
||||||
return True
|
return status
|
||||||
|
|
||||||
def emptyTrash(self):
|
def emptyTrash(self):
|
||||||
"""Permanently delete all documents in the Trash folder. This
|
"""Permanently delete all documents in the Trash folder. This
|
||||||
@@ -697,6 +697,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
self.tr("Permanently delete {0} file(s) from Trash?").format(nTrash)
|
self.tr("Permanently delete {0} file(s) from Trash?").format(nTrash)
|
||||||
)
|
)
|
||||||
if not msgYes:
|
if not msgYes:
|
||||||
|
logger.info("Action cancelled by user")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
logger.verbose("Deleting %d file(s) from Trash", nTrash)
|
logger.verbose("Deleting %d file(s) from Trash", nTrash)
|
||||||
@@ -761,7 +762,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def permanentlyDeleteItem(self, tHandle, askFirst=True, flush=False):
|
def permanentlyDeleteItem(self, tHandle, askFirst=True, flush=True):
|
||||||
"""Permanently delete a tree item from the project and the map.
|
"""Permanently delete a tree item from the project and the map.
|
||||||
Root items are handled a little different than other items.
|
Root items are handled a little different than other items.
|
||||||
"""
|
"""
|
||||||
|
|||||||
+291
-184
@@ -19,8 +19,8 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pytest
|
|
||||||
import os
|
import os
|
||||||
|
import pytest
|
||||||
|
|
||||||
from tools import buildTestProject
|
from tools import buildTestProject
|
||||||
|
|
||||||
@@ -42,113 +42,127 @@ def testGuiProjTree_NewItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockRnd)
|
|||||||
monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes)
|
monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes)
|
||||||
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
||||||
|
|
||||||
nwTree = nwGUI.projView
|
projView = nwGUI.projView
|
||||||
|
projTree = nwGUI.projView.projTree
|
||||||
|
theProject = nwGUI.theProject
|
||||||
|
|
||||||
# Try to add item with no project
|
# Try to add item with no project
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FILE) is False
|
assert projView.projTree.newTreeItem(nwItemType.FILE) is False
|
||||||
|
|
||||||
# Create a project
|
# Create a project
|
||||||
prjDir = os.path.join(fncDir, "project")
|
prjDir = os.path.join(fncDir, "project")
|
||||||
buildTestProject(nwGUI, prjDir)
|
buildTestProject(nwGUI, prjDir)
|
||||||
|
|
||||||
# No itemType set
|
# No itemType set
|
||||||
nwTree.projTree.clearSelection()
|
projView.projTree.clearSelection()
|
||||||
assert nwTree.projTree.newTreeItem(None) is False
|
assert projView.projTree.newTreeItem(None) is False
|
||||||
|
|
||||||
# Root Items
|
# Root Items
|
||||||
# ==========
|
# ==========
|
||||||
|
|
||||||
# No class set
|
# No class set
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.ROOT) is False
|
assert projView.projTree.newTreeItem(nwItemType.ROOT) is False
|
||||||
|
|
||||||
# Create root item
|
# Create root item
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.ROOT, nwItemClass.WORLD) is True
|
assert projView.projTree.newTreeItem(nwItemType.ROOT, nwItemClass.WORLD) is True
|
||||||
assert "0000000000010" in nwGUI.theProject.tree
|
assert "0000000000010" in theProject.tree
|
||||||
|
|
||||||
# File/Folder Items
|
# File/Folder Items
|
||||||
# =================
|
# =================
|
||||||
|
|
||||||
# No location selected for new item
|
# No location selected for new item
|
||||||
nwTree.projTree.clearSelection()
|
projView.projTree.clearSelection()
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FILE) is False
|
assert projView.projTree.newTreeItem(nwItemType.FILE) is False
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FOLDER) is False
|
assert projView.projTree.newTreeItem(nwItemType.FOLDER) is False
|
||||||
assert "Did not find anywhere" in caplog.text
|
assert "Did not find anywhere" in caplog.text
|
||||||
|
|
||||||
# Create new folder as child of Novel folder
|
# Create new folder as child of Novel folder
|
||||||
nwTree.setSelectedHandle("0000000000008")
|
projView.setSelectedHandle("0000000000008")
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FOLDER) is True
|
assert projView.projTree.newTreeItem(nwItemType.FOLDER) is True
|
||||||
assert nwGUI.theProject.tree["0000000000011"].itemParent == "0000000000008"
|
assert theProject.tree["0000000000011"].itemParent == "0000000000008"
|
||||||
assert nwGUI.theProject.tree["0000000000011"].itemRoot == "0000000000008"
|
assert theProject.tree["0000000000011"].itemRoot == "0000000000008"
|
||||||
assert nwGUI.theProject.tree["0000000000011"].itemClass == nwItemClass.NOVEL
|
assert theProject.tree["0000000000011"].itemClass == nwItemClass.NOVEL
|
||||||
|
|
||||||
# Add a new file in the new folder
|
# Add a new file in the new folder
|
||||||
nwTree.setSelectedHandle("0000000000011")
|
projView.setSelectedHandle("0000000000011")
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FILE) is True
|
assert projView.projTree.newTreeItem(nwItemType.FILE) is True
|
||||||
assert nwGUI.theProject.tree["0000000000012"].itemParent == "0000000000011"
|
assert theProject.tree["0000000000012"].itemParent == "0000000000011"
|
||||||
assert nwGUI.theProject.tree["0000000000012"].itemRoot == "0000000000008"
|
assert theProject.tree["0000000000012"].itemRoot == "0000000000008"
|
||||||
assert nwGUI.theProject.tree["0000000000012"].itemClass == nwItemClass.NOVEL
|
assert theProject.tree["0000000000012"].itemClass == nwItemClass.NOVEL
|
||||||
|
|
||||||
# Add a new chapter next to the other new file
|
# Add a new chapter next to the other new file
|
||||||
nwTree.setSelectedHandle("0000000000012")
|
projView.setSelectedHandle("0000000000012")
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FILE, hLevel=2) is True
|
assert projView.projTree.newTreeItem(nwItemType.FILE, hLevel=2) is True
|
||||||
assert nwGUI.theProject.tree["0000000000013"].itemParent == "0000000000011"
|
assert theProject.tree["0000000000013"].itemParent == "0000000000011"
|
||||||
assert nwGUI.theProject.tree["0000000000013"].itemRoot == "0000000000008"
|
assert theProject.tree["0000000000013"].itemRoot == "0000000000008"
|
||||||
assert nwGUI.theProject.tree["0000000000013"].itemClass == nwItemClass.NOVEL
|
assert theProject.tree["0000000000013"].itemClass == nwItemClass.NOVEL
|
||||||
assert nwGUI.openDocument("0000000000013")
|
assert nwGUI.openDocument("0000000000013")
|
||||||
assert nwGUI.docEditor.getText() == "## New Chapter\n\n"
|
assert nwGUI.docEditor.getText() == "## New Chapter\n\n"
|
||||||
|
|
||||||
# Add a new scene next to the other new file
|
# Add a new scene next to the other new file
|
||||||
nwTree.setSelectedHandle("0000000000012")
|
projView.setSelectedHandle("0000000000012")
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FILE, hLevel=3) is True
|
assert projView.projTree.newTreeItem(nwItemType.FILE, hLevel=3) is True
|
||||||
assert nwGUI.theProject.tree["0000000000014"].itemParent == "0000000000011"
|
assert theProject.tree["0000000000014"].itemParent == "0000000000011"
|
||||||
assert nwGUI.theProject.tree["0000000000014"].itemRoot == "0000000000008"
|
assert theProject.tree["0000000000014"].itemRoot == "0000000000008"
|
||||||
assert nwGUI.theProject.tree["0000000000014"].itemClass == nwItemClass.NOVEL
|
assert theProject.tree["0000000000014"].itemClass == nwItemClass.NOVEL
|
||||||
assert nwGUI.openDocument("0000000000014")
|
assert nwGUI.openDocument("0000000000014")
|
||||||
assert nwGUI.docEditor.getText() == "### New Scene\n\n"
|
assert nwGUI.docEditor.getText() == "### New Scene\n\n"
|
||||||
|
|
||||||
# Add a new file to the characters folder
|
# Add a new file to the characters folder
|
||||||
nwTree.setSelectedHandle("000000000000a")
|
projView.setSelectedHandle("000000000000a")
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FILE, hLevel=1, isNote=True) is True
|
assert projView.projTree.newTreeItem(nwItemType.FILE, hLevel=1, isNote=True) is True
|
||||||
assert nwGUI.theProject.tree["0000000000015"].itemParent == "000000000000a"
|
assert theProject.tree["0000000000015"].itemParent == "000000000000a"
|
||||||
assert nwGUI.theProject.tree["0000000000015"].itemRoot == "000000000000a"
|
assert theProject.tree["0000000000015"].itemRoot == "000000000000a"
|
||||||
assert nwGUI.theProject.tree["0000000000015"].itemClass == nwItemClass.CHARACTER
|
assert theProject.tree["0000000000015"].itemClass == nwItemClass.CHARACTER
|
||||||
assert nwGUI.openDocument("0000000000015")
|
assert nwGUI.openDocument("0000000000015")
|
||||||
assert nwGUI.docEditor.getText() == "# New Note\n\n"
|
assert nwGUI.docEditor.getText() == "# New Note\n\n"
|
||||||
|
|
||||||
# Make sure the sibling folder bug trap works
|
# Make sure the sibling folder bug trap works
|
||||||
nwTree.setSelectedHandle("0000000000013")
|
projView.setSelectedHandle("0000000000013")
|
||||||
nwGUI.theProject.tree["0000000000013"].setParent(None) # This should not happen
|
theProject.tree["0000000000013"].setParent(None) # This should not happen
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FILE) is False
|
assert projView.projTree.newTreeItem(nwItemType.FILE) is False
|
||||||
assert "Internal error" in caplog.text
|
assert "Internal error" in caplog.text
|
||||||
nwGUI.theProject.tree["0000000000013"].setParent("0000000000011")
|
theProject.tree["0000000000013"].setParent("0000000000011")
|
||||||
|
|
||||||
# Cancel during creation
|
# Cancel during creation
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr(GuiEditLabel, "getLabel", lambda *a, **k: ("", False))
|
mp.setattr(GuiEditLabel, "getLabel", lambda *a, **k: ("", False))
|
||||||
nwTree.setSelectedHandle("0000000000013")
|
projView.setSelectedHandle("0000000000013")
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FILE) is False
|
assert projView.projTree.newTreeItem(nwItemType.FILE) is False
|
||||||
|
|
||||||
# Get the trash folder
|
# Get the trash folder
|
||||||
nwTree.projTree._addTrashRoot()
|
projView.projTree._addTrashRoot()
|
||||||
trashHandle = nwGUI.theProject.trashFolder()
|
trashHandle = theProject.trashFolder()
|
||||||
nwTree.setSelectedHandle(trashHandle)
|
projView.setSelectedHandle(trashHandle)
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FILE) is False
|
assert projView.projTree.newTreeItem(nwItemType.FILE) is False
|
||||||
assert "Cannot add new files or folders to the Trash folder" in caplog.text
|
assert "Cannot add new files or folders to the Trash folder" in caplog.text
|
||||||
|
|
||||||
|
# Rename Item
|
||||||
|
# ===========
|
||||||
|
|
||||||
|
# Rename plot folder
|
||||||
|
with monkeypatch.context() as mp:
|
||||||
|
mp.setattr(GuiEditLabel, "getLabel", lambda *a, **k: ("Stuff", True))
|
||||||
|
projTree.renameTreeItem("0000000000009") is True
|
||||||
|
assert theProject.tree["0000000000009"].itemName == "Stuff"
|
||||||
|
|
||||||
|
# Rename invalid folder
|
||||||
|
projTree.renameTreeItem("0000000000000") is False
|
||||||
|
|
||||||
# Other Checks
|
# Other Checks
|
||||||
# ============
|
# ============
|
||||||
|
|
||||||
# Also check error handling in reveal function
|
# Also check error handling in reveal function
|
||||||
assert nwTree.revealNewTreeItem("abc") is False
|
assert projView.revealNewTreeItem("abc") is False
|
||||||
|
|
||||||
# Add an item that cannot be displayed in the tree
|
# Add an item that cannot be displayed in the tree
|
||||||
nHandle = nwGUI.theProject.newFile("Test", None)
|
nHandle = theProject.newFile("Test", None)
|
||||||
assert nwTree.revealNewTreeItem(nHandle) is False
|
assert projView.revealNewTreeItem(nHandle) is False
|
||||||
|
|
||||||
# Clean up
|
# Clean up
|
||||||
# qtbot.stopForInteraction()
|
# qtbot.stop()
|
||||||
nwGUI.closeProject()
|
nwGUI.closeProject()
|
||||||
|
|
||||||
# END Test testGuiProjTree_NewItems
|
# END Test testGuiProjTree_NewItems
|
||||||
@@ -270,8 +284,8 @@ def testGuiProjTree_MoveItems(qtbot, monkeypatch, nwGUI, fncDir, mockRnd):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.gui
|
@pytest.mark.gui
|
||||||
def testGuiProjTree_DeleteItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockRnd):
|
def testGuiProjTree_RequestDeleteItem(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockRnd):
|
||||||
"""Test adding and removing items from the project tree.
|
"""Test external requests for removing items from project tree.
|
||||||
"""
|
"""
|
||||||
# Block message box
|
# Block message box
|
||||||
monkeypatch.setattr(QMessageBox, "warning", lambda *a: QMessageBox.Yes)
|
monkeypatch.setattr(QMessageBox, "warning", lambda *a: QMessageBox.Yes)
|
||||||
@@ -280,181 +294,274 @@ def testGuiProjTree_DeleteItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockR
|
|||||||
monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes)
|
monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes)
|
||||||
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
||||||
|
|
||||||
nwTree = nwGUI.projView
|
nwView = nwGUI.projView
|
||||||
|
|
||||||
# Try to run with no project
|
# Try to run with no project
|
||||||
assert nwTree.emptyTrash() is False
|
assert nwView.requestDeleteItem() is False
|
||||||
assert nwTree.deleteItem() is False
|
|
||||||
|
|
||||||
# Create a project
|
# Create a project
|
||||||
prjDir = os.path.join(fncDir, "project")
|
prjDir = os.path.join(fncDir, "project")
|
||||||
buildTestProject(nwGUI, prjDir)
|
buildTestProject(nwGUI, prjDir)
|
||||||
|
|
||||||
# Try emptying the trash already now, when there is no trash folder
|
# Try emptying the trash already now, when there is no trash folder
|
||||||
assert nwTree.emptyTrash() is False
|
assert nwView.emptyTrash() is False
|
||||||
|
|
||||||
# Add some files
|
# Add some files
|
||||||
nwTree.setSelectedHandle("000000000000d")
|
nwView.setSelectedHandle("000000000000d")
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FILE) is True
|
assert nwView.projTree.newTreeItem(nwItemType.FILE) is True
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FILE) is True
|
assert nwView.projTree.newTreeItem(nwItemType.FILE) is True
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FILE) is True
|
assert nwView.projTree.newTreeItem(nwItemType.FILE) is True
|
||||||
assert nwTree.getTreeFromHandle("000000000000d") == [
|
assert nwView.getTreeFromHandle("000000000000d") == [
|
||||||
"000000000000d", "000000000000e", "000000000000f",
|
"000000000000d", "000000000000e", "000000000000f",
|
||||||
"0000000000010", "0000000000011", "0000000000012",
|
"0000000000010", "0000000000011", "0000000000012",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Delete item without focus -> blocked
|
# Delete item without focus -> blocked
|
||||||
monkeypatch.setattr(GuiProjectTree, "hasFocus", lambda *a: False)
|
monkeypatch.setattr(GuiProjectTree, "hasFocus", lambda *a: False)
|
||||||
nwTree.setSelectedHandle("0000000000012")
|
nwView.setSelectedHandle("0000000000012")
|
||||||
assert nwTree.deleteItem() is False
|
assert nwView.requestDeleteItem() is False
|
||||||
monkeypatch.setattr(GuiProjectTree, "hasFocus", lambda *a: True)
|
monkeypatch.setattr(GuiProjectTree, "hasFocus", lambda *a: True)
|
||||||
|
|
||||||
# No selection made
|
# No selection made
|
||||||
nwTree.projTree.clearSelection()
|
nwView.projTree.clearSelection()
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
assert nwTree.deleteItem() is False
|
assert nwView.requestDeleteItem() is False
|
||||||
assert "no item to delete" in caplog.text
|
assert "no item to delete" in caplog.text
|
||||||
|
|
||||||
# Not a valid handle
|
# Not a valid handle
|
||||||
nwTree.projTree.clearSelection()
|
nwView.projTree.clearSelection()
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
assert nwTree.deleteItem("0000000000000") is False
|
assert nwView.requestDeleteItem("0000000000000") is False
|
||||||
assert "Could not find tree item" in caplog.text
|
assert "No tree item with handle '0000000000000'" in caplog.text
|
||||||
|
|
||||||
# Delete Folder/Root
|
# Delete Root Folders
|
||||||
# ==================
|
# ===================
|
||||||
|
|
||||||
# Deleting non-empty folders is blocked
|
assert nwView.requestDeleteItem("0000000000008") is False # Novel Root is blocked
|
||||||
assert nwTree.deleteItem("0000000000008") is False # Novel Root
|
assert nwView.requestDeleteItem("000000000000a") is True # Character Root
|
||||||
assert nwTree.deleteItem("000000000000a") is True # Character Root
|
|
||||||
|
|
||||||
# Delete File
|
# Delete File
|
||||||
# ===========
|
# ===========
|
||||||
|
|
||||||
# Block adding trash folder
|
# Block adding trash folder
|
||||||
funcPointer = nwTree.projTree._addTrashRoot
|
funcPointer = nwView.projTree._addTrashRoot
|
||||||
nwTree.projTree._addTrashRoot = lambda *a: None
|
nwView.projTree._addTrashRoot = lambda *a: None
|
||||||
assert nwTree.deleteItem("0000000000012") is False
|
assert nwView.requestDeleteItem("0000000000012") is False
|
||||||
nwTree.projTree._addTrashRoot = funcPointer
|
nwView.projTree._addTrashRoot = funcPointer
|
||||||
|
|
||||||
# Delete last two documents, which also adds the trash folder
|
# Delete last two documents, which also adds the trash folder
|
||||||
assert nwTree.deleteItem("0000000000012") is True
|
assert nwView.requestDeleteItem("0000000000012") is True
|
||||||
assert nwTree.deleteItem("0000000000011") is True
|
assert nwView.requestDeleteItem("0000000000011") is True
|
||||||
assert nwTree.getTreeFromHandle("000000000000d") == [
|
assert nwView.getTreeFromHandle("000000000000d") == [
|
||||||
"000000000000d", "000000000000e", "000000000000f",
|
"000000000000d", "000000000000e", "000000000000f",
|
||||||
"0000000000010"
|
"0000000000010"
|
||||||
]
|
]
|
||||||
trashHandle = nwGUI.theProject.tree.trashRoot()
|
trashHandle = nwGUI.theProject.tree.trashRoot()
|
||||||
assert nwTree.getTreeFromHandle(trashHandle) == [
|
assert nwView.getTreeFromHandle(trashHandle) == [
|
||||||
trashHandle, "0000000000012", "0000000000011"
|
trashHandle, "0000000000012", "0000000000011"
|
||||||
]
|
]
|
||||||
|
|
||||||
# Delete the first file again (permanent), and ask for permission
|
# Try to delete the trash folder
|
||||||
# Also open the document in the editor, which should trigger a close
|
caplog.clear()
|
||||||
assert os.path.isfile(os.path.join(prjDir, "content", "0000000000012.nwd"))
|
assert nwView.requestDeleteItem("0000000000013") is False
|
||||||
assert "0000000000012" in nwGUI.theProject.tree
|
assert "Cannot delete the Trash folder" in caplog.text
|
||||||
assert nwGUI.docEditor.docHandle() is None
|
|
||||||
assert nwGUI.openDocument("0000000000012") is True
|
|
||||||
assert nwGUI.docEditor.docHandle() == "0000000000012"
|
|
||||||
assert nwTree.deleteItem("0000000000012") is True
|
|
||||||
assert nwGUI.docEditor.docHandle() is None
|
|
||||||
assert not os.path.isfile(os.path.join(prjDir, "content", "0000000000012.nwd"))
|
|
||||||
assert "0000000000012" not in nwGUI.theProject.tree
|
|
||||||
assert nwTree.getTreeFromHandle(trashHandle) == [
|
|
||||||
trashHandle, "0000000000011"
|
|
||||||
]
|
|
||||||
|
|
||||||
# Delete the second file, and skip asking for permission
|
|
||||||
assert os.path.isfile(os.path.join(prjDir, "content", "0000000000011.nwd"))
|
|
||||||
assert "0000000000011" in nwGUI.theProject.tree
|
|
||||||
assert nwTree.deleteItem("0000000000011", alreadyAsked=True) is True
|
|
||||||
assert not os.path.isfile(os.path.join(prjDir, "content", "0000000000011.nwd"))
|
|
||||||
assert "0000000000011" not in nwGUI.theProject.tree
|
|
||||||
assert nwTree.getTreeFromHandle(trashHandle) == [trashHandle]
|
|
||||||
|
|
||||||
# Delete Folder
|
|
||||||
# =============
|
|
||||||
|
|
||||||
trashHandle = nwGUI.theProject.tree.trashRoot()
|
|
||||||
|
|
||||||
# Add a folder with two files
|
|
||||||
nwTree.setSelectedHandle("0000000000009")
|
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FOLDER) is True
|
|
||||||
nwTree.setSelectedHandle("0000000000014")
|
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FILE) is True
|
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FILE) is True
|
|
||||||
assert os.path.isfile(os.path.join(fncDir, "project", "content", "0000000000015.nwd"))
|
|
||||||
assert os.path.isfile(os.path.join(fncDir, "project", "content", "0000000000016.nwd"))
|
|
||||||
|
|
||||||
# Delete the folder, which moves everything to Trash
|
|
||||||
assert nwTree.getTreeFromHandle("0000000000014") == [
|
|
||||||
"0000000000014", "0000000000015", "0000000000016"
|
|
||||||
]
|
|
||||||
assert nwTree.deleteItem("0000000000014") is True
|
|
||||||
assert nwTree.getTreeFromHandle(trashHandle) == [
|
|
||||||
trashHandle, "0000000000014", "0000000000015", "0000000000016"
|
|
||||||
]
|
|
||||||
assert os.path.isfile(os.path.join(fncDir, "project", "content", "0000000000015.nwd"))
|
|
||||||
assert os.path.isfile(os.path.join(fncDir, "project", "content", "0000000000016.nwd"))
|
|
||||||
|
|
||||||
# Delete again, which should delete folder and all files
|
|
||||||
assert nwTree.deleteItem("0000000000014") is True
|
|
||||||
assert nwTree.getTreeFromHandle(trashHandle) == [trashHandle]
|
|
||||||
assert not os.path.isfile(os.path.join(fncDir, "project", "content", "0000000000015.nwd"))
|
|
||||||
assert not os.path.isfile(os.path.join(fncDir, "project", "content", "0000000000016.nwd"))
|
|
||||||
|
|
||||||
# Add an empty folder, which can be deleted with no further restrictions
|
|
||||||
nwTree.setSelectedHandle("0000000000009")
|
|
||||||
assert nwTree.projTree.newTreeItem(nwItemType.FOLDER) is True
|
|
||||||
assert nwTree.getTreeFromHandle("0000000000009") == ["0000000000009", "0000000000017"]
|
|
||||||
|
|
||||||
nwTree.setSelectedHandle("0000000000017")
|
|
||||||
assert nwTree.deleteItem("0000000000017") is True
|
|
||||||
assert nwTree.getTreeFromHandle("0000000000009") == ["0000000000009"]
|
|
||||||
|
|
||||||
# Empty Trash
|
|
||||||
# ===========
|
|
||||||
|
|
||||||
# Try to empty trash that is already empty
|
|
||||||
assert nwTree.getTreeFromHandle(trashHandle) == [trashHandle]
|
|
||||||
assert nwTree.emptyTrash() is False
|
|
||||||
|
|
||||||
# Move the two remaining scene documents to trash
|
|
||||||
assert nwTree.deleteItem("000000000000f") is True
|
|
||||||
assert nwTree.deleteItem("0000000000010") is True
|
|
||||||
assert nwTree.getTreeFromHandle("000000000000d") == [
|
|
||||||
"000000000000d", "000000000000e"
|
|
||||||
]
|
|
||||||
assert nwTree.getTreeFromHandle(trashHandle) == [
|
|
||||||
trashHandle, "000000000000f", "0000000000010"
|
|
||||||
]
|
|
||||||
|
|
||||||
# Empty trash, but select no on question
|
|
||||||
with monkeypatch.context() as mp:
|
|
||||||
mp.setattr(QMessageBox, "question", lambda *a: QMessageBox.No)
|
|
||||||
assert nwTree.emptyTrash() is False
|
|
||||||
|
|
||||||
# Empty the trash proper
|
|
||||||
assert nwTree.emptyTrash() is True
|
|
||||||
assert nwTree.getTreeFromHandle(trashHandle) == [trashHandle]
|
|
||||||
|
|
||||||
# Try to delete a file, but block the underlying deletion of the file on disk
|
|
||||||
assert os.path.isfile(os.path.join(fncDir, "project", "content", "000000000000e.nwd"))
|
|
||||||
with monkeypatch.context() as mp:
|
|
||||||
mp.setattr("novelwriter.core.document.NWDoc.deleteDocument", lambda *a: False)
|
|
||||||
assert nwTree.deleteItem("000000000000e") is True
|
|
||||||
assert nwTree.deleteItem("000000000000e") is True
|
|
||||||
assert os.path.isfile(os.path.join(fncDir, "project", "content", "000000000000e.nwd"))
|
|
||||||
|
|
||||||
# Delete proper
|
|
||||||
assert nwTree.projTree._deleteTreeItem("000000000000e") is True
|
|
||||||
assert not os.path.isfile(os.path.join(fncDir, "project", "content", "000000000000e.nwd"))
|
|
||||||
|
|
||||||
# Clean up
|
|
||||||
# qtbot.stopForInteraction()
|
|
||||||
nwGUI.closeProject()
|
nwGUI.closeProject()
|
||||||
|
|
||||||
# END Test testGuiProjTree_DeleteItems
|
# END Test testGuiProjTree_RequestDeleteItem
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.gui
|
||||||
|
def testGuiProjTree_MoveItemToTrash(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockRnd):
|
||||||
|
"""Test moving items to Trash.
|
||||||
|
"""
|
||||||
|
# Block message box
|
||||||
|
monkeypatch.setattr(QMessageBox, "warning", lambda *a: QMessageBox.Yes)
|
||||||
|
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
|
||||||
|
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||||
|
monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes)
|
||||||
|
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
||||||
|
|
||||||
|
theProject = nwGUI.theProject
|
||||||
|
projTree = nwGUI.projView.projTree
|
||||||
|
|
||||||
|
# Create a project
|
||||||
|
prjDir = os.path.join(fncDir, "project")
|
||||||
|
buildTestProject(nwGUI, prjDir)
|
||||||
|
|
||||||
|
hInvalid = "0000000000000"
|
||||||
|
hNovelRoot = "0000000000008"
|
||||||
|
hTitlePage = "000000000000c"
|
||||||
|
|
||||||
|
# Invalid item
|
||||||
|
caplog.clear()
|
||||||
|
assert projTree.moveItemToTrash(hInvalid) is False
|
||||||
|
assert "Could not find tree item for deletion" in caplog.text
|
||||||
|
|
||||||
|
# Root folders cannot be moved to Trash
|
||||||
|
caplog.clear()
|
||||||
|
assert projTree.moveItemToTrash(hNovelRoot) is False
|
||||||
|
assert "Root folders cannot be moved to Trash" in caplog.text
|
||||||
|
|
||||||
|
# Block adding trash folder
|
||||||
|
funcPointer = projTree._addTrashRoot
|
||||||
|
projTree._addTrashRoot = lambda *a: None
|
||||||
|
|
||||||
|
caplog.clear()
|
||||||
|
assert projTree.moveItemToTrash(hTitlePage) is False
|
||||||
|
assert theProject.tree.isTrash(hTitlePage) is False
|
||||||
|
assert "Could not delete item" in caplog.text
|
||||||
|
|
||||||
|
projTree._addTrashRoot = funcPointer
|
||||||
|
|
||||||
|
# User cancels action
|
||||||
|
with monkeypatch.context() as mp:
|
||||||
|
mp.setattr(QMessageBox, "question", lambda *a: QMessageBox.No)
|
||||||
|
assert projTree.moveItemToTrash(hTitlePage) is False
|
||||||
|
assert theProject.tree.isTrash(hTitlePage) is False
|
||||||
|
|
||||||
|
# Move a document to Trash
|
||||||
|
assert projTree.moveItemToTrash(hTitlePage) is True
|
||||||
|
assert theProject.tree.isTrash(hTitlePage) is True
|
||||||
|
|
||||||
|
# Cannot be moved again
|
||||||
|
caplog.clear()
|
||||||
|
assert projTree.moveItemToTrash(hTitlePage) is False
|
||||||
|
assert "Item is already in the Trash folder" in caplog.text
|
||||||
|
|
||||||
|
nwGUI.closeProject()
|
||||||
|
|
||||||
|
# END Test testGuiProjTree_MoveItemToTrash
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.gui
|
||||||
|
def testGuiProjTree_PermanentlyDeleteItem(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockRnd):
|
||||||
|
"""Test permanently deleting items.
|
||||||
|
"""
|
||||||
|
# Block message box
|
||||||
|
monkeypatch.setattr(QMessageBox, "warning", lambda *a: QMessageBox.Yes)
|
||||||
|
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
|
||||||
|
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||||
|
monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes)
|
||||||
|
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
||||||
|
|
||||||
|
theProject = nwGUI.theProject
|
||||||
|
projTree = nwGUI.projView.projTree
|
||||||
|
|
||||||
|
# Create a project
|
||||||
|
prjDir = os.path.join(fncDir, "project")
|
||||||
|
buildTestProject(nwGUI, prjDir)
|
||||||
|
|
||||||
|
hInvalid = "0000000000000"
|
||||||
|
hNovelRoot = "0000000000008"
|
||||||
|
hPlotRoot = "0000000000009"
|
||||||
|
hTitlePage = "000000000000c"
|
||||||
|
hChapterDir = "000000000000d"
|
||||||
|
hChapterDoc = "000000000000e"
|
||||||
|
hSceneDoc = "000000000000f"
|
||||||
|
|
||||||
|
# Invalid item
|
||||||
|
caplog.clear()
|
||||||
|
assert projTree.permanentlyDeleteItem(hInvalid) is False
|
||||||
|
assert "Could not find tree item for deletion" in caplog.text
|
||||||
|
|
||||||
|
# Not deleting root item in use
|
||||||
|
caplog.clear()
|
||||||
|
assert projTree.permanentlyDeleteItem(hNovelRoot) is False
|
||||||
|
assert "Root folders can only be deleted when they are empty" in caplog.text
|
||||||
|
assert hNovelRoot in theProject.tree
|
||||||
|
|
||||||
|
# Deleting unused root item is allowed
|
||||||
|
caplog.clear()
|
||||||
|
assert projTree.permanentlyDeleteItem(hPlotRoot) is True
|
||||||
|
assert hPlotRoot not in theProject.tree
|
||||||
|
|
||||||
|
# User cancels action
|
||||||
|
with monkeypatch.context() as mp:
|
||||||
|
mp.setattr(QMessageBox, "question", lambda *a: QMessageBox.No)
|
||||||
|
assert projTree.permanentlyDeleteItem(hTitlePage) is False
|
||||||
|
assert hTitlePage in theProject.tree
|
||||||
|
|
||||||
|
# Deleting file is OK, and if it is open, it should close
|
||||||
|
assert nwGUI.openDocument(hTitlePage) is True
|
||||||
|
assert nwGUI.docEditor.docHandle() == hTitlePage
|
||||||
|
assert projTree.permanentlyDeleteItem(hTitlePage) is True
|
||||||
|
assert hTitlePage not in theProject.tree
|
||||||
|
assert nwGUI.docEditor.docHandle() is None
|
||||||
|
|
||||||
|
# Deleting folder + files recursiely is ok
|
||||||
|
assert projTree.permanentlyDeleteItem(hChapterDir) is True
|
||||||
|
assert hChapterDir not in theProject.tree
|
||||||
|
assert hChapterDoc not in theProject.tree
|
||||||
|
assert hSceneDoc not in theProject.tree
|
||||||
|
|
||||||
|
nwGUI.closeProject()
|
||||||
|
|
||||||
|
# END Test testGuiProjTree_PermanentlyDeleteItem
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.gui
|
||||||
|
def testGuiProjTree_EmptyTrash(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockRnd):
|
||||||
|
"""Test emptying Trash.
|
||||||
|
"""
|
||||||
|
# Block message box
|
||||||
|
monkeypatch.setattr(QMessageBox, "warning", lambda *a: QMessageBox.Yes)
|
||||||
|
monkeypatch.setattr(QMessageBox, "critical", lambda *a: QMessageBox.Yes)
|
||||||
|
monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes)
|
||||||
|
monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Yes)
|
||||||
|
monkeypatch.setattr(GuiEditLabel, "getLabel", lambda *a, text: (text, True))
|
||||||
|
|
||||||
|
theProject = nwGUI.theProject
|
||||||
|
projTree = nwGUI.projView.projTree
|
||||||
|
|
||||||
|
# No project open
|
||||||
|
caplog.clear()
|
||||||
|
assert projTree.emptyTrash() is False
|
||||||
|
assert "No project open" in caplog.text
|
||||||
|
|
||||||
|
# Create a project
|
||||||
|
prjDir = os.path.join(fncDir, "project")
|
||||||
|
buildTestProject(nwGUI, prjDir)
|
||||||
|
|
||||||
|
hTitlePage = "000000000000c"
|
||||||
|
hChapterDir = "000000000000d"
|
||||||
|
hChapterDoc = "000000000000e"
|
||||||
|
hSceneDoc = "000000000000f"
|
||||||
|
|
||||||
|
# No Trash folder
|
||||||
|
assert projTree.emptyTrash() is False
|
||||||
|
|
||||||
|
# Move some documents to Trash
|
||||||
|
assert projTree.moveItemToTrash(hTitlePage) is True
|
||||||
|
assert projTree.moveItemToTrash(hChapterDir) is True
|
||||||
|
|
||||||
|
assert theProject.tree.isTrash(hTitlePage) is True
|
||||||
|
assert theProject.tree.isTrash(hChapterDir) is True
|
||||||
|
assert theProject.tree.isTrash(hChapterDoc) is True
|
||||||
|
assert theProject.tree.isTrash(hSceneDoc) is True
|
||||||
|
|
||||||
|
# User cancels
|
||||||
|
with monkeypatch.context() as mp:
|
||||||
|
mp.setattr(QMessageBox, "question", lambda *a: QMessageBox.No)
|
||||||
|
assert projTree.emptyTrash() is False
|
||||||
|
assert hTitlePage in theProject.tree
|
||||||
|
assert hChapterDir in theProject.tree
|
||||||
|
assert hChapterDoc in theProject.tree
|
||||||
|
assert hSceneDoc in theProject.tree
|
||||||
|
|
||||||
|
# Run again to empty all items
|
||||||
|
assert projTree.emptyTrash() is True
|
||||||
|
assert hTitlePage not in theProject.tree
|
||||||
|
assert hChapterDir not in theProject.tree
|
||||||
|
assert hChapterDoc not in theProject.tree
|
||||||
|
assert hSceneDoc not in theProject.tree
|
||||||
|
|
||||||
|
# Running Emtpy Trash again is cancelled due to empty folder
|
||||||
|
assert projTree.emptyTrash() is False
|
||||||
|
|
||||||
|
nwGUI.closeProject()
|
||||||
|
|
||||||
|
# END Test testGuiProjTree_EmptyTrash
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.gui
|
@pytest.mark.gui
|
||||||
|
|||||||
Reference in New Issue
Block a user