Skip to content

Commit

Permalink
update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
willforde committed Feb 24, 2021
1 parent 6530540 commit 2910fcc
Show file tree
Hide file tree
Showing 6 changed files with 414 additions and 44 deletions.
2 changes: 1 addition & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[run]
source=urlquick
branch = True
branch=True

[report]
exclude_lines =
Expand Down
96 changes: 77 additions & 19 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
import requests
import urlquick
import pytest
import json as _json
import io

from requests.adapters import HTTPResponse
from requests import adapters


class RequestsMock(object):
def __init__(self, mocker):
self.mocker = mocker
self._store = {}

def mock_send(self_mock, request, **_):
urlid = urlquick.hash_url(request)
assert urlid in self._store
return self_mock.build_response(request, self._store[urlid])

mocker.patch.object(adapters.HTTPAdapter, "send", mock_send)
class MockResponse(object):
"""Mock response that keeps track of when or if the response was called."""
def __init__(self, body="", json=None, **kwargs):
if json is not None:
body = _json.dumps(json)

@staticmethod
def build_urllib3_response(text="", **kwargs): # type: (...) -> HTTPResponse
# Alieas to some common params
kwargs["body"] = io.BytesIO(urlquick.to_bytes_string(text))
self._body = body
kwargs["body"] = io.BytesIO(urlquick.to_bytes_string(body))
kwargs.setdefault("status", 200)
kwargs.setdefault("reason", "OK")
kwargs["preload_content"] = False
Expand All @@ -31,20 +25,84 @@ def build_urllib3_response(text="", **kwargs): # type: (...) -> HTTPResponse
# Add mock headers
headers = kwargs.setdefault("headers", {})
headers.setdefault("Content-Type", "text/html; charset=utf8")
return HTTPResponse(**kwargs)
self._kwargs = kwargs
self._called = 0

@property
def response(self):
"""Return the response but increment called counter."""
self._called += 1
self._kwargs["body"] = io.BytesIO(urlquick.to_bytes_string(self._body))
return HTTPResponse(**self._kwargs)

@property
def called(self):
"""State that the mock was called at least once."""
return self._called > 0

@property
def called_once(self):
"""State that the mock was called exactly once."""
return self._called == 1

def reset_stats(self):
"""Reset the stats counters."""
self._called = 0


class RequestsMock(object):
"""
Mock requests HTTPAdapter.
def request(self, method, url, data=b"", **kwargs): # type: (str, str, bytes, ...) -> None
Example:
def test(requests_mock):
requests_mock.get('https://www.test.com', text="data")
# Now you can run your tests
"""
def __init__(self, mocker):
self.mocker = mocker
self._store = {}

def mock_send(self_mock, request, **_):
urlid = urlquick.hash_url(request)
assert urlid in self._store, "There is no mock response for given method & url"
return self_mock.build_response(request, self._store[urlid].response)

mocker.patch.object(adapters.HTTPAdapter, "send", mock_send)

def request(self, method, url, data=b"", **kwargs): # type: (str, str, bytes, ...) -> MockResponse
req = requests.PreparedRequest()
req.prepare_method(method)
req.prepare_url(url, None)
req.prepare_headers(None)
req.prepare_body(data, None, None)

urlid = urlquick.hash_url(req)
self._store[urlid] = self.build_urllib3_response(**kwargs)
mock_response = MockResponse(**kwargs)
self._store[urlid] = mock_response
return mock_response

def get(self, url, **kwargs): # type: (str, ...) -> MockResponse
return self.request("GET", url, **kwargs)

def options(self, url, **kwargs): # type: (str, ...) -> MockResponse
return self.request("OPTIONS", url, **kwargs)

def head(self, url, **kwargs): # type: (str, ...) -> MockResponse
return self.request("HEAD", url, **kwargs)

def post(self, url, data=None, **kwargs): # type: (...) -> MockResponse
return self.request("POST", url, data, **kwargs)

def put(self, url, data=None, **kwargs): # type: (...) -> MockResponse
return self.request("PUT", url, data, **kwargs)

def patch(self, url, data=None, **kwargs): # type: (...) -> MockResponse
return self.request("PATCH", url, data, **kwargs)

def get(self, url, **kwargs): # type: (str, ...) -> None
self.request("GET", url, **kwargs)
def delete(self, url, **kwargs): # type: (...) -> MockResponse
return self.request("DELETE", url, **kwargs)


@pytest.fixture(scope="function")
Expand Down
10 changes: 10 additions & 0 deletions tests/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,13 @@ def test_hash_url(method, url, body):
urlhash = urlquick.hash_url(req)
assert isinstance(urlhash, str)
assert len(urlhash) == 40


def test_cache_cleanup():
with pytest.deprecated_call():
urlquick.cache_cleanup()


def test_auto_cache_cleanup():
with pytest.deprecated_call():
urlquick.auto_cache_cleanup()
46 changes: 46 additions & 0 deletions tests/test_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import urlquick
import pytest
import shutil


@pytest.fixture(autouse=True, scope="module")
def clear_cache():
shutil.rmtree(urlquick.CACHE_LOCATION, ignore_errors=True)


def test_xml(requests_mock):
xml = b"""
<note>
<to>Tove</to>
<from secure="true">Jani</from>
</note>
"""
requests_mock.get('https://www.test.com/cache/1', body=xml)
ret = urlquick.get('https://www.test.com/cache/1')
assert ret.content == xml
tree = ret.xml()

assert tree.find("to").text == "Tove"
assert tree.find("from").text == "Jani"
assert tree.find("from").get("secure") == "true"


def test_parse(requests_mock):
html = b"""
<html>
<head>
<title>Test title</title>
</head>
<body>
<a href="https://google.ie">google</a>
</body>
</html>
"""
requests_mock.get('https://www.test.com/cache/2', body=html)
ret = urlquick.get('https://www.test.com/cache/2')
assert ret.content == html
tree = ret.parse()

assert tree.find(".//title").text == "Test title"
assert tree.find(".//a").text == "google"
assert tree.find(".//a").get("href") == "https://google.ie"
Loading

0 comments on commit 2910fcc

Please sign in to comment.