2016-06-09 13:15:52 +02:00
|
|
|
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
|
|
|
|
|
2017-05-09 21:37:03 +02:00
|
|
|
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
2016-06-09 13:15:52 +02:00
|
|
|
#
|
|
|
|
# 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
"""Tests for the global page history."""
|
|
|
|
|
2016-06-10 12:00:57 +02:00
|
|
|
import logging
|
2016-06-09 21:13:25 +02:00
|
|
|
|
2016-06-09 13:15:52 +02:00
|
|
|
import pytest
|
|
|
|
from PyQt5.QtCore import QUrl
|
|
|
|
|
2016-08-10 14:45:52 +02:00
|
|
|
from qutebrowser.browser import history
|
2017-02-06 01:34:14 +01:00
|
|
|
from qutebrowser.utils import objreg, urlutils, usertypes
|
2016-06-09 13:15:52 +02:00
|
|
|
|
|
|
|
|
2017-01-16 03:42:35 +01:00
|
|
|
@pytest.fixture(autouse=True)
|
2017-02-12 14:39:24 +01:00
|
|
|
def prerequisites(config_stub, fake_save_manager, init_sql):
|
2017-01-16 03:42:35 +01:00
|
|
|
"""Make sure everything is ready to initialize a WebHistory."""
|
|
|
|
config_stub.data = {'general': {'private-browsing': False}}
|
2016-06-09 21:13:25 +02:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture()
|
2017-01-16 03:42:35 +01:00
|
|
|
def hist(tmpdir):
|
2017-03-26 22:52:10 +02:00
|
|
|
return history.WebHistory()
|
2016-06-09 13:15:52 +02:00
|
|
|
|
|
|
|
|
2017-03-26 22:52:10 +02:00
|
|
|
@pytest.fixture()
|
|
|
|
def mock_time(mocker):
|
|
|
|
m = mocker.patch('qutebrowser.browser.history.time')
|
|
|
|
m.time.return_value = 12345
|
|
|
|
return 12345
|
2016-06-09 13:15:52 +02:00
|
|
|
|
|
|
|
|
2016-06-10 12:00:57 +02:00
|
|
|
def test_iter(hist):
|
2017-01-16 03:42:35 +01:00
|
|
|
urlstr = 'http://www.example.com/'
|
|
|
|
url = QUrl(urlstr)
|
2016-06-10 12:12:29 +02:00
|
|
|
hist.add_url(url, atime=12345)
|
|
|
|
|
2017-01-16 03:42:35 +01:00
|
|
|
assert list(hist) == [(urlstr, '', 12345, False)]
|
2016-06-10 12:00:57 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_len(hist):
|
|
|
|
assert len(hist) == 0
|
2016-06-10 12:12:29 +02:00
|
|
|
|
2016-06-10 12:00:57 +02:00
|
|
|
url = QUrl('http://www.example.com/')
|
|
|
|
hist.add_url(url)
|
2016-06-10 12:12:29 +02:00
|
|
|
|
2016-06-10 12:00:57 +02:00
|
|
|
assert len(hist) == 1
|
|
|
|
|
|
|
|
|
2017-04-08 23:18:20 +02:00
|
|
|
def test_contains(hist):
|
|
|
|
hist.add_url(QUrl('http://www.example.com/'), title='Title', atime=12345)
|
|
|
|
assert 'http://www.example.com/' in hist
|
2017-04-09 13:02:14 +02:00
|
|
|
assert 'www.example.com' not in hist
|
|
|
|
assert 'Title' not in hist
|
|
|
|
assert 12345 not in hist
|
2017-04-08 23:18:20 +02:00
|
|
|
|
|
|
|
|
2017-03-26 22:52:10 +02:00
|
|
|
def test_get_recent(hist):
|
2016-06-10 12:12:29 +02:00
|
|
|
hist.add_url(QUrl('http://www.qutebrowser.org/'), atime=67890)
|
2017-03-26 22:52:10 +02:00
|
|
|
hist.add_url(QUrl('http://example.com/'), atime=12345)
|
|
|
|
assert list(hist.get_recent()) == [
|
2017-04-06 18:02:43 +02:00
|
|
|
('http://www.qutebrowser.org/', '', 67890, False),
|
2017-03-26 22:52:10 +02:00
|
|
|
('http://example.com/', '', 12345, False),
|
|
|
|
]
|
2016-06-10 12:00:57 +02:00
|
|
|
|
|
|
|
|
2017-05-08 04:21:46 +02:00
|
|
|
def test_entries_between(hist):
|
|
|
|
hist.add_url(QUrl('http://www.example.com/1'), atime=12345)
|
|
|
|
hist.add_url(QUrl('http://www.example.com/2'), atime=12346)
|
|
|
|
hist.add_url(QUrl('http://www.example.com/3'), atime=12347)
|
|
|
|
hist.add_url(QUrl('http://www.example.com/4'), atime=12348)
|
|
|
|
hist.add_url(QUrl('http://www.example.com/5'), atime=12348)
|
|
|
|
hist.add_url(QUrl('http://www.example.com/6'), atime=12349)
|
|
|
|
hist.add_url(QUrl('http://www.example.com/7'), atime=12350)
|
|
|
|
|
|
|
|
times = [x.atime for x in hist.entries_between(12346, 12349)]
|
|
|
|
assert times == [12349, 12348, 12348, 12347]
|
|
|
|
|
|
|
|
|
|
|
|
def test_entries_before(hist):
|
|
|
|
hist.add_url(QUrl('http://www.example.com/1'), atime=12346)
|
|
|
|
hist.add_url(QUrl('http://www.example.com/2'), atime=12346)
|
|
|
|
hist.add_url(QUrl('http://www.example.com/3'), atime=12347)
|
|
|
|
hist.add_url(QUrl('http://www.example.com/4'), atime=12348)
|
|
|
|
hist.add_url(QUrl('http://www.example.com/5'), atime=12348)
|
|
|
|
hist.add_url(QUrl('http://www.example.com/6'), atime=12348)
|
|
|
|
hist.add_url(QUrl('http://www.example.com/7'), atime=12349)
|
|
|
|
hist.add_url(QUrl('http://www.example.com/8'), atime=12349)
|
|
|
|
|
|
|
|
times = [x.atime for x in hist.entries_before(12348, limit=3, offset=2)]
|
|
|
|
assert times == [12348, 12347, 12346]
|
|
|
|
|
|
|
|
|
2017-03-26 22:52:10 +02:00
|
|
|
def test_save(tmpdir, hist):
|
|
|
|
hist.add_url(QUrl('http://example.com/'), atime=12345)
|
2016-06-10 12:12:29 +02:00
|
|
|
hist.add_url(QUrl('http://www.qutebrowser.org/'), atime=67890)
|
2016-06-10 12:00:57 +02:00
|
|
|
|
2017-03-26 22:52:10 +02:00
|
|
|
hist2 = history.WebHistory()
|
|
|
|
assert list(hist2) == [('http://example.com/', '', 12345, False),
|
|
|
|
('http://www.qutebrowser.org/', '', 67890, False)]
|
2016-06-10 12:00:57 +02:00
|
|
|
|
|
|
|
|
2017-03-26 22:52:10 +02:00
|
|
|
def test_clear(qtbot, tmpdir, hist, mocker):
|
|
|
|
hist.add_url(QUrl('http://example.com/'))
|
|
|
|
hist.add_url(QUrl('http://www.qutebrowser.org/'))
|
2016-06-10 12:00:57 +02:00
|
|
|
|
2017-03-26 22:52:10 +02:00
|
|
|
m = mocker.patch('qutebrowser.browser.history.message.confirm_async')
|
|
|
|
hist.clear()
|
|
|
|
m.assert_called()
|
2016-06-10 12:00:57 +02:00
|
|
|
|
|
|
|
|
2017-03-26 22:52:10 +02:00
|
|
|
def test_clear_force(qtbot, tmpdir, hist):
|
|
|
|
hist.add_url(QUrl('http://example.com/'))
|
2016-06-10 12:00:57 +02:00
|
|
|
hist.add_url(QUrl('http://www.qutebrowser.org/'))
|
2017-04-08 13:13:16 +02:00
|
|
|
hist.clear(force=True)
|
2017-03-26 22:52:10 +02:00
|
|
|
assert not len(hist)
|
2016-06-10 12:00:57 +02:00
|
|
|
|
|
|
|
|
2017-02-21 14:27:52 +01:00
|
|
|
@pytest.mark.parametrize('item', [
|
|
|
|
('http://www.example.com', 12346, 'the title', False),
|
|
|
|
('http://www.example.com', 12346, 'the title', True)
|
|
|
|
])
|
|
|
|
def test_add_item(qtbot, hist, item):
|
|
|
|
(url, atime, title, redirect) = item
|
|
|
|
hist.add_url(QUrl(url), atime=atime, title=title, redirect=redirect)
|
2017-04-04 14:27:42 +02:00
|
|
|
assert list(hist) == [(url, title, atime, redirect)]
|
2016-06-10 14:29:03 +02:00
|
|
|
|
|
|
|
|
2017-03-26 22:52:10 +02:00
|
|
|
def test_add_item_invalid(qtbot, hist, caplog):
|
|
|
|
with caplog.at_level(logging.WARNING):
|
|
|
|
hist.add_url(QUrl())
|
|
|
|
assert not list(hist)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('level, url, req_url, expected', [
|
|
|
|
(logging.DEBUG, 'a.com', 'a.com', [('a.com', 'title', 12345, False)]),
|
|
|
|
(logging.DEBUG, 'a.com', 'b.com', [('a.com', 'title', 12345, False),
|
|
|
|
('b.com', 'title', 12345, True)]),
|
|
|
|
(logging.WARNING, 'a.com', '', [('a.com', 'title', 12345, False)]),
|
|
|
|
(logging.WARNING, '', '', []),
|
|
|
|
])
|
|
|
|
def test_add_from_tab(hist, level, url, req_url, expected, mock_time, caplog):
|
|
|
|
with caplog.at_level(level):
|
|
|
|
hist.add_from_tab(QUrl(url), QUrl(req_url), 'title')
|
|
|
|
assert set(list(hist)) == set(expected)
|
2016-06-10 14:29:03 +02:00
|
|
|
|
|
|
|
|
2016-08-22 07:40:24 +02:00
|
|
|
@pytest.fixture
|
2016-06-09 21:13:25 +02:00
|
|
|
def hist_interface():
|
2016-09-05 18:45:50 +02:00
|
|
|
# pylint: disable=invalid-name
|
|
|
|
QtWebKit = pytest.importorskip('PyQt5.QtWebKit')
|
|
|
|
from qutebrowser.browser.webkit import webkithistory
|
|
|
|
QWebHistoryInterface = QtWebKit.QWebHistoryInterface
|
|
|
|
# pylint: enable=invalid-name
|
2016-06-09 21:13:25 +02:00
|
|
|
entry = history.Entry(atime=0, url=QUrl('http://www.example.com/'),
|
|
|
|
title='example')
|
|
|
|
history_dict = {'http://www.example.com/': entry}
|
2017-01-16 03:42:35 +01:00
|
|
|
interface = webkithistory.WebHistoryInterface(history_dict)
|
2016-06-09 21:13:25 +02:00
|
|
|
QWebHistoryInterface.setDefaultInterface(interface)
|
|
|
|
yield
|
|
|
|
QWebHistoryInterface.setDefaultInterface(None)
|
|
|
|
|
|
|
|
|
|
|
|
def test_history_interface(qtbot, webview, hist_interface):
|
2016-11-15 22:25:51 +01:00
|
|
|
html = b"<a href='about:blank'>foo</a>"
|
|
|
|
url = urlutils.data_url('text/html', html)
|
2016-06-09 21:13:25 +02:00
|
|
|
with qtbot.waitSignal(webview.loadFinished):
|
|
|
|
webview.load(url)
|
2016-06-10 12:00:57 +02:00
|
|
|
|
|
|
|
|
2017-02-21 14:27:52 +01:00
|
|
|
@pytest.fixture
|
|
|
|
def cleanup_init():
|
|
|
|
# prevent test_init from leaking state
|
2017-03-23 00:55:03 +01:00
|
|
|
yield
|
2017-02-21 14:27:52 +01:00
|
|
|
try:
|
2017-03-23 00:55:03 +01:00
|
|
|
hist = objreg.get('web-history')
|
|
|
|
hist.setParent(None)
|
|
|
|
objreg.delete('web-history')
|
2017-02-21 14:27:52 +01:00
|
|
|
from PyQt5.QtWebKit import QWebHistoryInterface
|
|
|
|
QWebHistoryInterface.setDefaultInterface(None)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2017-02-05 17:09:04 +01:00
|
|
|
@pytest.mark.parametrize('backend', [usertypes.Backend.QtWebEngine,
|
|
|
|
usertypes.Backend.QtWebKit])
|
2017-02-21 14:27:52 +01:00
|
|
|
def test_init(backend, qapp, tmpdir, monkeypatch, cleanup_init):
|
2017-02-08 17:04:14 +01:00
|
|
|
if backend == usertypes.Backend.QtWebKit:
|
2016-09-05 18:45:50 +02:00
|
|
|
pytest.importorskip('PyQt5.QtWebKitWidgets')
|
2017-02-08 17:04:14 +01:00
|
|
|
else:
|
|
|
|
assert backend == usertypes.Backend.QtWebEngine
|
2016-09-05 18:45:50 +02:00
|
|
|
|
2017-02-05 17:09:04 +01:00
|
|
|
monkeypatch.setattr(history.objects, 'backend', backend)
|
2016-06-10 12:00:57 +02:00
|
|
|
history.init(qapp)
|
|
|
|
hist = objreg.get('web-history')
|
|
|
|
assert hist.parent() is qapp
|
2016-09-05 18:45:50 +02:00
|
|
|
|
|
|
|
try:
|
|
|
|
from PyQt5.QtWebKit import QWebHistoryInterface
|
|
|
|
except ImportError:
|
|
|
|
QWebHistoryInterface = None
|
2016-08-10 15:19:12 +02:00
|
|
|
|
2017-02-05 17:09:04 +01:00
|
|
|
if backend == usertypes.Backend.QtWebKit:
|
2016-09-05 18:45:50 +02:00
|
|
|
default_interface = QWebHistoryInterface.defaultInterface()
|
2016-08-10 15:19:12 +02:00
|
|
|
assert default_interface._history is hist
|
|
|
|
else:
|
2017-02-05 17:09:04 +01:00
|
|
|
assert backend == usertypes.Backend.QtWebEngine
|
2016-09-05 18:45:50 +02:00
|
|
|
if QWebHistoryInterface is None:
|
|
|
|
default_interface = None
|
|
|
|
else:
|
|
|
|
default_interface = QWebHistoryInterface.defaultInterface()
|
2016-08-10 15:19:12 +02:00
|
|
|
# For this to work, nothing can ever have called setDefaultInterface
|
|
|
|
# before (so we need to test webengine before webkit)
|
|
|
|
assert default_interface is None
|
2017-03-29 14:59:16 +02:00
|
|
|
|
|
|
|
|
2017-04-08 22:20:55 +02:00
|
|
|
def test_read(hist, tmpdir):
|
2017-03-29 14:59:16 +02:00
|
|
|
histfile = tmpdir / 'history'
|
2017-04-08 22:20:55 +02:00
|
|
|
# empty line is deliberate, to test skipping empty lines
|
2017-03-29 14:59:16 +02:00
|
|
|
histfile.write('''12345 http://example.com/ title
|
|
|
|
12346 http://qutebrowser.org/
|
|
|
|
67890 http://example.com/path
|
|
|
|
|
2017-04-08 22:20:55 +02:00
|
|
|
68891-r http://example.com/path/other ''')
|
2017-03-29 14:59:16 +02:00
|
|
|
|
2017-04-08 22:20:55 +02:00
|
|
|
hist.read(str(histfile))
|
2017-03-29 14:59:16 +02:00
|
|
|
|
|
|
|
assert list(hist) == [
|
|
|
|
('http://example.com/', 'title', 12345, False),
|
|
|
|
('http://qutebrowser.org/', '', 12346, False),
|
|
|
|
('http://example.com/path', '', 67890, False),
|
|
|
|
('http://example.com/path/other', '', 68891, True)
|
|
|
|
]
|
2017-04-08 22:20:55 +02:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('line', [
|
|
|
|
'xyz http://example.com/bad-timestamp',
|
|
|
|
'12345',
|
|
|
|
'http://example.com/no-timestamp',
|
|
|
|
'68891-r-r http://example.com/double-flag',
|
|
|
|
])
|
|
|
|
def test_read_invalid(hist, tmpdir, line):
|
|
|
|
histfile = tmpdir / 'history'
|
|
|
|
histfile.write(line)
|
|
|
|
|
|
|
|
with pytest.raises(Exception):
|
|
|
|
hist.read(str(histfile))
|