253 lines
8.8 KiB
Python
253 lines
8.8 KiB
Python
#
|
|
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
|
#
|
|
|
|
import pytest
|
|
import requests
|
|
from airbyte_cdk.sources.http_logger import format_http_message
|
|
|
|
A_TITLE = "a title"
|
|
A_DESCRIPTION = "a description"
|
|
A_STREAM_NAME = "a stream name"
|
|
ANY_REQUEST = requests.Request(method="POST", url="http://a-url.com", headers={}, params={}).prepare()
|
|
|
|
|
|
class ResponseBuilder:
|
|
def __init__(self):
|
|
self._body_content = ""
|
|
self._headers = {}
|
|
self._request = ANY_REQUEST
|
|
self._status_code = 100
|
|
|
|
def body_content(self, body_content: bytes) -> "ResponseBuilder":
|
|
self._body_content = body_content
|
|
return self
|
|
|
|
def headers(self, headers: dict) -> "ResponseBuilder":
|
|
self._headers = headers
|
|
return self
|
|
|
|
def request(self, request: requests.PreparedRequest) -> "ResponseBuilder":
|
|
self._request = request
|
|
return self
|
|
|
|
def status_code(self, status_code: int) -> "ResponseBuilder":
|
|
self._status_code = status_code
|
|
return self
|
|
|
|
def build(self):
|
|
response = requests.Response()
|
|
response._content = self._body_content
|
|
response.headers = self._headers
|
|
response.request = self._request
|
|
response.status_code = self._status_code
|
|
return response
|
|
|
|
|
|
EMPTY_RESPONSE = {"body": {"content": ""}, "headers": {}, "status_code": 100}
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"test_name, http_method, url, headers, params, body_json, body_data, expected_airbyte_message",
|
|
[
|
|
(
|
|
"test_basic_get_request",
|
|
"GET",
|
|
"https://airbyte.io",
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{
|
|
"airbyte_cdk": {"stream": {"name": A_STREAM_NAME}},
|
|
"http": {
|
|
"title": A_TITLE,
|
|
"description": A_DESCRIPTION,
|
|
"request": {"method": "GET", "body": {"content": None}, "headers": {}},
|
|
"response": EMPTY_RESPONSE,
|
|
},
|
|
"log": {"level": "debug"},
|
|
"url": {"full": "https://airbyte.io/"},
|
|
},
|
|
),
|
|
(
|
|
"test_get_request_with_headers",
|
|
"GET",
|
|
"https://airbyte.io",
|
|
{"h1": "v1", "h2": "v2"},
|
|
{},
|
|
{},
|
|
{},
|
|
{
|
|
"airbyte_cdk": {"stream": {"name": A_STREAM_NAME}},
|
|
"http": {
|
|
"title": A_TITLE,
|
|
"description": A_DESCRIPTION,
|
|
"request": {"method": "GET", "body": {"content": None}, "headers": {"h1": "v1", "h2": "v2"}},
|
|
"response": EMPTY_RESPONSE,
|
|
},
|
|
"log": {"level": "debug"},
|
|
"url": {"full": "https://airbyte.io/"},
|
|
},
|
|
),
|
|
(
|
|
"test_get_request_with_request_params",
|
|
"GET",
|
|
"https://airbyte.io",
|
|
{},
|
|
{"p1": "v1", "p2": "v2"},
|
|
{},
|
|
{},
|
|
{
|
|
"airbyte_cdk": {"stream": {"name": A_STREAM_NAME}},
|
|
"http": {
|
|
"title": A_TITLE,
|
|
"description": A_DESCRIPTION,
|
|
"request": {"method": "GET", "body": {"content": None}, "headers": {}},
|
|
"response": EMPTY_RESPONSE,
|
|
},
|
|
"log": {"level": "debug"},
|
|
"url": {"full": "https://airbyte.io/?p1=v1&p2=v2"},
|
|
},
|
|
),
|
|
(
|
|
"test_get_request_with_request_body_json",
|
|
"GET",
|
|
"https://airbyte.io",
|
|
{"Content-Type": "application/json"},
|
|
{},
|
|
{"b1": "v1", "b2": "v2"},
|
|
{},
|
|
{
|
|
"airbyte_cdk": {"stream": {"name": A_STREAM_NAME}},
|
|
"http": {
|
|
"title": A_TITLE,
|
|
"description": A_DESCRIPTION,
|
|
"request": {
|
|
"method": "GET",
|
|
"body": {"content": '{"b1": "v1", "b2": "v2"}'},
|
|
"headers": {"Content-Type": "application/json", "Content-Length": "24"},
|
|
},
|
|
"response": EMPTY_RESPONSE,
|
|
},
|
|
"log": {"level": "debug"},
|
|
"url": {"full": "https://airbyte.io/"},
|
|
},
|
|
),
|
|
(
|
|
"test_get_request_with_headers_params_and_body",
|
|
"GET",
|
|
"https://airbyte.io",
|
|
{"Content-Type": "application/json", "h1": "v1"},
|
|
{"p1": "v1", "p2": "v2"},
|
|
{"b1": "v1", "b2": "v2"},
|
|
{},
|
|
{
|
|
"airbyte_cdk": {"stream": {"name": A_STREAM_NAME}},
|
|
"http": {
|
|
"title": A_TITLE,
|
|
"description": A_DESCRIPTION,
|
|
"request": {
|
|
"method": "GET",
|
|
"body": {"content": '{"b1": "v1", "b2": "v2"}'},
|
|
"headers": {"Content-Type": "application/json", "Content-Length": "24", "h1": "v1"},
|
|
},
|
|
"response": EMPTY_RESPONSE,
|
|
},
|
|
"log": {"level": "debug"},
|
|
"url": {"full": "https://airbyte.io/?p1=v1&p2=v2"},
|
|
},
|
|
),
|
|
(
|
|
"test_get_request_with_request_body_data",
|
|
"GET",
|
|
"https://airbyte.io",
|
|
{"Content-Type": "application/x-www-form-urlencoded"},
|
|
{},
|
|
{},
|
|
{"b1": "v1", "b2": "v2"},
|
|
{
|
|
"airbyte_cdk": {"stream": {"name": A_STREAM_NAME}},
|
|
"http": {
|
|
"title": A_TITLE,
|
|
"description": A_DESCRIPTION,
|
|
"request": {
|
|
"method": "GET",
|
|
"body": {"content": "b1=v1&b2=v2"},
|
|
"headers": {"Content-Type": "application/x-www-form-urlencoded", "Content-Length": "11"},
|
|
},
|
|
"response": EMPTY_RESPONSE,
|
|
},
|
|
"log": {"level": "debug"},
|
|
"url": {"full": "https://airbyte.io/"},
|
|
},
|
|
),
|
|
(
|
|
"test_basic_post_request",
|
|
"POST",
|
|
"https://airbyte.io",
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{
|
|
"airbyte_cdk": {"stream": {"name": A_STREAM_NAME}},
|
|
"http": {
|
|
"title": A_TITLE,
|
|
"description": A_DESCRIPTION,
|
|
"request": {"method": "POST", "body": {"content": None}, "headers": {"Content-Length": "0"}},
|
|
"response": EMPTY_RESPONSE,
|
|
},
|
|
"log": {"level": "debug"},
|
|
"url": {"full": "https://airbyte.io/"},
|
|
},
|
|
),
|
|
],
|
|
)
|
|
def test_prepared_request_to_airbyte_message(test_name, http_method, url, headers, params, body_json, body_data, expected_airbyte_message):
|
|
request = requests.Request(method=http_method, url=url, headers=headers, params=params)
|
|
if body_json:
|
|
request.json = body_json
|
|
if body_data:
|
|
request.data = body_data
|
|
prepared_request = request.prepare()
|
|
|
|
actual_airbyte_message = format_http_message(ResponseBuilder().request(prepared_request).build(), A_TITLE, A_DESCRIPTION, A_STREAM_NAME)
|
|
|
|
assert actual_airbyte_message == expected_airbyte_message
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"test_name, response_body, response_headers, status_code, expected_airbyte_message",
|
|
[
|
|
("test_response_no_body_no_headers", b"", {}, 200, {"body": {"content": ""}, "headers": {}, "status_code": 200}),
|
|
(
|
|
"test_response_no_body_with_headers",
|
|
b"",
|
|
{"h1": "v1", "h2": "v2"},
|
|
200,
|
|
{"body": {"content": ""}, "headers": {"h1": "v1", "h2": "v2"}, "status_code": 200},
|
|
),
|
|
(
|
|
"test_response_with_body_no_headers",
|
|
b'{"b1": "v1", "b2": "v2"}',
|
|
{},
|
|
200,
|
|
{"body": {"content": '{"b1": "v1", "b2": "v2"}'}, "headers": {}, "status_code": 200},
|
|
),
|
|
(
|
|
"test_response_with_body_and_headers",
|
|
b'{"b1": "v1", "b2": "v2"}',
|
|
{"h1": "v1", "h2": "v2"},
|
|
200,
|
|
{"body": {"content": '{"b1": "v1", "b2": "v2"}'}, "headers": {"h1": "v1", "h2": "v2"}, "status_code": 200},
|
|
),
|
|
],
|
|
)
|
|
def test_response_to_airbyte_message(test_name, response_body, response_headers, status_code, expected_airbyte_message):
|
|
response = ResponseBuilder().body_content(response_body).headers(response_headers).status_code(status_code).build()
|
|
|
|
actual_airbyte_message = format_http_message(response, A_TITLE, A_DESCRIPTION, A_STREAM_NAME)
|
|
|
|
assert actual_airbyte_message["http"]["response"] == expected_airbyte_message
|