diff --git a/emails/testsuite/conftest.py b/emails/testsuite/conftest.py index 5269a51..a36492f 100644 --- a/emails/testsuite/conftest.py +++ b/emails/testsuite/conftest.py @@ -6,6 +6,10 @@ import random import sys import platform +import os +import functools +import threading +from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer logging.basicConfig(level=logging.DEBUG) @@ -14,6 +18,37 @@ import cssutils cssutils.log.setLevel(logging.FATAL) +import emails.utils + +TESTSUITE_ROOT = os.path.dirname(__file__) + + +class _QuietHandler(SimpleHTTPRequestHandler): + def log_message(self, *args): + pass + + +@pytest.fixture(scope='session') +def _http_fixtures_server(): + handler = functools.partial(_QuietHandler, directory=TESTSUITE_ROOT) + server = ThreadingHTTPServer(('127.0.0.1', 0), handler) + thread = threading.Thread(target=server.serve_forever, daemon=True) + thread.start() + yield 'http://127.0.0.1:%s/' % server.server_address[1] + server.shutdown() + server.server_close() + + +@pytest.fixture +def http_fixtures(_http_fixtures_server, monkeypatch): + """ + Base url of a local HTTP server that serves files from emails/testsuite, + e.g. http_fixtures + 'data/http/python-logo.gif'. + Fetching from loopback is allowed while the fixture is active. + """ + monkeypatch.setattr(emails.utils, 'url_validator', None) + return _http_fixtures_server + @pytest.fixture(scope='module') def django_email_backend(request): diff --git a/emails/testsuite/data/http/python-logo.gif b/emails/testsuite/data/http/python-logo.gif new file mode 100644 index 0000000..01c7bf3 Binary files /dev/null and b/emails/testsuite/data/http/python-logo.gif differ diff --git a/emails/testsuite/data/http/sample-template/images/facebook.gif b/emails/testsuite/data/http/sample-template/images/facebook.gif new file mode 100644 index 0000000..f85793d Binary files /dev/null and b/emails/testsuite/data/http/sample-template/images/facebook.gif differ diff --git a/emails/testsuite/data/http/sample-template/images/flickr.gif b/emails/testsuite/data/http/sample-template/images/flickr.gif new file mode 100644 index 0000000..2f39e10 Binary files /dev/null and b/emails/testsuite/data/http/sample-template/images/flickr.gif differ diff --git a/emails/testsuite/data/http/sample-template/images/gallery.png b/emails/testsuite/data/http/sample-template/images/gallery.png new file mode 100644 index 0000000..000c71e Binary files /dev/null and b/emails/testsuite/data/http/sample-template/images/gallery.png differ diff --git a/emails/testsuite/data/http/sample-template/images/spacer.gif b/emails/testsuite/data/http/sample-template/images/spacer.gif new file mode 100644 index 0000000..35d42e8 Binary files /dev/null and b/emails/testsuite/data/http/sample-template/images/spacer.gif differ diff --git a/emails/testsuite/data/http/sample-template/images/twitter.gif b/emails/testsuite/data/http/sample-template/images/twitter.gif new file mode 100644 index 0000000..1148a0b Binary files /dev/null and b/emails/testsuite/data/http/sample-template/images/twitter.gif differ diff --git a/emails/testsuite/data/http/sample-template/images/widget-hero3.png b/emails/testsuite/data/http/sample-template/images/widget-hero3.png new file mode 100644 index 0000000..ba184ec Binary files /dev/null and b/emails/testsuite/data/http/sample-template/images/widget-hero3.png differ diff --git a/emails/testsuite/data/http/sample-template/images/widget-logo4.png b/emails/testsuite/data/http/sample-template/images/widget-logo4.png new file mode 100644 index 0000000..4a4e735 Binary files /dev/null and b/emails/testsuite/data/http/sample-template/images/widget-logo4.png differ diff --git a/emails/testsuite/data/http/sample-template/template-widgets.html b/emails/testsuite/data/http/sample-template/template-widgets.html new file mode 100644 index 0000000..e805f34 --- /dev/null +++ b/emails/testsuite/data/http/sample-template/template-widgets.html @@ -0,0 +1,301 @@ + + + + + + Campaign Monitor Newsletter + + + + + + + + +
+ + + + + +
+ + + + + + +

Campaign Monitor


WIDGET  NEWSLETTER 
+ + + + + + + +
+ +

Main feature introduction

+ +
+ +
+ + + + + + + + +
+ + + + + +
+ +

Title of new feature

+

A short explanation of the new feature

+ +
+ +
+
+
+ + + + + + +
+ + + + + +
+ +

Title of article/tip/resource

+

Description

+ +
+ +
+
+
+ + + + + + +
+ + + + + +
+ +

Title of gallery summary

+

Description of this month's gallery entries

