From ed7dde2aaa3084e24a9d45dffe4060909944859c Mon Sep 17 00:00:00 2001
From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com>
Date: Wed, 14 Feb 2024 23:19:25 +0100
Subject: [PATCH] Add test coverage
---
novelwriter/extensions/versioninfo.py | 1 -
tests/test_ext/test_ext_modified.py | 4 +-
tests/test_ext/test_ext_versioninfo.py | 155 +++++++++++++++++++++++++
3 files changed, 157 insertions(+), 3 deletions(-)
create mode 100644 tests/test_ext/test_ext_versioninfo.py
diff --git a/novelwriter/extensions/versioninfo.py b/novelwriter/extensions/versioninfo.py
index 02fb86e4..08cbc74e 100644
--- a/novelwriter/extensions/versioninfo.py
+++ b/novelwriter/extensions/versioninfo.py
@@ -118,7 +118,6 @@ class _Retriever(QRunnable):
def __init__(self) -> None:
super().__init__()
- self._isRunning = False
self.signals = _RetrieverSignal()
return
diff --git a/tests/test_ext/test_ext_modified.py b/tests/test_ext/test_ext_modified.py
index c1d0e3c2..7ea40755 100644
--- a/tests/test_ext/test_ext_modified.py
+++ b/tests/test_ext/test_ext_modified.py
@@ -1,6 +1,6 @@
"""
-novelWriter – Wheel Event Filter Tester
-=======================================
+novelWriter – Modified Widgets Tester
+=====================================
This file is a part of novelWriter
Copyright 2018–2024, Veronica Berglyd Olsen
diff --git a/tests/test_ext/test_ext_versioninfo.py b/tests/test_ext/test_ext_versioninfo.py
new file mode 100644
index 00000000..b30fb19c
--- /dev/null
+++ b/tests/test_ext/test_ext_versioninfo.py
@@ -0,0 +1,155 @@
+"""
+novelWriter – Version Info Widget Tester
+========================================
+
+This file is a part of novelWriter
+Copyright 2018–2024, Veronica Berglyd Olsen
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+"""
+from __future__ import annotations
+
+import pytest
+
+from urllib.error import HTTPError
+
+from tools import SimpleDialog
+
+from PyQt5.QtCore import QUrl
+
+from novelwriter import SHARED
+from novelwriter.constants import nwConst
+from novelwriter.extensions.versioninfo import VersionInfoWidget, _Retriever, _RetrieverSignal
+
+
+class MockRetriever:
+ signals = _RetrieverSignal()
+
+
+class MockDesktopServices:
+
+ url = None
+
+ @staticmethod
+ def openUrl(url):
+ MockDesktopServices.url = url
+ return
+
+
+class MockData:
+ pass
+
+
+class MockPayload:
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, *args):
+ return
+
+ def read(self):
+ data = MockData()
+ data.decode = lambda *a: '{"tag_name": "v1.0"}'
+ return data
+
+
+class MockHTTPError:
+
+ def __enter__(self):
+ raise HTTPError("http://example.com", 403, "Rate limit", None, None)
+
+ def __exit__(self, *args):
+ return
+
+
+class MockException:
+
+ def __enter__(self):
+ raise Exception("Oh noes!")
+
+ def __exit__(self, *args):
+ return
+
+
+@pytest.mark.gui
+def testExtVersionInfo_Main(qtbot, monkeypatch):
+ """Test the VersionInfoWidget class."""
+ version = VersionInfoWidget(None)
+ dialog = SimpleDialog(version)
+ dialog.show()
+
+ with monkeypatch.context() as mp:
+ mp.setattr("novelwriter.extensions.versioninfo.QDesktopServices", MockDesktopServices)
+ version._processLink("#notes")
+ assert MockDesktopServices.url == QUrl(nwConst.URL_RELEASES)
+
+ with monkeypatch.context() as mp:
+ mp.setattr("novelwriter.extensions.versioninfo.QDesktopServices", MockDesktopServices)
+ version._processLink("#website")
+ assert MockDesktopServices.url == QUrl(nwConst.URL_WEB)
+
+ with monkeypatch.context() as mp:
+ mp.setattr("novelwriter.extensions.versioninfo._Retriever", MockRetriever)
+ mp.setattr(SHARED, "runInThreadPool", lambda *a: None)
+ version._processLink("#update")
+ assert version._lblRelease.text() == "Latest Version: Checking ..."
+
+ version._updateReleaseInfo("v2.0", "")
+ assert version._lblRelease.text() == (
+ "Latest Version: 2.0 – Download from novelwriter.io"
+ )
+
+ version._updateReleaseInfo("", "Error")
+ assert version._lblRelease.text() == "Latest Version: Error"
+
+ version._updateReleaseInfo("", "")
+ assert version._lblRelease.text() == "Latest Version: Failed"
+
+ dialog.close()
+ # qtbot.stop()
+
+# END Test testExtVersionInfo_Main
+
+
+@pytest.mark.gui
+def testExtVersionInfo_Retriever(qtbot, monkeypatch):
+ """Test the _Retriever class."""
+ task = _Retriever()
+
+ # Valid Data
+ with monkeypatch.context() as mp:
+ mp.setattr("novelwriter.extensions.versioninfo.urlopen", lambda *a, **k: MockPayload())
+ with qtbot.waitSignal(task.signals.dataReady) as signal:
+ task.run()
+ assert signal.args == ["v1.0", ""]
+
+ def httpErr():
+ raise HTTPError("http://example.com", 403, "Rate limit")
+
+ # HTTP Error
+ with monkeypatch.context() as mp:
+ mp.setattr("novelwriter.extensions.versioninfo.urlopen", lambda *a, **k: MockHTTPError())
+ with qtbot.waitSignal(task.signals.dataReady) as signal:
+ task.run()
+ assert signal.args == ["", "Rate limit (HTTP 403)"]
+
+ # Other Error
+ with monkeypatch.context() as mp:
+ mp.setattr("novelwriter.extensions.versioninfo.urlopen", lambda *a, **k: MockException())
+ with qtbot.waitSignal(task.signals.dataReady) as signal:
+ task.run()
+ assert signal.args == ["", "Oh noes!"]
+
+# END Test testExtVersionInfo_Retriever