airbyte-source-kyriba 0.1.0__py3-none-any.whl → 0.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- airbyte_source_kyriba-0.1.3.dist-info/METADATA +110 -0
- airbyte_source_kyriba-0.1.3.dist-info/RECORD +15 -0
- {airbyte_source_kyriba-0.1.0.dist-info → airbyte_source_kyriba-0.1.3.dist-info}/WHEEL +1 -2
- airbyte_source_kyriba-0.1.3.dist-info/entry_points.txt +3 -0
- source_kyriba/schemas/accounts.json +174 -289
- source_kyriba/schemas/bank_balances_eod.json +20 -38
- source_kyriba/schemas/bank_balances_intraday.json +21 -32
- source_kyriba/schemas/cash_balances_eod.json +36 -58
- source_kyriba/schemas/cash_balances_intraday.json +29 -57
- source_kyriba/schemas/cash_flows.json +25 -47
- source_kyriba/schemas/shared/_definitions.json +146 -333
- source_kyriba/source.py +9 -3
- source_kyriba/spec.json +9 -5
- airbyte_source_kyriba-0.1.0.dist-info/METADATA +0 -99
- airbyte_source_kyriba-0.1.0.dist-info/RECORD +0 -31
- airbyte_source_kyriba-0.1.0.dist-info/entry_points.txt +0 -2
- airbyte_source_kyriba-0.1.0.dist-info/top_level.txt +0 -3
- integration_tests/__init__.py +0 -3
- integration_tests/abnormal_state.json +0 -1
- integration_tests/acceptance.py +0 -16
- integration_tests/configured_catalog.json +0 -74
- integration_tests/invalid_config.json +0 -7
- integration_tests/sample_config.json +0 -7
- integration_tests/sample_state.json +0 -1
- unit_tests/__init__.py +0 -3
- unit_tests/test_account_sub_stream.py +0 -37
- unit_tests/test_bank_balances_stream.py +0 -77
- unit_tests/test_cash_balances_stream.py +0 -77
- unit_tests/test_cash_flows.py +0 -100
- unit_tests/test_incremental_streams.py +0 -72
- unit_tests/test_source.py +0 -35
- unit_tests/test_streams.py +0 -121
@@ -1,72 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
3
|
-
#
|
4
|
-
|
5
|
-
|
6
|
-
from airbyte_cdk.models import SyncMode
|
7
|
-
from pytest import fixture
|
8
|
-
from source_kyriba.source import IncrementalKyribaStream
|
9
|
-
|
10
|
-
from .test_streams import config
|
11
|
-
|
12
|
-
|
13
|
-
@fixture
|
14
|
-
def patch_incremental_base_class(mocker):
|
15
|
-
# Mock abstract methods to enable instantiating abstract class
|
16
|
-
mocker.patch.object(IncrementalKyribaStream, "path", "v0/example_endpoint")
|
17
|
-
mocker.patch.object(IncrementalKyribaStream, "primary_key", "test_primary_key")
|
18
|
-
mocker.patch.object(IncrementalKyribaStream, "__abstractmethods__", set())
|
19
|
-
|
20
|
-
|
21
|
-
def test_cursor_field(patch_incremental_base_class):
|
22
|
-
stream = IncrementalKyribaStream(**config())
|
23
|
-
expected_cursor_field = "updateDateTime"
|
24
|
-
assert stream.cursor_field == expected_cursor_field
|
25
|
-
|
26
|
-
|
27
|
-
def test_get_updated_state(patch_incremental_base_class):
|
28
|
-
stream = IncrementalKyribaStream(**config())
|
29
|
-
inputs = {
|
30
|
-
"current_stream_state": {"updateDateTime": "2022-01-01T00:00:00Z"},
|
31
|
-
"latest_record": {"updateDateTime": "2022-01-01T00:00:01Z"},
|
32
|
-
}
|
33
|
-
expected_state = {"updateDateTime": "2022-01-01T00:00:01Z"}
|
34
|
-
assert stream.get_updated_state(**inputs) == expected_state
|
35
|
-
|
36
|
-
|
37
|
-
def test_stream_slices(patch_incremental_base_class):
|
38
|
-
stream = IncrementalKyribaStream(**config())
|
39
|
-
inputs = {"sync_mode": SyncMode.incremental, "cursor_field": [], "stream_state": {}}
|
40
|
-
expected_stream_slice = [None]
|
41
|
-
assert stream.stream_slices(**inputs) == expected_stream_slice
|
42
|
-
|
43
|
-
|
44
|
-
def test_supports_incremental(patch_incremental_base_class, mocker):
|
45
|
-
mocker.patch.object(IncrementalKyribaStream, "cursor_field", "dummy_field")
|
46
|
-
stream = IncrementalKyribaStream(**config())
|
47
|
-
assert stream.supports_incremental
|
48
|
-
|
49
|
-
|
50
|
-
def test_source_defined_cursor(patch_incremental_base_class):
|
51
|
-
stream = IncrementalKyribaStream(**config())
|
52
|
-
assert stream.source_defined_cursor
|
53
|
-
|
54
|
-
|
55
|
-
def test_stream_checkpoint_interval(patch_incremental_base_class):
|
56
|
-
stream = IncrementalKyribaStream(**config())
|
57
|
-
expected_checkpoint_interval = 100
|
58
|
-
assert stream.state_checkpoint_interval == expected_checkpoint_interval
|
59
|
-
|
60
|
-
|
61
|
-
def test_all_request_params(patch_incremental_base_class):
|
62
|
-
stream = IncrementalKyribaStream(**config())
|
63
|
-
inputs = {"stream_state": {"updateDateTime": "2022-01-01T00:00:00Z"}, "stream_slice": {}, "next_page_token": {"page.offset": 100}}
|
64
|
-
expected = {"sort": "updateDateTime", "page.offset": 100, "filter": "updateDateTime=gt='2022-01-01T00:00:00Z'"}
|
65
|
-
assert stream.request_params(**inputs) == expected
|
66
|
-
|
67
|
-
|
68
|
-
def test_min_request_params(patch_incremental_base_class):
|
69
|
-
stream = IncrementalKyribaStream(**config())
|
70
|
-
inputs = {"stream_state": {}, "stream_slice": {}, "next_page_token": {}}
|
71
|
-
expected = {"sort": "updateDateTime", "filter": "updateDateTime=gt='2022-01-01T00:00:00Z'"}
|
72
|
-
assert stream.request_params(**inputs) == expected
|
unit_tests/test_source.py
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
3
|
-
#
|
4
|
-
|
5
|
-
from unittest.mock import MagicMock
|
6
|
-
|
7
|
-
from source_kyriba.source import KyribaClient, SourceKyriba
|
8
|
-
|
9
|
-
config = {
|
10
|
-
"username": "username",
|
11
|
-
"password": "password",
|
12
|
-
"domain": "demo.kyriba.com",
|
13
|
-
"start_date": "2022-01-01",
|
14
|
-
}
|
15
|
-
|
16
|
-
config = {
|
17
|
-
"username": "username",
|
18
|
-
"password": "password",
|
19
|
-
"domain": "demo.kyriba.com",
|
20
|
-
"start_date": "2022-01-01",
|
21
|
-
}
|
22
|
-
|
23
|
-
|
24
|
-
def test_check_connection(mocker):
|
25
|
-
source = SourceKyriba()
|
26
|
-
KyribaClient.login = MagicMock()
|
27
|
-
logger_mock = MagicMock()
|
28
|
-
assert source.check_connection(logger_mock, config) == (True, None)
|
29
|
-
|
30
|
-
|
31
|
-
def test_streams(mocker):
|
32
|
-
source = SourceKyriba()
|
33
|
-
streams = source.streams(config)
|
34
|
-
expected_streams_number = 6
|
35
|
-
assert len(streams) == expected_streams_number
|
unit_tests/test_streams.py
DELETED
@@ -1,121 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
3
|
-
#
|
4
|
-
|
5
|
-
from http import HTTPStatus
|
6
|
-
from unittest.mock import MagicMock
|
7
|
-
|
8
|
-
import pytest
|
9
|
-
import requests
|
10
|
-
from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator
|
11
|
-
from source_kyriba.source import KyribaClient, KyribaStream
|
12
|
-
|
13
|
-
|
14
|
-
@pytest.fixture
|
15
|
-
def patch_base_class(mocker):
|
16
|
-
# Mock abstract methods to enable instantiating abstract class
|
17
|
-
mocker.patch.object(KyribaStream, "path", "v0/example_endpoint")
|
18
|
-
mocker.patch.object(KyribaStream, "primary_key", "test_primary_key")
|
19
|
-
mocker.patch.object(KyribaStream, "__abstractmethods__", set())
|
20
|
-
|
21
|
-
|
22
|
-
def config():
|
23
|
-
gateway_url = "https://demo.kyriba.com/gateway"
|
24
|
-
client = KyribaClient("username", "password", gateway_url)
|
25
|
-
client.login = MagicMock(return_value=TokenAuthenticator("token"))
|
26
|
-
return {
|
27
|
-
"gateway_url": "https://demo.kyriba.com/gateway",
|
28
|
-
"client": client,
|
29
|
-
"start_date": "2022-01-01",
|
30
|
-
"end_date": "2022-03-01",
|
31
|
-
}
|
32
|
-
|
33
|
-
|
34
|
-
def test_request_params(patch_base_class):
|
35
|
-
stream = KyribaStream(**config())
|
36
|
-
inputs = {"stream_slice": None, "stream_state": None, "next_page_token": {"page.offset": 100}}
|
37
|
-
expected_params = {"page.offset": 100}
|
38
|
-
assert stream.request_params(**inputs) == expected_params
|
39
|
-
|
40
|
-
|
41
|
-
def test_next_page_token(patch_base_class):
|
42
|
-
stream = KyribaStream(**config())
|
43
|
-
# TODO: replace this with your input parameters
|
44
|
-
resp = requests.Response()
|
45
|
-
resp_dict = {
|
46
|
-
"metadata": {
|
47
|
-
"links": {"next": "https://next"},
|
48
|
-
"pageOffset": 0,
|
49
|
-
"pageLimit": 100,
|
50
|
-
}
|
51
|
-
}
|
52
|
-
resp.json = MagicMock(return_value=resp_dict)
|
53
|
-
inputs = {"response": resp}
|
54
|
-
expected_token = {"page.offset": 100}
|
55
|
-
assert stream.next_page_token(**inputs) == expected_token
|
56
|
-
|
57
|
-
|
58
|
-
def test_parse_response(patch_base_class):
|
59
|
-
stream = KyribaStream(**config())
|
60
|
-
resp = requests.Response()
|
61
|
-
resp_dict = {"results": [{"uuid": "uuid"}]}
|
62
|
-
resp.json = MagicMock(return_value=resp_dict)
|
63
|
-
inputs = {"response": resp}
|
64
|
-
expected_parsed_object = {"uuid": "uuid"}
|
65
|
-
assert next(stream.parse_response(**inputs)) == expected_parsed_object
|
66
|
-
|
67
|
-
|
68
|
-
def test_request_headers(patch_base_class):
|
69
|
-
stream = KyribaStream(**config())
|
70
|
-
inputs = {"stream_slice": None, "stream_state": None, "next_page_token": None}
|
71
|
-
expected_headers = {}
|
72
|
-
assert stream.request_headers(**inputs) == expected_headers
|
73
|
-
|
74
|
-
|
75
|
-
def test_http_method(patch_base_class):
|
76
|
-
stream = KyribaStream(**config())
|
77
|
-
expected_method = "GET"
|
78
|
-
assert stream.http_method == expected_method
|
79
|
-
|
80
|
-
|
81
|
-
@pytest.mark.parametrize(
|
82
|
-
("http_status", "should_retry"),
|
83
|
-
[
|
84
|
-
(HTTPStatus.OK, False),
|
85
|
-
(HTTPStatus.BAD_REQUEST, False),
|
86
|
-
(HTTPStatus.TOO_MANY_REQUESTS, True),
|
87
|
-
(HTTPStatus.INTERNAL_SERVER_ERROR, True),
|
88
|
-
],
|
89
|
-
)
|
90
|
-
def test_should_retry(patch_base_class, http_status, should_retry):
|
91
|
-
response_mock = MagicMock()
|
92
|
-
response_mock.status_code = http_status
|
93
|
-
stream = KyribaStream(**config())
|
94
|
-
assert stream.should_retry(response_mock) == should_retry
|
95
|
-
|
96
|
-
|
97
|
-
def test_should_retry_401(patch_base_class):
|
98
|
-
response_mock = MagicMock()
|
99
|
-
response_mock.status_code = HTTPStatus.UNAUTHORIZED
|
100
|
-
cfg = config()
|
101
|
-
client = KyribaClient("username", "password", "https://gateway.url")
|
102
|
-
client.login = MagicMock(return_value=TokenAuthenticator("token"))
|
103
|
-
client.access_token = "token"
|
104
|
-
cfg["client"] = client
|
105
|
-
stream = KyribaStream(**cfg)
|
106
|
-
client.login.assert_called_once()
|
107
|
-
assert stream.should_retry(response_mock)
|
108
|
-
|
109
|
-
|
110
|
-
def test_backoff_time(patch_base_class):
|
111
|
-
response_mock = MagicMock()
|
112
|
-
stream = KyribaStream(**config())
|
113
|
-
expected_backoff_time = None
|
114
|
-
assert stream.backoff_time(response_mock) == expected_backoff_time
|
115
|
-
|
116
|
-
|
117
|
-
def test_unnest(patch_base_class):
|
118
|
-
stream = KyribaStream(**config())
|
119
|
-
data = {"uuid": "uuid", "nested": {"date": "date"}}
|
120
|
-
expected = {"uuid": "uuid", "date": "date"}
|
121
|
-
assert stream.unnest("nested", data) == expected
|