Skip to content

Commit

Permalink
have response state if response is from the cache
Browse files Browse the repository at this point in the history
  • Loading branch information
willforde committed Feb 27, 2021
1 parent 3b39871 commit 1d4914f
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
42 changes: 41 additions & 1 deletion tests/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import requests
import shutil
import pytest
import sqlite3
import time


Expand All @@ -19,19 +18,22 @@ def test_get(self, obj, requests_mock):
mocked = requests_mock.get('https://www.test.com/test/586', body=b"data")
ret = obj.get('https://www.test.com/test/586')
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"data"
assert ret.text == "data"

def test_options(self, obj, requests_mock):
mocked = requests_mock.options('https://www.test.com', json={"test": True})
ret = obj.options('https://www.test.com')
assert mocked.called
assert ret.from_cache is False
assert ret.json() == {"test": True}

def test_head(self, obj, requests_mock):
mocked = requests_mock.head('https://www.test.com', headers={"X-TEST": "12345"})
ret = obj.head('https://www.test.com')
assert mocked.called
assert ret.from_cache is False
assert ret.content == b""
assert ret.text == ""
assert "X-TEST" in ret.headers and ret.headers["X-TEST"] == "12345"
Expand All @@ -40,30 +42,35 @@ def test_post(self, obj, requests_mock):
mocked = requests_mock.post('https://www.test.com', json={"test": True}, data=b"test")
ret = obj.post('https://www.test.com', data=b"test")
assert mocked.called
assert ret.from_cache is False
assert ret.json() == {"test": True}

def test_put(self, obj, requests_mock):
mocked = requests_mock.put('https://www.test.com', json={"test": True})
ret = obj.put('https://www.test.com')
assert mocked.called
assert ret.from_cache is False
assert ret.json() == {"test": True}

def test_patch(self, obj, requests_mock):
mocked = requests_mock.patch('https://www.test.com', json={"test": True})
ret = obj.patch('https://www.test.com')
assert mocked.called
assert ret.from_cache is False
assert ret.json() == {"test": True}

def test_delete(self, obj, requests_mock):
mocked = requests_mock.delete('https://www.test.com', json={"test": True})
ret = obj.delete('https://www.test.com')
assert mocked.called
assert ret.from_cache is False
assert ret.json() == {"test": True}

def test_headers_none(self, obj, requests_mock):
mocked = requests_mock.get('https://www.test.com/50', json={"test": True})
ret = obj.get('https://www.test.com/50', headers=None)
assert mocked.called
assert ret.from_cache is False
assert ret.json() == {"test": True}


Expand All @@ -79,67 +86,79 @@ def test_cache(self, requests_mock):
mocked = requests_mock.get('https://www.test.com/1', body=b"data")
ret = urlquick.get('https://www.test.com/1')
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"data"
mocked.reset_stats()

ret = urlquick.get('https://www.test.com/1')
assert not mocked.called
assert ret.from_cache is True
assert ret.content == b"data"

def test_delay(self, requests_mock):
mocked = requests_mock.get('https://www.test.com/1', body=b"data")
ret = urlquick.get('https://www.test.com/1')
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"data"
mocked.reset_stats()

time.sleep(1.2) # 1.2 seconds should be enough
ret = urlquick.get('https://www.test.com/1', max_age=1)
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"data"

def test_disable_flag(self, requests_mock):
mocked = requests_mock.get('https://www.test.com/1', body=b"data")
ret = urlquick.get('https://www.test.com/1')
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"data"
mocked.reset_stats()

ret = urlquick.get('https://www.test.com/1', max_age=-1)
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"data"

def test_never_valid(self, requests_mock):
mocked = requests_mock.get('https://www.test.com/1', body=b"data")
ret = urlquick.get('https://www.test.com/1')
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"data"
mocked.reset_stats()

ret = urlquick.get('https://www.test.com/1', max_age=0)
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"data"

def test_etag(self, requests_mock):
mocked = requests_mock.get('https://www.test.com/1', body=b"data", headers={"Etag": "12345"})
ret = urlquick.get('https://www.test.com/1')
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"data"
mocked.reset_stats()

ret = urlquick.get('https://www.test.com/1', max_age=0)
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"data"

def test_last_modified(self, requests_mock):
mocked = requests_mock.get('https://www.test.com/1', body=b"test 304", headers={"Last-modified": "12345"})
ret = urlquick.get('https://www.test.com/1') # Gets cached
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"test 304"

mocked = requests_mock.get('https://www.test.com/1', headers={"Last-modified": "12345"}, status=304)
ret = urlquick.get('https://www.test.com/1', max_age=0)
assert mocked.called
assert ret.from_cache is True
assert ret.content == b"test 304"

def test_wipe(self, requests_mock):
Expand All @@ -148,6 +167,7 @@ def test_wipe(self, requests_mock):

ret = session.get('https://www.test.com/1')
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"data"
mocked.reset_stats()

Expand All @@ -156,6 +176,7 @@ def test_wipe(self, requests_mock):

ret = session.get('https://www.test.com/1')
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"data"

