summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJordan Cook <jordan.cook@pioneer.com>2022-03-19 16:49:27 -0500
committerJordan Cook <jordan.cook@pioneer.com>2022-03-29 12:17:43 -0500
commit2578cde2692714f1d74fcc20b47fd68d81295b51 (patch)
treeca2b41d3c171394eac0cf2ea009d19182193c9ce /tests
parentb3646b03bc05f5b05f4384eb9a2b4796fa59cb34 (diff)
downloadrequests-cache-2578cde2692714f1d74fcc20b47fd68d81295b51.tar.gz
Fix some regression bugs and broken tests
Diffstat (limited to 'tests')
-rw-r--r--tests/conftest.py16
-rw-r--r--tests/integration/base_cache_test.py2
-rw-r--r--tests/unit/test_cache_control.py20
-rw-r--r--tests/unit/test_session.py72
4 files changed, 63 insertions, 47 deletions
diff --git a/tests/conftest.py b/tests/conftest.py
index aa2cb33..a21b3fc 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -13,6 +13,7 @@ from datetime import datetime, timedelta
from functools import wraps
from logging import basicConfig, getLogger
from os.path import abspath, dirname, join
+from unittest.mock import MagicMock
from uuid import uuid4
import pytest
@@ -213,6 +214,21 @@ def get_mock_adapter() -> Adapter:
return adapter
+def get_mock_response(
+ method='GET',
+ url='https://img.site.com/base/img.jpg',
+ status_code=200,
+ headers={},
+ request_headers={},
+):
+ return MagicMock(
+ url=url,
+ status_code=status_code,
+ headers=headers,
+ request=MagicMock(method=method, url=url, headers=request_headers),
+ )
+
+
def fail_if_no_connection(connect_timeout: float = 1.0) -> bool:
"""Decorator for testing a backend connection. This will intentionally cause a test failure if
the wrapped function doesn't have dependencies installed, doesn't connect after a short timeout,
diff --git a/tests/integration/base_cache_test.py b/tests/integration/base_cache_test.py
index 1fe4253..e0a2d06 100644
--- a/tests/integration/base_cache_test.py
+++ b/tests/integration/base_cache_test.py
@@ -359,7 +359,7 @@ class BaseCacheTest:
session_factory = partial(self.init_session, clear=False)
request_func = partial(_send_request, session_factory, url)
- with ProcessPoolExecutor(max_workers=N_WORKERS) as executor:
+ with executor_class(max_workers=N_WORKERS) as executor:
_ = list(executor.map(request_func, range(N_REQUESTS_PER_ITERATION)))
# Some logging for debug purposes
diff --git a/tests/unit/test_cache_control.py b/tests/unit/test_cache_control.py
index 1d9f417..ac9342a 100644
--- a/tests/unit/test_cache_control.py
+++ b/tests/unit/test_cache_control.py
@@ -6,7 +6,7 @@ from requests import PreparedRequest
from requests_cache.cache_control import DO_NOT_CACHE, CacheActions
from requests_cache.models import CachedResponse, CacheSettings, RequestSettings
-from tests.conftest import ETAG, HTTPDATE_STR, LAST_MODIFIED
+from tests.conftest import ETAG, HTTPDATE_STR, LAST_MODIFIED, get_mock_response
IGNORED_DIRECTIVES = [
'no-transform',
@@ -47,7 +47,7 @@ def test_init(
actions = CacheActions.from_request(
cache_key='key',
request=request,
- settings=RequestSettings(settings, expire_after=request_expire_after),
+ settings=settings,
)
assert actions.expire_after == expected_expiration
@@ -135,13 +135,10 @@ def test_init_from_settings_and_headers(
"""Test behavior with both cache settings and request headers. The only variation in behavior
with cache_control=True is that expire_after=0 should *not* cause the cache read to be skipped.
"""
- request = MagicMock(
- url='https://img.site.com/base/img.jpg',
- headers=headers,
- )
-
+ request = get_mock_response(headers=headers)
settings = CacheSettings(cache_control=cache_control, expire_after=expire_after)
actions = CacheActions.from_request('key', request, RequestSettings(settings))
+
assert actions.expire_after == expected_expiration
assert actions.skip_read == expected_skip_read
@@ -235,7 +232,7 @@ def test_update_from_response(headers, expected_expiration):
actions = CacheActions.from_request(
'key', MagicMock(url=url), RequestSettings(cache_control=True)
)
- actions.update_from_response(MagicMock(url=url, headers=headers))
+ actions.update_from_response(get_mock_response(headers=headers))
if expected_expiration == DO_NOT_CACHE:
assert not actions.expire_after # May be either 0 or None
@@ -250,7 +247,7 @@ def test_update_from_response__ignored():
actions = CacheActions.from_request(
'key', MagicMock(url=url), RequestSettings(cache_control=False)
)
- actions.update_from_response(MagicMock(url=url, headers={'Cache-Control': 'max-age=5'}))
+ actions.update_from_response(get_mock_response(headers={'Cache-Control': 'max-age=5'}))
assert actions.expire_after is None
@@ -262,11 +259,12 @@ def test_update_from_response__revalidate(mock_datetime, cache_headers, validato
expiration
"""
url = 'https://img.site.com/base/img.jpg'
- headers = {**cache_headers, **validator_headers}
actions = CacheActions.from_request(
'key', MagicMock(url=url), RequestSettings(cache_control=True)
)
- actions.update_from_response(MagicMock(url=url, headers=headers))
+ response = get_mock_response(headers={**cache_headers, **validator_headers})
+ actions.update_from_response(response)
+
assert actions.expires == mock_datetime.utcnow()
assert actions.skip_write is False
diff --git a/tests/unit/test_session.py b/tests/unit/test_session.py
index 86d10cb..9fe1dac 100644
--- a/tests/unit/test_session.py
+++ b/tests/unit/test_session.py
@@ -52,8 +52,8 @@ def test_init_backend_instance__kwargs():
)
assert session.cache.cache_name == 'test_cache'
- assert session.cache.settings.ignored_parameters == ['foo']
- assert session.cache.settings.match_headers is True
+ assert session.settings.ignored_parameters == ['foo']
+ assert session.settings.match_headers is True
def test_init_backend_class():
@@ -81,18 +81,20 @@ def test_init_missing_backend_dependency():
def test_repr(mock_session):
"""Test session and cache string representations"""
- mock_session.expire_after = 11
+ mock_session.settings.expire_after = 11
mock_session.cache.responses['key'] = 'value'
mock_session.cache.redirects['key'] = 'value'
mock_session.cache.redirects['key_2'] = 'value'
- assert mock_session.cache.cache_name in repr(mock_session) and '11' in repr(mock_session)
- assert '2 redirects' in str(mock_session.cache) and '1 responses' in str(mock_session.cache)
+ assert mock_session.cache.cache_name in repr(mock_session)
+ assert '11' in repr(mock_session)
+ assert '2 redirects' in str(mock_session.cache)
+ assert '1 responses' in str(mock_session.cache)
def test_response_defaults(mock_session):
"""Both cached and new responses should always have the following attributes"""
- mock_session.expire_after = datetime.utcnow() + timedelta(days=1)
+ mock_session.settings.expire_after = datetime.utcnow() + timedelta(days=1)
response_1 = mock_session.get(MOCKED_URL)
response_2 = mock_session.get(MOCKED_URL)
response_3 = mock_session.get(MOCKED_URL)
@@ -134,8 +136,8 @@ def test_all_methods__ignored_parameters__not_matched(field, method, mock_sessio
"""Test all relevant combinations of methods and data fields. Requests with different request
params, data, or json should not be cached under different keys based on an ignored param.
"""
- mock_session.cache.settings.ignored_parameters = ['ignored']
- mock_session.cache.settings.match_headers = True
+ mock_session.settings.ignored_parameters = ['ignored']
+ mock_session.settings.match_headers = True
params_1 = {'ignored': 'value_1', 'not_ignored': 'value_1'}
params_2 = {'ignored': 'value_2', 'not_ignored': 'value_1'}
params_3 = {'ignored': 'value_2', 'not_ignored': 'value_2'}
@@ -153,7 +155,7 @@ def test_all_methods__ignored_parameters__redacted(field, method, mock_session):
"""Test all relevant combinations of methods and data fields. Requests with ignored params
should have those values redacted from the cached response.
"""
- mock_session.cache.settings.ignored_parameters = ['access_token']
+ mock_session.settings.ignored_parameters = ['access_token']
params_1 = {'access_token': 'asdf', 'not_ignored': 'value_1'}
mock_session.request(method, MOCKED_URL, **{field: params_1})
@@ -296,7 +298,7 @@ def test_normalize_params__url(mock_session):
def test_match_headers(mock_session):
"""With match_headers, requests with different headers should have different cache keys"""
- mock_session.cache.settings.match_headers = True
+ mock_session.settings.match_headers = True
headers_list = [
{'Accept': 'application/json'},
{'Accept': 'text/xml'},
@@ -310,7 +312,7 @@ def test_match_headers(mock_session):
def test_match_headers__normalize(mock_session):
"""With match_headers, the same headers (in any order) should have the same cache key"""
- mock_session.cache.settings.match_headers = True
+ mock_session.settings.match_headers = True
headers = {'Accept': 'application/json', 'Custom': 'abc'}
reversed_headers = {'Custom': 'abc', 'Accept': 'application/json'}
assert mock_session.get(MOCKED_URL, headers=headers).from_cache is False
@@ -319,7 +321,7 @@ def test_match_headers__normalize(mock_session):
def test_match_headers__list(mock_session):
"""match_headers can optionally be a list of specific headers to include"""
- mock_session.cache.settings.match_headers = ['Accept']
+ mock_session.settings.match_headers = ['Accept']
headers_1 = {'Accept': 'application/json', 'User-Agent': 'qutebrowser'}
headers_2 = {'Accept': 'application/json', 'User-Agent': 'Firefox'}
headers_3 = {'Accept': 'text/plain', 'User-Agent': 'qutebrowser'}
@@ -333,7 +335,7 @@ def test_match_headers__list(mock_session):
def test_include_get_headers():
"""include_get_headers is aliased to match_headers for backwards-compatibility"""
session = CachedSession(include_get_headers=True, backend='memory')
- assert session.cache.settings.match_headers is True
+ assert session.settings.match_headers is True
# Error handling
@@ -351,8 +353,8 @@ def test_cache_error(exception_cls, mock_session):
def test_expired_request_error(mock_session):
"""Without stale_if_error (default), if there is an error while re-fetching an expired
response, the request should be re-raised and the expired item deleted"""
- mock_session.cache.settings.stale_if_error = False
- mock_session.cache.settings.expire_after = 1
+ mock_session.settings.stale_if_error = False
+ mock_session.settings.expire_after = 1
mock_session.get(MOCKED_URL)
time.sleep(1)
@@ -364,8 +366,8 @@ def test_expired_request_error(mock_session):
def test_stale_if_error__exception(mock_session):
"""With stale_if_error, expect to get old cache data if there is an exception during a request"""
- mock_session.cache.settings.stale_if_error = True
- mock_session.cache.settings.expire_after = 1
+ mock_session.settings.stale_if_error = True
+ mock_session.settings.expire_after = 1
assert mock_session.get(MOCKED_URL).from_cache is False
assert mock_session.get(MOCKED_URL).from_cache is True
@@ -377,9 +379,9 @@ def test_stale_if_error__exception(mock_session):
def test_stale_if_error__error_code(mock_session):
"""With stale_if_error, expect to get old cache data if a response has an error status code"""
- mock_session.cache.settings.stale_if_error = True
- mock_session.cache.settings.expire_after = 1
- mock_session.cache.settings.allowable_codes = (200, 404)
+ mock_session.settings.stale_if_error = True
+ mock_session.settings.expire_after = 1
+ mock_session.settings.allowable_codes = (200, 404)
assert mock_session.get(MOCKED_URL_404).from_cache is False
@@ -391,7 +393,7 @@ def test_stale_if_error__error_code(mock_session):
def test_old_data_on_error():
"""stale_if_error is aliased to old_data_on_error for backwards-compatibility"""
session = CachedSession(old_data_on_error=True, backend='memory')
- assert session.cache.settings.stale_if_error is True
+ assert session.settings.stale_if_error is True
def test_cache_disabled(mock_session):
@@ -431,7 +433,7 @@ def test_unpickle_errors(mock_session):
def test_filter_fn(mock_session):
- mock_session.cache.settings.filter_fn = lambda r: r.request.url != MOCKED_URL_JSON
+ mock_session.settings.filter_fn = lambda r: r.request.url != MOCKED_URL_JSON
mock_session.get(MOCKED_URL)
mock_session.get(MOCKED_URL_JSON)
@@ -442,7 +444,7 @@ def test_filter_fn(mock_session):
def test_filter_fn__retroactive(mock_session):
"""filter_fn should also apply to previously cached responses"""
mock_session.get(MOCKED_URL_JSON)
- mock_session.cache.settings.filter_fn = lambda r: r.request.url != MOCKED_URL_JSON
+ mock_session.settings.filter_fn = lambda r: r.request.url != MOCKED_URL_JSON
mock_session.get(MOCKED_URL_JSON)
assert not mock_session.cache.has_url(MOCKED_URL_JSON)
@@ -453,7 +455,7 @@ def test_key_fn(mock_session):
"""Create a key based on only the request URL (without params)"""
return request.url.split('?')[0]
- mock_session.cache.settings.key_fn = create_key
+ mock_session.settings.key_fn = create_key
mock_session.get(MOCKED_URL)
response = mock_session.get(MOCKED_URL, params={'k': 'v'})
assert response.from_cache is True
@@ -477,13 +479,13 @@ def test_hooks(mock_session):
def test_do_not_cache(mock_session):
"""expire_after=0 should bypass the cache on both read and write"""
- # Bypass read
+ # Skip read
mock_session.get(MOCKED_URL)
assert mock_session.cache.has_url(MOCKED_URL)
assert mock_session.get(MOCKED_URL, expire_after=0).from_cache is False
- # Bypass write
- mock_session.expire_after = 0
+ # Skip write
+ mock_session.settings.expire_after = 0
mock_session.get(MOCKED_URL_JSON)
assert not mock_session.cache.has_url(MOCKED_URL_JSON)
@@ -506,7 +508,7 @@ def test_304_not_modified(
):
url = f'{MOCKED_URL}/endpoint_2'
if cache_expired:
- mock_session.expire_after = datetime.now() - timedelta(1)
+ mock_session.settings.expire_after = datetime.now() - timedelta(1)
if cache_hit:
mock_session.mock_adapter.register_uri('GET', url, status_code=200)
mock_session.get(url)
@@ -518,7 +520,7 @@ def test_304_not_modified(
def test_url_allowlist(mock_session):
"""If the default is 0, only URLs matching patterns in urls_expire_after should be cached"""
- mock_session.urls_expire_after = {
+ mock_session.settings.urls_expire_after = {
MOCKED_URL_JSON: 60,
'*': 0,
}
@@ -533,7 +535,7 @@ def test_remove_expired_responses(mock_session):
mock_session.mock_adapter.register_uri(
'GET', unexpired_url, status_code=200, text='mock response'
)
- mock_session.expire_after = 1
+ mock_session.settings.expire_after = 1
mock_session.get(MOCKED_URL)
mock_session.get(MOCKED_URL_JSON)
time.sleep(1)
@@ -571,7 +573,7 @@ def test_remove_expired_responses__error(mock_session):
def test_remove_expired_responses__extend_expiration(mock_session):
# Start with an expired response
- mock_session.expire_after = datetime.utcnow() - timedelta(seconds=0.01)
+ mock_session.settings.expire_after = datetime.utcnow() - timedelta(seconds=0.01)
mock_session.get(MOCKED_URL)
# Set expiration in the future
@@ -583,7 +585,7 @@ def test_remove_expired_responses__extend_expiration(mock_session):
def test_remove_expired_responses__shorten_expiration(mock_session):
# Start with a non-expired response
- mock_session.expire_after = datetime.utcnow() + timedelta(seconds=1)
+ mock_session.settings.expire_after = datetime.utcnow() + timedelta(seconds=1)
mock_session.get(MOCKED_URL)
# Set expiration in the past
@@ -624,7 +626,7 @@ def test_remove_expired_responses__per_request(mock_session):
def test_request_expire_after__enable_expiration(mock_session):
"""No per-session expiration is set, but then overridden for a single request"""
- mock_session.expire_after = None
+ mock_session.settings.expire_after = None
response = mock_session.get(MOCKED_URL, expire_after=1)
assert response.from_cache is False
assert mock_session.get(MOCKED_URL).from_cache is True
@@ -636,7 +638,7 @@ def test_request_expire_after__enable_expiration(mock_session):
def test_request_expire_after__disable_expiration(mock_session):
"""A per-session expiration is set, but then disabled for a single request"""
- mock_session.expire_after = 60
+ mock_session.settings.expire_after = 60
response = mock_session.get(MOCKED_URL, expire_after=-1)
response = mock_session.get(MOCKED_URL, expire_after=-1)
assert response.from_cache is True
@@ -645,7 +647,7 @@ def test_request_expire_after__disable_expiration(mock_session):
def test_request_expire_after__prepared_request(mock_session):
"""Pre-request expiration should also work for PreparedRequests with CachedSession.send()"""
- mock_session.expire_after = None
+ mock_session.settings.expire_after = None
request = Request(method='GET', url=MOCKED_URL, headers={}, data=None).prepare()
response = mock_session.send(request, expire_after=1)
assert response.from_cache is False