From d77c58fc80a2fe62180796bdc28e8ed69bd46715 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Wed, 20 Jun 2018 21:01:33 +0200 Subject: Move tests to pytest It just seems a little nicer than plain old unittest --- crocoite/browser.py | 162 ---------------------------------------------------- 1 file changed, 162 deletions(-) (limited to 'crocoite/browser.py') diff --git a/crocoite/browser.py b/crocoite/browser.py index f583c9b..3b9f7ab 100644 --- a/crocoite/browser.py +++ b/crocoite/browser.py @@ -25,7 +25,6 @@ Chrome browser interactions. import logging from urllib.parse import urlsplit from base64 import b64decode -from http.server import BaseHTTPRequestHandler from collections import deque from threading import Event @@ -397,164 +396,3 @@ class NullService: def __exit__ (self, *exc): pass -### tests ### - -import unittest, time -from operator import itemgetter - -class TestItem (Item): - """ This should be as close to Item as possible """ - - __slots__ = ('bodySend', '_body') - base = 'http://localhost:8000/' - - def __init__ (self, path, status, headers, bodyReceive, bodySend=None): - super ().__init__ (tab=None) - self.chromeResponse = {'response': {'headers': headers, 'status': status, 'url': self.base + path}} - self._body = bodyReceive, False - self.bodySend = bodyReceive if not bodySend else bodySend - - @property - def body (self): - return self._body - -testItems = [ - TestItem ('binary', 200, {'Content-Type': 'application/octet-stream'}, b'\x00\x01\x02'), - TestItem ('attachment', 200, - {'Content-Type': 'text/plain; charset=utf-8', - 'Content-Disposition': 'attachment; filename="attachment.txt"', - }, - 'This is a simple text file with umlauts. ÄÖU.'.encode ('utf8')), - TestItem ('encoding/utf8', 200, {'Content-Type': 'text/plain; charset=utf-8'}, - 'This is a test, äöü μνψκ ¥¥¥¿ýý¡'.encode ('utf8')), - TestItem ('encoding/iso88591', 200, {'Content-Type': 'text/plain; charset=ISO-8859-1'}, - 'This is a test, äöü.'.encode ('utf8'), - 'This is a test, äöü.'.encode ('ISO-8859-1')), - TestItem ('encoding/latin1', 200, {'Content-Type': 'text/plain; charset=latin1'}, - 'This is a test, äöü.'.encode ('utf8'), - 'This is a test, äöü.'.encode ('latin1')), - TestItem ('image', 200, {'Content-Type': 'image/png'}, - # 1×1 png image - b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x00\x00\x00\x00:~\x9bU\x00\x00\x00\nIDAT\x08\x1dc\xf8\x0f\x00\x01\x01\x01\x006_g\x80\x00\x00\x00\x00IEND\xaeB`\x82'), - TestItem ('empty', 200, {}, b''), - TestItem ('redirect/301/empty', 301, {'Location': '/empty'}, b''), - TestItem ('redirect/301/redirect/301/empty', 301, {'Location': '/redirect/301/empty'}, b''), - TestItem ('nonexistent', 404, {}, b''), - TestItem ('html', 200, {'Content-Type': 'html'}, - ''.encode ('utf8')), - TestItem ('html/alert', 200, {'Content-Type': 'html'}, - ''.encode ('utf8')), - ] -testItemMap = dict ([(item.parsedUrl.path, item) for item in testItems]) - -class TestHTTPRequestHandler (BaseHTTPRequestHandler): - def do_GET(self): - item = testItemMap.get (self.path) - if item: - self.send_response (item.response['status']) - for k, v in item.response['headers'].items (): - self.send_header (k, v) - body = item.bodySend - self.send_header ('Content-Length', len (body)) - self.end_headers() - self.wfile.write (body) - return - - def log_message (self, format, *args): - pass - -def startServer (): - import http.server - PORT = 8000 - httpd = http.server.HTTPServer (("localhost", PORT), TestHTTPRequestHandler) - httpd.serve_forever() - -class TestSiteLoader (unittest.TestCase): - __slots__ = ('server', 'baseurl', 'service', 'browser') - - def setUp (self): - from multiprocessing import Process - self.server = Process (target=startServer) - self.server.start () - self.baseurl = 'http://localhost:8000' - self.service = ChromeService () - self.browser = self.service.__enter__ () - - def buildAdapter (self, path): - self.assertTrue (path.startswith ('/')) - return SiteLoader (self.browser, '{}{}'.format (self.baseurl, path)) - - def assertItems (self, l, items): - items = dict ([(i.parsedUrl.path, i) for i in items]) - timeout = 5 - while True: - if not l.notify.wait (timeout) and len (items) > 0: - self.fail ('timeout') - if len (l.queue) > 0: - item = l.queue.popleft () - if isinstance (item, Exception): - raise item - self.assertIsNot (item.chromeResponse, None, msg='url={}'.format (item.request['url'])) - golden = items.pop (item.parsedUrl.path) - if not golden: - self.fail ('url {} not supposed to be fetched'.format (item.url)) - self.assertEqual (item.body[0], golden.body[0], msg='body for url={}'.format (item.request['url'])) - self.assertEqual (item.response['status'], golden.response['status']) - for k, v in golden.responseHeaders: - actual = list (map (itemgetter (1), filter (lambda x: x[0] == k, item.responseHeaders))) - self.assertIn (v, actual) - - # check queue at least once - if not items: - break - - def assertLiteralItem (self, item, deps=[]): - with self.buildAdapter (item.parsedUrl.path) as l: - l.start () - self.assertItems (l, [item] + deps) - - def test_empty (self): - self.assertLiteralItem (testItemMap['/empty']) - - def test_redirect (self): - self.assertLiteralItem (testItemMap['/redirect/301/empty'], [testItemMap['/empty']]) - # chained redirects - self.assertLiteralItem (testItemMap['/redirect/301/redirect/301/empty'], [testItemMap['/redirect/301/empty'], testItemMap['/empty']]) - - def test_encoding (self): - """ Text responses are transformed to UTF-8. Make sure this works - correctly. """ - for item in {testItemMap['/encoding/utf8'], testItemMap['/encoding/latin1'], testItemMap['/encoding/iso88591']}: - self.assertLiteralItem (item) - - def test_binary (self): - """ Browser should ignore content it cannot display (i.e. octet-stream) """ - with self.buildAdapter ('/binary') as l: - l.start () - self.assertItems (l, []) - - def test_image (self): - """ Images should be displayed inline """ - self.assertLiteralItem (testItemMap['/image']) - - def test_attachment (self): - """ And downloads won’t work in headless mode, even if it’s just a text file """ - with self.buildAdapter ('/attachment') as l: - l.start () - self.assertItems (l, []) - - def test_html (self): - self.assertLiteralItem (testItemMap['/html'], [testItemMap['/image'], testItemMap['/nonexistent']]) - # make sure alerts are dismissed correctly (image won’t load otherwise) - self.assertLiteralItem (testItemMap['/html/alert'], [testItemMap['/image']]) - - def tearDown (self): - self.service.__exit__ (None, None, None) - self.server.terminate () - self.server.join () - -if __name__ == '__main__': - import sys - if sys.argv[1] == 'server': - startServer () - -- cgit v1.2.3