def test_delete(self, requests_mock):
Expand All @@ -165,6 +186,7 @@ def test_delete(self, requests_mock):

ret = session.get('https://www.test.com/1')
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"data"
mocked.reset_stats()

Expand All @@ -181,6 +203,7 @@ def test_delete(self, requests_mock):

ret = session.get('https://www.test.com/1')
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"data"


Expand All @@ -198,6 +221,7 @@ def test_false_normal(self, requests_mock):

ret = session.get('https://www.test.com/1')
assert mocked.called
assert ret.from_cache is False
assert ret.status_code == 200
assert ret.content == b"data"

Expand All @@ -207,6 +231,7 @@ def test_false_error(self, requests_mock):

ret = session.get('https://www.test.com/1')
assert mocked.called
assert ret.from_cache is False
assert ret.status_code == 404
assert ret.content == b"data"

Expand All @@ -216,6 +241,7 @@ def test_true_normal(self, requests_mock):

ret = session.get('https://www.test.com/1')
assert mocked.called
assert ret.from_cache is False
assert ret.status_code == 200
assert ret.content == b"data"

Expand Down Expand Up @@ -265,6 +291,7 @@ def test_request_header_data(requests_mock):

ret = session.request("GET", 'https://www.test.com/test/542', None, None, {"X-TEST": "test"})
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"data"


Expand All @@ -274,6 +301,7 @@ def test_session_method(requests_mock):
session = urlquick.session()
ret = session.get('https://www.test.com')
assert mocked.called
assert ret.from_cache is False
assert ret.content == b"data"
assert ret.text == "data"

Expand All @@ -288,20 +316,24 @@ def test_cache_unsupported_protocol(mocker, requests_mock):
# Check that the mocked url is called
ret = session.get('https://www.test.com/1')
assert mocked_url_1.called
assert ret.from_cache is False
assert ret.content == b"test1"
mocked_url_1.reset_stats()
ret = session.get('https://www.test.com/2')
assert mocked_url_2.called
assert ret.from_cache is False
assert ret.content == b"test2"
mocked_url_2.reset_stats()

# Should be cached now so mocked should not be called
ret = session.get('https://www.test.com/1')
assert not mocked_url_1.called
assert ret.from_cache is True
assert ret.content == b"test1"
mocked_url_1.reset_stats()
ret = session.get('https://www.test.com/2')
assert not mocked_url_2.called
assert ret.from_cache is True
assert ret.content == b"test2"
mocked_url_2.reset_stats()

Expand All @@ -312,11 +344,13 @@ def test_cache_unsupported_protocol(mocker, requests_mock):
# For a unsupported pickle protocol the whole cache is wiped so both should be called
ret = session.get('https://www.test.com/1')
assert mocked_url_1.called
assert ret.from_cache is False
assert ret.content == b"test1"
mocked.stopall()
# This should be called again
ret = session.get('https://www.test.com/2')
assert mocked_url_2.called
assert ret.from_cache is False
assert ret.content == b"test2"


Expand All @@ -330,20 +364,24 @@ def test_cache_unknown_error(mocker, requests_mock):
# Check that the mocked url is called
ret = session.get('https://www.test.com/1')
assert mocked_url_1.called
assert ret.from_cache is False
assert ret.content == b"test1"
mocked_url_1.reset_stats()
ret = session.get('https://www.test.com/2')
assert mocked_url_2.called
assert ret.from_cache is False
assert ret.content == b"test2"
mocked_url_2.reset_stats()

# Should be cached now so mocked should not be called
ret = session.get('https://www.test.com/1')
assert not mocked_url_1.called
assert ret.from_cache is True
assert ret.content == b"test1"
mocked_url_1.reset_stats()
ret = session.get('https://www.test.com/2')
assert not mocked_url_2.called
assert ret.from_cache is True
assert ret.content == b"test2"
mocked_url_2.reset_stats()

Expand All @@ -355,10 +393,12 @@ def test_cache_unknown_error(mocker, requests_mock):
# will be remove but all the rest will stay
ret = session.get('https://www.test.com/1')
assert mocked_url_1.called
assert ret.from_cache is False
assert ret.content == b"test1"
mocker.stopall()

# This request should not be called again
ret = session.get('https://www.test.com/2')
assert not mocked_url_2.called
assert ret.from_cache is True
assert ret.content == b"test2"
5 changes: 5 additions & 0 deletions urlquick.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ class CacheError(RequestException):


class Response(requests.Response):
def __init__(self):
super(Response, self).__init__()
self.from_cache = False

def xml(self):
"""
Parse's "XML" document into a element tree.
Expand Down Expand Up @@ -209,6 +213,7 @@ class CacheRecord(object):
def __init__(self, record): # type: (sqlite3.Row) -> None
self._response = response = pickle.loads(bytes(record["response"]))
self._fresh = record["fresh"] or response.status_code in REDIRECT_CODES
self._response.from_cache = True

@property
def response(self): # type: () -> Response
Expand Down

0 comments on commit 1d4914f

Please sign in to comment.