138 lines
7.7 KiB
Python
138 lines
7.7 KiB
Python
#
|
|
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
|
#
|
|
|
|
import pytest
|
|
from airbyte_api_client.api import destination_api, source_api, web_backend_api
|
|
from airbyte_api_client.model.destination_id_request_body import DestinationIdRequestBody
|
|
from airbyte_api_client.model.source_id_request_body import SourceIdRequestBody
|
|
from airbyte_api_client.model.web_backend_connection_request_body import WebBackendConnectionRequestBody
|
|
from octavia_cli.get.resources import BaseResource, Connection, Destination, DuplicateResourceError, ResourceNotFoundError, Source
|
|
|
|
|
|
class TestBaseResource:
|
|
@pytest.fixture
|
|
def patch_base_class(self, mocker):
|
|
# Mock abstract methods to enable instantiating abstract class
|
|
mocker.patch.object(BaseResource, "__abstractmethods__", set())
|
|
mocker.patch.object(BaseResource, "api", mocker.Mock())
|
|
mocker.patch.object(BaseResource, "get_function_name", "get_function_name")
|
|
mocker.patch.object(BaseResource, "get_payload", "get_payload")
|
|
mocker.patch.object(BaseResource, "list_for_workspace_function_name", "list_for_workspace_function_name")
|
|
mocker.patch.object(BaseResource, "name", "fake_resource")
|
|
|
|
@pytest.mark.parametrize(
|
|
"resource_id, resource_name, expected_error, expected_error_message",
|
|
[
|
|
("my_resource_id", None, None, None),
|
|
(None, "my_resource_name", None, None),
|
|
(None, None, ValueError, "resource_id and resource_name keyword arguments can't be both None."),
|
|
("my_resource_id", "my_resource_name", ValueError, "resource_id and resource_name keyword arguments can't be both set."),
|
|
],
|
|
)
|
|
def test_init(self, patch_base_class, mock_api_client, resource_id, resource_name, expected_error, expected_error_message):
|
|
if expected_error:
|
|
with pytest.raises(expected_error, match=expected_error_message):
|
|
base_resource = BaseResource(mock_api_client, "workspace_id", resource_id=resource_id, resource_name=resource_name)
|
|
else:
|
|
base_resource = BaseResource(mock_api_client, "workspace_id", resource_id=resource_id, resource_name=resource_name)
|
|
base_resource.api.assert_called_with(mock_api_client)
|
|
assert base_resource.api_instance == base_resource.api.return_value
|
|
assert base_resource.workspace_id == "workspace_id"
|
|
assert base_resource._get_fn == getattr(base_resource.api, base_resource.get_function_name)
|
|
assert base_resource._list_for_workspace_fn == getattr(base_resource.api, base_resource.list_for_workspace_function_name)
|
|
assert base_resource.resource_id == resource_id
|
|
assert base_resource.resource_name == resource_name
|
|
|
|
@pytest.mark.parametrize(
|
|
"resource_name, api_response_resources_names, expected_error, expected_error_message",
|
|
[
|
|
("foo", ["foo", "bar"], None, None),
|
|
("foo", ["bar", "fooo"], ResourceNotFoundError, "The fake_resource foo was not found in your current Airbyte workspace."),
|
|
(
|
|
"foo",
|
|
["foo", "foo"],
|
|
DuplicateResourceError,
|
|
"2 fake_resources with the name foo were found in your current Airbyte workspace.",
|
|
),
|
|
],
|
|
)
|
|
def test__find_by_resource_name(
|
|
self, mocker, patch_base_class, mock_api_client, resource_name, api_response_resources_names, expected_error, expected_error_message
|
|
):
|
|
mock_api_response_records = []
|
|
for fake_resource_name in api_response_resources_names:
|
|
mock_api_response_record = mocker.Mock() # We can't set the mock name on creation as it's a reserved attribute
|
|
mock_api_response_record.name = fake_resource_name
|
|
mock_api_response_records.append(mock_api_response_record)
|
|
|
|
mocker.patch.object(
|
|
BaseResource, "_list_for_workspace_fn", mocker.Mock(return_value=mocker.Mock(fake_resources=mock_api_response_records))
|
|
)
|
|
base_resource = BaseResource(mock_api_client, "workspace_id", resource_id=None, resource_name=resource_name)
|
|
if not expected_error:
|
|
found_resource = base_resource._find_by_resource_name()
|
|
assert found_resource.name == resource_name
|
|
if expected_error:
|
|
with pytest.raises(expected_error, match=expected_error_message):
|
|
base_resource._find_by_resource_name()
|
|
|
|
def test__find_by_id(self, mocker, patch_base_class, mock_api_client):
|
|
mocker.patch.object(BaseResource, "_get_fn")
|
|
base_resource = BaseResource(mock_api_client, "workspace_id", resource_id="my_resource_id")
|
|
base_resource._find_by_resource_id()
|
|
base_resource._get_fn.assert_called_with(base_resource.api_instance, base_resource.get_payload)
|
|
|
|
@pytest.mark.parametrize("resource_id, resource_name", [("my_resource_id", None), (None, "my_resource_name")])
|
|
def test_get_remote_resource(self, mocker, patch_base_class, mock_api_client, resource_id, resource_name):
|
|
mocker.patch.object(BaseResource, "_find_by_resource_id")
|
|
mocker.patch.object(BaseResource, "_find_by_resource_name")
|
|
base_resource = BaseResource(mock_api_client, "workspace_id", resource_id=resource_id, resource_name=resource_name)
|
|
remote_resource = base_resource.get_remote_resource()
|
|
if resource_id is not None:
|
|
base_resource._find_by_resource_id.assert_called_once()
|
|
base_resource._find_by_resource_name.assert_not_called()
|
|
assert remote_resource == base_resource._find_by_resource_id.return_value
|
|
if resource_name is not None:
|
|
base_resource._find_by_resource_id.assert_not_called()
|
|
base_resource._find_by_resource_name.assert_called_once()
|
|
assert remote_resource == base_resource._find_by_resource_name.return_value
|
|
|
|
def test_to_json(self, mocker, patch_base_class, mock_api_client):
|
|
mocker.patch.object(
|
|
BaseResource, "get_remote_resource", mocker.Mock(return_value=mocker.Mock(to_dict=mocker.Mock(return_value={"foo": "bar"})))
|
|
)
|
|
base_resource = BaseResource(mock_api_client, "workspace_id", resource_id="my_resource_id")
|
|
json_repr = base_resource.to_json()
|
|
assert json_repr == '{"foo": "bar"}'
|
|
|
|
|
|
class TestSource:
|
|
def test_init(self, mock_api_client):
|
|
assert Source.__base__ == BaseResource
|
|
source = Source(mock_api_client, "workspace_id", "resource_id")
|
|
assert source.api == source_api.SourceApi
|
|
assert source.get_function_name == "get_source"
|
|
assert source.list_for_workspace_function_name == "list_sources_for_workspace"
|
|
assert source.get_payload == SourceIdRequestBody("resource_id")
|
|
|
|
|
|
class TestDestination:
|
|
def test_init(self, mock_api_client):
|
|
assert Destination.__base__ == BaseResource
|
|
destination = Destination(mock_api_client, "workspace_id", "resource_id")
|
|
assert destination.api == destination_api.DestinationApi
|
|
assert destination.get_function_name == "get_destination"
|
|
assert destination.list_for_workspace_function_name == "list_destinations_for_workspace"
|
|
assert destination.get_payload == DestinationIdRequestBody("resource_id")
|
|
|
|
|
|
class TestConnection:
|
|
def test_init(self, mock_api_client):
|
|
assert Connection.__base__ == BaseResource
|
|
connection = Connection(mock_api_client, "workspace_id", "resource_id")
|
|
assert connection.api == web_backend_api.WebBackendApi
|
|
assert connection.get_function_name == "web_backend_get_connection"
|
|
assert connection.list_for_workspace_function_name == "web_backend_list_connections_for_workspace"
|
|
assert connection.get_payload == WebBackendConnectionRequestBody(with_refreshed_catalog=False, connection_id=connection.resource_id)
|