# -*- coding: utf-8 -*-
"""Unit tests for webmention.py."""
from unittest.mock import patch
import requests
from .. import testutil, util
from ..testutil import requests_response
from ..webmention import discover, send
[docs]
class DiscoverTest(testutil.TestCase):
def _test(self, expected, html, status_code=200, response_headers=None):
resp = requests_response(
f'<html>{html}</html>', url='http://foo', status=status_code,
headers=response_headers)
with patch.object(util.session, 'get', return_value=resp):
got = discover('http://foo')
self.assertEqual(expected, got.endpoint)
self.assertEqual(resp, got.response)
[docs]
def test_bad_url(self):
for bad in (None, 123, '', 'asdf'):
with self.assertRaises(ValueError):
discover(bad)
[docs]
def test_no_endpoint(self):
self._test(None, '')
[docs]
def test_html_link(self):
self._test('http://endpoint', '<link rel="webmention" href="http://endpoint">')
[docs]
def test_html_a(self):
self._test('http://endpoint', '<a rel="webmention" href="http://endpoint">')
[docs]
def test_html_refresh(self):
resp2 = requests_response(
'<html><link rel="webmention" href="http://endpoint"></html>', url='http://foo')
with patch.object(util.session, 'get', side_effect=[
requests_response(
"""<html><meta http-equiv="refresh" content="0;URL='http://foo'"></html>""",
url='http://will/redirect'),
resp2,
]):
got = discover('http://will/redirect', follow_meta_refresh=True)
self.assertEqual('http://endpoint', got.endpoint)
self.assertEqual(resp2, got.response)
[docs]
def test_html_relative(self):
self._test('http://foo/bar', '<link rel="webmention" href="/bar">')
[docs]
def test_html_rel_url(self):
self._test('http://foo/bar', '<link rel="http://webmention.org/" href="/bar">')
[docs]
def test_html_link_and_a(self):
self._test('http://endpoint1', """\
<a rel="webmention" href="http://endpoint1">
<link rel="webmention" href="http://endpoint2">
""")
[docs]
def test_html_link_a_and_refresh(self):
self._test('http://endpoint1', """\
<meta http-equiv="refresh" content="0;URL=\'http://refresh\'">
<a rel="webmention" href="http://endpoint1">
<link rel="webmention" href="http://endpoint2">
""")
[docs]
def test_html_other_links(self):
self._test('http://endpoint', """\
<link rel="foo" href="http://bar">
<link rel="webmention" href="http://endpoint">
""")
[docs]
def test_html_empty(self):
self._test(None, '<link rel="webmention/" href="">')
[docs]
def test_html_unicode(self):
self._test('http://☕/☕?☕=☕', '<link rel="webmention" href="http://☕/☕?☕=☕">')
[docs]
def test_html_escaped(self):
self._test('http://%E2%98%95/%E2%98%95?%E2%98%95=%E2%98%95',
'<link rel="webmention" href="http://%E2%98%95/%E2%98%95?%E2%98%95=%E2%98%95">')
[docs]
def test_html_content_type_html(self):
self._test('http://foo/bar', '<link rel="http://webmention.org/" href="/bar">',
response_headers={'Content-Type': 'text/html'})
[docs]
def test_html_content_type_html_charset(self):
self._test('http://foo/bar', '<link rel="http://webmention.org/" href="/bar">',
response_headers={'Content-Type': 'text/html; charset=utf-8'})
[docs]
def test_html_content_type_other(self):
self._test(None, '<link rel="http://webmention.org/" href="/bar">',
response_headers={'Content-Type': 'text/json'})
[docs]
def test_http_500(self):
self._test('http://endpoint', '', status_code=500, response_headers={
'Link': '<http://endpoint>; rel=webmention',
})
[docs]
@patch.object(util.session, 'get', side_effect=requests.ConnectionError('foo'))
def test_connection_error(self, _):
with self.assertRaises(requests.ConnectionError):
discover('http://foo')
[docs]
class SendTest(testutil.TestCase):
def _test(self, endpoint='http://endpoint', source='http://source',
target='http://target', status_code=200):
resp = requests_response('', url=endpoint, status=status_code)
with patch.object(util.session, 'post', return_value=resp):
got = send(endpoint, source, target)
self.assertEqual(resp, got)
[docs]
def test_bad_url(self):
for bad in (None, 123, '', 'asdf'):
with self.assertRaises(ValueError):
send(bad, 'http://x', 'http://x')
with self.assertRaises(ValueError):
send('http://x', bad, 'http://x')
with self.assertRaises(ValueError):
send('http://x', 'http://x', bad)
[docs]
def test_success(self):
self._test()
[docs]
def test_requests_exception(self):
with self.assertRaises(requests.HTTPError):
self._test(status_code=500)
[docs]
def test_preserve_endpoint_query_params(self):
self._test('http://endpoint?x=y&a=b')
[docs]
def test_unicode_urls(self):
self._test('http://☕/☕?☕=☕', 'http://❤/❤?❤=❤', 'http://⚠/⚠?⚠=⚠')
[docs]
def test_unicode_urls_escaped(self):
self._test('http://%E2%98%95/%E2%98%95?%E2%98%95=%E2%98%95',
'http://%E2%9A%A0/%E2%9A%A0?%E2%9A%A0=%E2%9A%A0',
'http://%E2%9D%A4/%E2%9D%A4?%E2%9D%A4=%E2%9D%A4')