2015-11-11 07:48:36 +01:00
|
|
|
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
|
|
|
|
|
2018-02-05 12:19:50 +01:00
|
|
|
# Copyright 2015-2018 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
2015-11-11 07:48:36 +01: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/>.
|
|
|
|
|
|
|
|
"""Test mhtml downloads based on sample files."""
|
|
|
|
|
|
|
|
import os
|
|
|
|
import os.path
|
2017-12-15 23:08:53 +01:00
|
|
|
import re
|
2015-11-21 00:20:09 +01:00
|
|
|
import collections
|
2015-11-11 07:48:36 +01:00
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
2018-03-05 11:36:29 +01:00
|
|
|
from qutebrowser.utils import qtutils
|
|
|
|
|
2015-11-11 07:48:36 +01:00
|
|
|
|
|
|
|
def collect_tests():
|
|
|
|
basedir = os.path.dirname(__file__)
|
|
|
|
datadir = os.path.join(basedir, 'data', 'downloads', 'mhtml')
|
|
|
|
files = os.listdir(datadir)
|
|
|
|
return files
|
|
|
|
|
|
|
|
|
|
|
|
def normalize_line(line):
|
|
|
|
line = line.rstrip('\n')
|
2017-02-07 00:15:39 +01:00
|
|
|
line = re.sub('boundary="-+(=_qute|MultipartBoundary)-[0-9a-zA-Z-]+"',
|
2015-11-11 07:48:36 +01:00
|
|
|
'boundary="---=_qute-UUID"', line)
|
2017-02-07 00:15:39 +01:00
|
|
|
line = re.sub('^-+(=_qute|MultipartBoundary)-[0-9a-zA-Z-]+$',
|
|
|
|
'-----=_qute-UUID', line)
|
2015-11-11 07:48:36 +01:00
|
|
|
line = re.sub(r'localhost:\d{1,5}', 'localhost:(port)', line)
|
2017-02-07 00:15:39 +01:00
|
|
|
if line.startswith('Date: '):
|
|
|
|
line = 'Date: today'
|
|
|
|
if line.startswith('Content-ID: '):
|
|
|
|
line = 'Content-ID: 42'
|
2015-11-21 16:17:20 +01:00
|
|
|
|
|
|
|
# Depending on Python's mimetypes module/the system's mime files, .js
|
|
|
|
# files could be either identified as x-javascript or just javascript
|
|
|
|
line = line.replace('Content-Type: application/x-javascript',
|
|
|
|
'Content-Type: application/javascript')
|
|
|
|
|
2018-03-05 11:36:29 +01:00
|
|
|
# Added with Qt 5.11
|
|
|
|
if (line.startswith('Snapshot-Content-Location: ') and
|
|
|
|
not qtutils.version_check('5.11', compiled=False)):
|
|
|
|
line = None
|
|
|
|
|
2015-11-11 07:48:36 +01:00
|
|
|
return line
|
|
|
|
|
|
|
|
|
2018-12-12 11:27:38 +01:00
|
|
|
def normalize_whole(s, webengine):
|
|
|
|
if qtutils.version_check('5.12', compiled=False) and webengine:
|
2018-09-24 11:03:38 +02:00
|
|
|
s = s.replace('\n\n-----=_qute-UUID', '\n-----=_qute-UUID')
|
|
|
|
return s
|
|
|
|
|
|
|
|
|
2015-11-11 07:48:36 +01:00
|
|
|
class DownloadDir:
|
|
|
|
|
|
|
|
"""Abstraction over a download directory."""
|
|
|
|
|
2018-12-12 11:27:38 +01:00
|
|
|
def __init__(self, tmpdir, config):
|
2015-11-11 07:48:36 +01:00
|
|
|
self._tmpdir = tmpdir
|
2018-12-12 11:27:38 +01:00
|
|
|
self._config = config
|
2015-11-11 07:48:36 +01:00
|
|
|
self.location = str(tmpdir)
|
|
|
|
|
|
|
|
def read_file(self):
|
|
|
|
files = self._tmpdir.listdir()
|
|
|
|
assert len(files) == 1
|
|
|
|
|
|
|
|
with open(str(files[0]), 'r', encoding='utf-8') as f:
|
|
|
|
return f.readlines()
|
|
|
|
|
2017-02-08 14:12:31 +01:00
|
|
|
def sanity_check_mhtml(self):
|
|
|
|
assert 'Content-Type: multipart/related' in '\n'.join(self.read_file())
|
|
|
|
|
2015-11-11 07:48:36 +01:00
|
|
|
def compare_mhtml(self, filename):
|
|
|
|
with open(filename, 'r', encoding='utf-8') as f:
|
2018-09-24 10:25:33 +02:00
|
|
|
expected_data = '\n'.join(normalize_line(line)
|
|
|
|
for line in f
|
|
|
|
if normalize_line(line) is not None)
|
|
|
|
actual_data = '\n'.join(normalize_line(line)
|
|
|
|
for line in self.read_file())
|
2018-12-12 11:27:38 +01:00
|
|
|
actual_data = normalize_whole(actual_data,
|
|
|
|
webengine=self._config.webengine)
|
2018-09-24 10:25:33 +02:00
|
|
|
|
2015-11-11 07:48:36 +01:00
|
|
|
assert actual_data == expected_data
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
2018-12-12 11:27:38 +01:00
|
|
|
def download_dir(tmpdir, pytestconfig):
|
|
|
|
return DownloadDir(tmpdir, pytestconfig)
|
2015-11-11 07:48:36 +01:00
|
|
|
|
|
|
|
|
2017-09-19 10:35:54 +02:00
|
|
|
def _test_mhtml_requests(test_dir, test_path, server):
|
2017-02-07 00:38:43 +01:00
|
|
|
with open(os.path.join(test_dir, 'requests'), encoding='utf-8') as f:
|
|
|
|
expected_requests = []
|
|
|
|
for line in f:
|
|
|
|
if line.startswith('#'):
|
|
|
|
continue
|
|
|
|
path = '/{}/{}'.format(test_path, line.strip())
|
2017-09-19 10:35:54 +02:00
|
|
|
expected_requests.append(server.ExpectedRequest('GET', path))
|
2017-02-07 00:38:43 +01:00
|
|
|
|
2017-09-19 10:35:54 +02:00
|
|
|
actual_requests = server.get_requests()
|
2017-02-07 00:38:43 +01:00
|
|
|
# Requests are not hashable, we need to convert to ExpectedRequests
|
2017-09-19 10:35:54 +02:00
|
|
|
actual_requests = [server.ExpectedRequest.from_request(req)
|
2017-02-07 00:38:43 +01:00
|
|
|
for req in actual_requests]
|
|
|
|
assert (collections.Counter(actual_requests) ==
|
|
|
|
collections.Counter(expected_requests))
|
|
|
|
|
|
|
|
|
2015-11-11 07:48:36 +01:00
|
|
|
@pytest.mark.parametrize('test_name', collect_tests())
|
2017-09-19 10:35:54 +02:00
|
|
|
def test_mhtml(request, test_name, download_dir, quteproc, server):
|
2017-06-16 16:22:41 +02:00
|
|
|
quteproc.set_setting('downloads.location.directory', download_dir.location)
|
|
|
|
quteproc.set_setting('downloads.location.prompt', 'false')
|
2015-11-11 07:48:36 +01:00
|
|
|
|
|
|
|
test_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)),
|
|
|
|
'data', 'downloads', 'mhtml', test_name)
|
|
|
|
test_path = 'data/downloads/mhtml/{}'.format(test_name)
|
|
|
|
|
2016-01-12 22:48:38 +01:00
|
|
|
url_path = '{}/{}.html'.format(test_path, test_name)
|
|
|
|
quteproc.open_path(url_path)
|
|
|
|
|
2015-11-11 07:48:36 +01:00
|
|
|
download_dest = os.path.join(download_dir.location,
|
|
|
|
'{}-downloaded.mht'.format(test_name))
|
2015-11-27 19:30:06 +01:00
|
|
|
|
|
|
|
# Wait for favicon.ico to be loaded if there is one
|
|
|
|
if os.path.exists(os.path.join(test_dir, 'favicon.png')):
|
2017-09-19 10:35:54 +02:00
|
|
|
server.wait_for(path='/{}/favicon.png'.format(test_path))
|
2015-11-27 19:30:06 +01:00
|
|
|
|
2015-11-21 00:10:49 +01:00
|
|
|
# Discard all requests that were necessary to display the page
|
2017-09-19 10:35:54 +02:00
|
|
|
server.clear_data()
|
2015-11-11 07:48:36 +01:00
|
|
|
quteproc.send_cmd(':download --mhtml --dest "{}"'.format(download_dest))
|
2017-02-07 00:15:39 +01:00
|
|
|
quteproc.wait_for(category='downloads',
|
2015-11-12 13:17:10 +01:00
|
|
|
message='File successfully written.')
|
2015-11-11 07:48:36 +01:00
|
|
|
|
2017-02-07 00:15:39 +01:00
|
|
|
suffix = '-webengine' if request.config.webengine else ''
|
|
|
|
filename = '{}{}.mht'.format(test_name, suffix)
|
|
|
|
expected_file = os.path.join(test_dir, filename)
|
2017-02-08 14:12:31 +01:00
|
|
|
if os.path.exists(expected_file):
|
|
|
|
download_dir.compare_mhtml(expected_file)
|
|
|
|
else:
|
|
|
|
download_dir.sanity_check_mhtml()
|
2015-11-11 07:48:36 +01:00
|
|
|
|
2017-02-07 00:38:43 +01:00
|
|
|
if not request.config.webengine:
|
2017-09-19 10:35:54 +02:00
|
|
|
_test_mhtml_requests(test_dir, test_path, server)
|