"""Example of using requests-cache with the responses library"""
from contextlib import contextmanager
from os.path import dirname, join
from unittest.mock import patch

import pytest
import requests
from requests.exceptions import ConnectionError
from responses import RequestsMock, Response

from requests_cache import CachedSession

TEST_DB = join(dirname(__file__), 'httpbin_sample.test-db')
TEST_URLS = [
    'https://httpbin.org/get',
    'https://httpbin.org/html',
    'https://httpbin.org/json',
]
PASSTHRU_URL = 'https://httpbin.org/gzip'
UNMOCKED_URL = 'https://httpbin.org/ip'


@contextmanager
def get_responses():
    """Contextmanager that provides a RequestsMock object mocked URLs and responses
    based on cache data
    """
    with RequestsMock() as mocker:
        cache = CachedSession(TEST_DB).cache
        for response in cache.responses.values():
            mocker.add(
                Response(
                    response.request.method,
                    response.request.url,
                    body=response.content,
                    headers=response.headers,
                    status=response.status_code,
                )
            )
        mocker.add_passthru(PASSTHRU_URL)
        yield mocker


# responses patches HTTPAdapter.send(), so we need to patch one level lower to verify request mocking
@patch.object(
    requests.adapters.HTTPAdapter, 'get_connection', side_effect=ValueError('Real request made!')
)
def test_mock_session(mock_http_adapter):
    """Test that the mock_session fixture is working as expected"""
    with get_responses():
        # An error will be raised if a real request is made
        with pytest.raises(ValueError):
            requests.get(PASSTHRU_URL)

        # All mocked URLs will return a response based on requests-cache data
        for url in TEST_URLS:
            response = requests.get(url)
            assert getattr(response, 'from_cache', False) is False

        # responses will raise an error for an unmocked URL, as usual
        with pytest.raises(ConnectionError):
            requests.get(UNMOCKED_URL)