+ +
+ +
+ + + + + + + +
+ + + + + + + + + + + + + + + + +
+ +
+ +
+
+
+ + + + + + +
+ + + + + +
+ +

Enter the quote in full

+ +
+ +
+
+
+
+ +
+ +
+ + + + + +
+ +
+ + + + + +
+ + + + + + +
+ +
+ +

You’re receiving this because you’re an awesome ABC Widgets customer or subscribed via our site.

+

Edit your subscription  |  Unsubscribe instantly

+ +
+ + + + + + + +
See our photos on FlickrFollow us on TwitterVisit us on Facebook
+ +

ABC Widgets

87 Street Avenue, California, USA

+ +
+ +
+ +
+ +
+ + + diff --git "a/emails/testsuite/data/http/url-fix/\320\237\321\203\321\210\320\272\320\270\320\275 \320\220.\320\241.jpg" "b/emails/testsuite/data/http/url-fix/\320\237\321\203\321\210\320\272\320\270\320\275 \320\220.\320\241.jpg" new file mode 100644 index 0000000..744c0eb Binary files /dev/null and "b/emails/testsuite/data/http/url-fix/\320\237\321\203\321\210\320\272\320\270\320\275 \320\220.\320\241.jpg" differ diff --git a/emails/testsuite/loader/test_loaders.py b/emails/testsuite/loader/test_loaders.py index 6617721..f91fe75 100644 --- a/emails/testsuite/loader/test_loaders.py +++ b/emails/testsuite/loader/test_loaders.py @@ -13,9 +13,7 @@ ROOT = os.path.dirname(__file__) -BASE_URL = 'http://lavr.github.io/python-emails/tests/' - -OLDORNAMENT_URLS = dict(from_url='campaignmonitor-samples/oldornament/index.html', +OLDORNAMENT_URLS = dict(from_url='loader/data/html_import/oldornament/oldornament/index.html', from_file='data/html_import/oldornament/oldornament/index.html', from_zip='data/html_import/oldornament/oldornament.zip') @@ -29,11 +27,12 @@ def test__from_html(): # TODO: more tests for from_html func -def load_messages(from_url=None, from_file=None, from_zip=None, from_directory=None, skip_text=False, **kw): +def load_messages(base_url, from_url=None, from_file=None, from_zip=None, from_directory=None, skip_text=False, + **kw): # Ususally all loaders loads same data if from_url: - print("emails.loader.from_url", BASE_URL + from_url, kw) - yield emails.loader.from_url(BASE_URL + from_url, **kw) + print("emails.loader.from_url", base_url + from_url, kw) + yield emails.loader.from_url(base_url + from_url, **kw) if from_file: print("emails.loader.from_file", os.path.join(ROOT, from_file), kw) yield emails.loader.from_file(os.path.join(ROOT, from_file), skip_text=skip_text, **kw) @@ -45,14 +44,14 @@ def load_messages(from_url=None, from_file=None, from_zip=None, from_directory=N yield emails.loader.from_zip(open(os.path.join(ROOT, from_zip), 'rb'), skip_text=skip_text, **kw) -def test_loaders(): +def test_loaders(http_fixtures): def _all_equals(seq): iseq = iter(seq) first = next(iseq) return all(x == first for x in iseq) - _base_url = os.path.dirname(BASE_URL + OLDORNAMENT_URLS['from_url']) + '/' + _base_url = os.path.dirname(http_fixtures + OLDORNAMENT_URLS['from_url']) + '/' def _remove_base_url(src, **kw): if src.startswith(_base_url): return src[len(_base_url):] @@ -63,7 +62,7 @@ def _remove_base_url(src, **kw): htmls = [] - for message in load_messages(message_params=message_params, **OLDORNAMENT_URLS): + for message in load_messages(http_fixtures, message_params=message_params, **OLDORNAMENT_URLS): # Check loaded images assert len(message.attachments.keys()) == 13 @@ -98,7 +97,7 @@ def test_noindex_loaders(): emails.loader.from_zip(open(os.path.join(ROOT, 'data/html_import/no-index/no-index.zip'), 'rb')) -def test_loaders_with_params(): +def test_loaders_with_params(http_fixtures): transform_params = [ dict(css_inline=True, remove_unsafe_tags=True, @@ -119,7 +118,8 @@ def test_loaders_with_params(): args = {} args.update(tp) args.update(OLDORNAMENT_URLS) - for m in load_messages(requests_params={'timeout': 10}, + for m in load_messages(http_fixtures, + requests_params={'timeout': 10}, message_params=message_params, **args): assert m.subject == message_params['subject'] @@ -128,7 +128,7 @@ def test_loaders_with_params(): assert a.is_inline is True -def test_loader_image_callback(): +def test_loader_image_callback(http_fixtures): checked_images = [] @@ -141,12 +141,12 @@ def check_image_callback(el, **kwargs): assert 0, "el should be lxml.etree._Element or cssutils.css.value.URIValue" return False - for message in load_messages(load_images=check_image_callback, **OLDORNAMENT_URLS): + for message in load_messages(http_fixtures, load_images=check_image_callback, **OLDORNAMENT_URLS): # Check images not loaded assert len(message.attachments.keys()) == 0 total_images = 0 - for message in load_messages(**OLDORNAMENT_URLS): + for message in load_messages(http_fixtures, **OLDORNAMENT_URLS): # Check loaded images assert len(message.attachments.keys()) == 13 total_images += len(message.attachments.keys()) @@ -154,6 +154,7 @@ def check_image_callback(el, **kwargs): assert len(checked_images) >= total_images +@pytest.mark.network def test_external_urls(): # Load some real sites with complicated html and css. diff --git a/emails/testsuite/message/test_send.py b/emails/testsuite/message/test_send.py index a7f00ee..9c742f8 100644 --- a/emails/testsuite/message/test_send.py +++ b/emails/testsuite/message/test_send.py @@ -9,10 +9,10 @@ from emails.testsuite.smtp_servers import get_servers -def get_letters(): +def get_letters(base_url): # Test email with attachment - URL = 'http://lavr.github.io/python-emails/tests/campaignmonitor-samples/sample-template/images/gallery.png' + URL = base_url + 'data/http/sample-template/images/gallery.png' data = common_email_data(subject='Single attachment', attachments=[emails.store.LazyHTTPFile(uri=URL), ]) yield emails.html(**data), None @@ -20,7 +20,7 @@ def get_letters(): yield emails.html(**common_email_data(subject='Render with name=John')), {'name': 'John'} # Email with several inline images - url = 'http://lavr.github.io/python-emails/tests/campaignmonitor-samples/sample-template/template-widgets.html' + url = base_url + 'data/http/sample-template/template-widgets.html' data = common_email_data(subject='Sample html with inline images') del data['html'] yield emails.loader.from_url(url=url, message_params=data, images_inline=True), None @@ -29,9 +29,9 @@ def get_letters(): yield emails.Message(**common_email_data(mail_to="anaïs@lavr.me", subject="UTF-8 To")), None -def test_send_letters(): +def test_send_letters(http_fixtures): - for m, render in get_letters(): + for m, render in get_letters(http_fixtures): for tag, server in get_servers(): server.patch_message(m) print(tag, server.params) diff --git a/emails/testsuite/store/test_store.py b/emails/testsuite/store/test_store.py index bedbb45..7f72474 100644 --- a/emails/testsuite/store/test_store.py +++ b/emails/testsuite/store/test_store.py @@ -11,8 +11,8 @@ def test_fix_content_type(): assert fix_content_type('') == 'image/unknown' -def test_lazy_http(): - IMG_URL = 'http://lavr.github.io/python-emails/tests/python-logo.gif' +def test_lazy_http(http_fixtures): + IMG_URL = http_fixtures + 'data/http/python-logo.gif' f = emails.store.LazyHTTPFile(uri=IMG_URL) assert f.filename == 'python-logo.gif' assert f.content_disposition == 'attachment' diff --git a/emails/testsuite/test_utils.py b/emails/testsuite/test_utils.py index 8b5371d..7a2c6de 100644 --- a/emails/testsuite/test_utils.py +++ b/emails/testsuite/test_utils.py @@ -43,10 +43,10 @@ def test_sanitize_email(): assert sanitize_email('a@♤.d') == 'a@xn--f6h.d' -def test_fetch_url(): - fetch_url('http://google.com') +def test_fetch_url(http_fixtures): + fetch_url(http_fixtures + 'data/http/python-logo.gif') with pytest.raises(HTTPLoaderError): - fetch_url('http://google.com/nonexistent-no-page') + fetch_url(http_fixtures + 'data/http/nonexistent-no-page') def test_message_id(): @@ -68,9 +68,9 @@ def test_message_id(): _ids.add(_id) -def test_url_fix(): +def test_url_fix(http_fixtures): # Check url with unicode and spaces - r = fetch_url('http://lavr.github.io/python-emails/tests/url-fix/Пушкин А.С.jpg') + r = fetch_url(http_fixtures + 'data/http/url-fix/Пушкин А.С.jpg') assert len(r.content) == 12910 diff --git a/setup.cfg b/setup.cfg index 86e0181..24992dd 100644 --- a/setup.cfg +++ b/setup.cfg @@ -40,6 +40,7 @@ ignore_errors = true norecursedirs = .* {arch} *.egg *.egg-info dist build requirements markers = e2e: tests that require a running SMTP server + network: tests that require access to external sites django: tests that require Django [coverage:run]