1
0
mirror of synced 2026-01-30 07:01:56 -05:00
Files
airbyte/airbyte-cdk/python/unit_tests/test/mock_http/test_mocker.py
2024-05-14 08:06:18 -06:00

243 lines
9.4 KiB
Python

# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
from unittest import TestCase
import pytest
import requests
from airbyte_cdk.test.mock_http import HttpMocker, HttpRequest, HttpResponse
# Ensure that the scheme is HTTP as requests only partially supports other schemes
# see https://github.com/psf/requests/blob/0b4d494192de489701d3a2e32acef8fb5d3f042e/src/requests/models.py#L424-L429
_A_URL = "http://test.com/"
_ANOTHER_URL = "http://another-test.com/"
_A_RESPONSE_BODY = "a body"
_ANOTHER_RESPONSE_BODY = "another body"
_A_RESPONSE = HttpResponse("any response")
_SOME_QUERY_PARAMS = {"q1": "query value"}
_SOME_HEADERS = {"h1": "header value"}
_OTHER_HEADERS = {"h2": "another header value"}
_SOME_REQUEST_BODY_MAPPING = {"first_field": "first_value", "second_field": 2}
_SOME_REQUEST_BODY_STR = "some_request_body"
class HttpMockerTest(TestCase):
@HttpMocker()
def test_given_get_request_match_when_decorate_then_return_response(self, http_mocker):
http_mocker.get(
HttpRequest(_A_URL, _SOME_QUERY_PARAMS, _SOME_HEADERS),
HttpResponse(_A_RESPONSE_BODY, 474, _OTHER_HEADERS),
)
response = requests.get(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS)
assert response.text == _A_RESPONSE_BODY
assert response.status_code == 474
assert response.headers == _OTHER_HEADERS
@HttpMocker()
def test_given_delete_request_match_when_decorate_then_return_response(self, http_mocker):
http_mocker.delete(
HttpRequest(_A_URL, headers=_SOME_HEADERS),
HttpResponse(_A_RESPONSE_BODY, 204, _OTHER_HEADERS),
)
response = requests.delete(_A_URL, headers=_SOME_HEADERS)
assert response.text == _A_RESPONSE_BODY
assert response.status_code == 204
assert response.headers == _OTHER_HEADERS
@HttpMocker()
def test_given_loose_headers_matching_when_decorate_then_match(self, http_mocker):
http_mocker.get(
HttpRequest(_A_URL, _SOME_QUERY_PARAMS, _SOME_HEADERS),
HttpResponse(_A_RESPONSE_BODY, 474),
)
requests.get(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS | {"more strict query param key": "any value"})
@HttpMocker()
def test_given_post_request_match_when_decorate_then_return_response(self, http_mocker):
http_mocker.post(
HttpRequest(_A_URL, _SOME_QUERY_PARAMS, _SOME_HEADERS, _SOME_REQUEST_BODY_STR),
HttpResponse(_A_RESPONSE_BODY, 474),
)
response = requests.post(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS, data=_SOME_REQUEST_BODY_STR)
assert response.text == _A_RESPONSE_BODY
assert response.status_code == 474
@HttpMocker()
def test_given_multiple_responses_when_decorate_get_request_then_return_response(self, http_mocker):
http_mocker.get(
HttpRequest(_A_URL, _SOME_QUERY_PARAMS, _SOME_HEADERS),
[HttpResponse(_A_RESPONSE_BODY, 1), HttpResponse(_ANOTHER_RESPONSE_BODY, 2)],
)
first_response = requests.get(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS)
second_response = requests.get(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS)
assert first_response.text == _A_RESPONSE_BODY
assert first_response.status_code == 1
assert second_response.text == _ANOTHER_RESPONSE_BODY
assert second_response.status_code == 2
@HttpMocker()
def test_given_multiple_responses_when_decorate_delete_request_then_return_response(self, http_mocker):
http_mocker.delete(
HttpRequest(_A_URL, headers=_SOME_HEADERS),
[HttpResponse(_A_RESPONSE_BODY, 1), HttpResponse(_ANOTHER_RESPONSE_BODY, 2)],
)
first_response = requests.delete(_A_URL, headers=_SOME_HEADERS)
second_response = requests.delete(_A_URL, headers=_SOME_HEADERS)
assert first_response.text == _A_RESPONSE_BODY
assert first_response.status_code == 1
assert second_response.text == _ANOTHER_RESPONSE_BODY
assert second_response.status_code == 2
@HttpMocker()
def test_given_multiple_responses_when_decorate_post_request_then_return_response(self, http_mocker):
http_mocker.post(
HttpRequest(_A_URL, _SOME_QUERY_PARAMS, _SOME_HEADERS, _SOME_REQUEST_BODY_STR),
[HttpResponse(_A_RESPONSE_BODY, 1), HttpResponse(_ANOTHER_RESPONSE_BODY, 2)],
)
first_response = requests.post(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS, data=_SOME_REQUEST_BODY_STR)
second_response = requests.post(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS, data=_SOME_REQUEST_BODY_STR)
assert first_response.text == _A_RESPONSE_BODY
assert first_response.status_code == 1
assert second_response.text == _ANOTHER_RESPONSE_BODY
assert second_response.status_code == 2
@HttpMocker()
def test_given_more_requests_than_responses_when_decorate_then_raise_error(self, http_mocker):
http_mocker.get(
HttpRequest(_A_URL, _SOME_QUERY_PARAMS, _SOME_HEADERS),
[HttpResponse(_A_RESPONSE_BODY, 1), HttpResponse(_ANOTHER_RESPONSE_BODY, 2)],
)
last_response = [requests.get(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS) for _ in range(10)][-1]
assert last_response.text == _ANOTHER_RESPONSE_BODY
assert last_response.status_code == 2
@HttpMocker()
def test_given_all_requests_match_when_decorate_then_do_not_raise(self, http_mocker):
http_mocker.get(
HttpRequest(_A_URL, _SOME_QUERY_PARAMS, _SOME_HEADERS),
_A_RESPONSE,
)
requests.get(_A_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS)
def test_given_missing_requests_when_decorate_then_raise(self):
@HttpMocker()
def decorated_function(http_mocker):
http_mocker.get(
HttpRequest(_A_URL),
_A_RESPONSE,
)
with pytest.raises(ValueError) as exc_info:
decorated_function()
assert "Invalid number of matches" in str(exc_info.value)
def test_given_assertion_error_when_decorate_then_raise_assertion_error(self):
@HttpMocker()
def decorated_function(http_mocker):
http_mocker.get(
HttpRequest(_A_URL),
_A_RESPONSE,
)
requests.get(_A_URL)
assert False
with pytest.raises(AssertionError):
decorated_function()
def test_given_assertion_error_but_missing_request_when_decorate_then_raise_missing_http_request(self):
@HttpMocker()
def decorated_function(http_mocker):
http_mocker.get(
HttpRequest(_A_URL),
_A_RESPONSE,
)
assert False
with pytest.raises(ValueError) as exc_info:
decorated_function()
assert "Invalid number of matches" in str(exc_info.value)
def test_given_request_does_not_match_when_decorate_then_raise(self):
@HttpMocker()
def decorated_function(http_mocker):
http_mocker.get(
HttpRequest(_A_URL),
_A_RESPONSE,
)
requests.get(_ANOTHER_URL, params=_SOME_QUERY_PARAMS, headers=_SOME_HEADERS)
with pytest.raises(ValueError) as exc_info:
decorated_function()
assert "No matcher matches" in str(exc_info.value)
def test_given_request_matches_multiple_matchers_when_decorate_then_match_first_one(self):
less_granular_headers = {"less_granular": "1"}
more_granular_headers = {"more_granular": "2"} | less_granular_headers
@HttpMocker()
def decorated_function(http_mocker):
http_mocker.get(
HttpRequest(_A_URL, headers=more_granular_headers),
_A_RESPONSE,
)
http_mocker.get(
HttpRequest(_A_URL, headers=less_granular_headers),
_A_RESPONSE,
)
requests.get(_A_URL, headers=more_granular_headers)
with pytest.raises(ValueError) as exc_info:
decorated_function()
assert "more_granular" in str(exc_info.value) # the matcher corresponding to the first `http_mocker.get` is not matched
def test_given_exact_number_of_call_provided_when_assert_number_of_calls_then_do_not_raise(self):
@HttpMocker()
def decorated_function(http_mocker):
request = HttpRequest(_A_URL)
http_mocker.get(request, _A_RESPONSE)
requests.get(_A_URL)
requests.get(_A_URL)
http_mocker.assert_number_of_calls(request, 2)
decorated_function()
# then do not raise
def test_given_invalid_number_of_call_provided_when_assert_number_of_calls_then_raise(self):
@HttpMocker()
def decorated_function(http_mocker):
request = HttpRequest(_A_URL)
http_mocker.get(request, _A_RESPONSE)
requests.get(_A_URL)
requests.get(_A_URL)
http_mocker.assert_number_of_calls(request, 1)
with pytest.raises(AssertionError):
decorated_function()
def test_given_unknown_request_when_assert_number_of_calls_then_raise(self):
@HttpMocker()
def decorated_function(http_mocker):
http_mocker.get(HttpRequest(_A_URL), _A_RESPONSE)
http_mocker.assert_number_of_calls(HttpRequest(_ANOTHER_URL), 1)
with pytest.raises(ValueError):
decorated_function()