diff --git a/README.asciidoc b/README.asciidoc index fe93da6df..8fc09e84e 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -165,6 +165,7 @@ Contributors, sorted by the number of commits in descending order: * Thorsten Wißmann * Austin Anderson * Alexey "Averrin" Nabrodov +* avk * ZDarian * Milan Svoboda * John ShaggyTwoDope Jenkins @@ -192,7 +193,6 @@ Contributors, sorted by the number of commits in descending order: * Link * Larry Hynes * Johannes Altmanninger -* avk * Samir Benmendil * Regina Hug * Mathias Fussenegger diff --git a/qutebrowser/browser/network/pastebin.py b/qutebrowser/browser/network/pastebin.py index 84976e9a0..977fffe4a 100644 --- a/qutebrowser/browser/network/pastebin.py +++ b/qutebrowser/browser/network/pastebin.py @@ -23,8 +23,6 @@ import urllib.parse from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl -from qutebrowser.misc import httpclient - class PastebinClient(QObject): @@ -47,11 +45,17 @@ class PastebinClient(QObject): success = pyqtSignal(str) error = pyqtSignal(str) - def __init__(self, parent=None): + def __init__(self, client, parent=None): + """Constructor. + + Args: + client: The HTTPClient to use. Will be reparented. + """ super().__init__(parent) - self._client = httpclient.HTTPClient(self) - self._client.error.connect(self.error) - self._client.success.connect(self.on_client_success) + client.setParent(self) + client.error.connect(self.error) + client.success.connect(self.on_client_success) + self._client = client def paste(self, name, title, text, parent=None): """Paste the text into a pastebin and return the URL. diff --git a/qutebrowser/misc/crashdialog.py b/qutebrowser/misc/crashdialog.py index ed4e47519..3c4ab03d4 100644 --- a/qutebrowser/misc/crashdialog.py +++ b/qutebrowser/misc/crashdialog.py @@ -36,7 +36,7 @@ from PyQt5.QtWidgets import (QDialog, QLabel, QTextEdit, QPushButton, import qutebrowser from qutebrowser.utils import version, log, utils, objreg, qtutils -from qutebrowser.misc import miscwidgets, autoupdate, msgbox +from qutebrowser.misc import miscwidgets, autoupdate, msgbox, httpclient from qutebrowser.browser.network import pastebin from qutebrowser.config import config @@ -141,7 +141,8 @@ class _CrashDialog(QDialog): self.setWindowTitle("Whoops!") self.resize(QSize(640, 600)) self._vbox = QVBoxLayout(self) - self._paste_client = pastebin.PastebinClient(self) + http_client = httpclient.HTTPClient() + self._paste_client = pastebin.PastebinClient(http_client, self) self._pypi_client = autoupdate.PyPIVersionClient(self) self._init_text() diff --git a/scripts/dev/check_coverage.py b/scripts/dev/check_coverage.py index ae75a3d4d..40f7ebc4a 100644 --- a/scripts/dev/check_coverage.py +++ b/scripts/dev/check_coverage.py @@ -65,6 +65,8 @@ PERFECT_FILES = [ 'qutebrowser/browser/network/filescheme.py'), ('tests/unit/browser/network/test_networkreply.py', 'qutebrowser/browser/network/networkreply.py'), + ('tests/unit/browser/network/test_pastebin.py', + 'qutebrowser/browser/network/pastebin.py'), ('tests/unit/browser/test_signalfilter.py', 'qutebrowser/browser/signalfilter.py'), diff --git a/tests/unit/browser/network/test_pastebin.py b/tests/unit/browser/network/test_pastebin.py new file mode 100644 index 000000000..56f988e94 --- /dev/null +++ b/tests/unit/browser/network/test_pastebin.py @@ -0,0 +1,125 @@ +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2016 Anna Kobak (avk) : +# +# This file is part of qutebrowser. +# +# qutebrowser 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. +# +# qutebrowser 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 qutebrowser. If not, see . + +import pytest +from PyQt5.QtCore import pyqtSignal, QUrl, QObject + +from qutebrowser.browser.network import pastebin +from qutebrowser.misc import httpclient + + +class HTTPPostStub(QObject): + + """A stub class for HTTPClient. + + Attributes: + url: the last url send by post() + data: the last data send by post() + """ + + success = pyqtSignal(str) + error = pyqtSignal(str) + + def __init__(self, parent=None): + super().__init__(parent) + self.url = None + self.data = None + + def post(self, url, data=None): + self.url = url + self.data = data + + +@pytest.fixture +def pbclient(): + http_stub = HTTPPostStub() + client = pastebin.PastebinClient(http_stub) + return client + + +def test_constructor(qapp): + http_client = httpclient.HTTPClient() + pbclient = pastebin.PastebinClient(http_client) + + +@pytest.mark.parametrize('data', [ + { + "name": "XYZ", + "title": "hello world", + "text": "xyz. 123 \n 172ANB", + "reply": "abc" + }, + { + "name": "the name", + "title": "the title", + "text": "some Text", + "reply": "some parent" + } +]) +def test_paste_with_parent(data, pbclient): + http_stub = pbclient._client + pbclient.paste(data["name"], data["title"], data["text"], data["reply"]) + assert http_stub.data == data + assert http_stub.url == QUrl('http://paste.the-compiler.org/api/create') + + +@pytest.mark.parametrize('data', [ + { + "name": "XYZ", + "title": "hello world", + "text": "xyz. 123 \n 172ANB" + }, + { + "name": "the name", + "title": "the title", + "text": "some Text" + } +]) +def test_paste_without_parent(data, pbclient): + http_stub = pbclient._client + pbclient.paste(data["name"], data["title"], data["text"]) + assert pbclient._client.data == data + assert http_stub.url == QUrl('http://paste.the-compiler.org/api/create') + + +@pytest.mark.parametrize('http', [ + "http://paste.the-compiler.org/view/ges83nt3", + "http://paste.the-compiler.org/view/3gjnwg4" +]) +def test_on_client_success(http, pbclient, qtbot): + with qtbot.assertNotEmitted(pbclient.error): + with qtbot.waitSignal(pbclient.success): + pbclient._client.success.emit(http) + + +@pytest.mark.parametrize('http', [ + "http invalid", + "http:/invalid.org" + "http//invalid.com" +]) +def test_client_success_invalid_http(http, pbclient, qtbot): + with qtbot.assertNotEmitted(pbclient.success): + with qtbot.waitSignal(pbclient.error): + pbclient._client.success.emit(http) + + +def test_client_error(pbclient, qtbot): + with qtbot.assertNotEmitted(pbclient.success): + with qtbot.waitSignal(pbclient.error): + pbclient._client.error.emit("msg")