Skip to content

Commit 9b0ed96

Browse files
authored
Source PayPal Transactions: increase unit tests (#15098)
* add unit tests * add unit tests * up * bump version * upd * upd * revert bump version
1 parent dd109de commit 9b0ed96

File tree

3 files changed

+197
-13
lines changed

3 files changed

+197
-13
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#
2+
# Copyright (c) 2022 Airbyte, Inc., all rights reserved.
3+
#
4+
5+
import json
6+
import pathlib
7+
8+
import pytest
9+
from source_paypal_transaction.source import PayPalOauth2Authenticator, SourcePaypalTransaction
10+
11+
12+
@pytest.fixture()
13+
def api_endpoint():
14+
return "https://api-m.paypal.com"
15+
16+
17+
@pytest.fixture()
18+
def sandbox_api_endpoint():
19+
return "https://api-m.sandbox.paypal.com"
20+
21+
22+
@pytest.fixture(autouse=True)
23+
def time_sleep_mock(mocker):
24+
time_mock = mocker.patch("time.sleep", lambda x: None)
25+
yield time_mock
26+
27+
28+
@pytest.fixture(autouse=True)
29+
def transactions(request):
30+
file = pathlib.Path(request.node.fspath.strpath)
31+
transaction = file.with_name("transaction.json")
32+
with transaction.open() as fp:
33+
return json.load(fp)
34+
35+
36+
@pytest.fixture()
37+
def prod_config():
38+
"""
39+
Credentials for oauth2.0 authorization
40+
"""
41+
return {
42+
"client_id": "some_client_id",
43+
"secret": "some_secret",
44+
"start_date": "2021-07-01T00:00:00+00:00",
45+
"end_date": "2021-07-10T00:00:00+00:00",
46+
"is_sandbox": False
47+
}
48+
49+
50+
@pytest.fixture()
51+
def sandbox_config():
52+
"""
53+
Credentials for oauth2.0 authorization
54+
"""
55+
return {
56+
"client_id": "some_client_id",
57+
"secret": "some_secret",
58+
"start_date": "2021-07-01T00:00:00+00:00",
59+
"end_date": "2021-07-10T00:00:00+00:00",
60+
"is_sandbox": True
61+
}
62+
63+
64+
@pytest.fixture()
65+
def new_prod_config():
66+
"""
67+
Credentials for oauth2.0 authorization
68+
"""
69+
return {
70+
"credentials": {
71+
"auth_type": "oauth2.0",
72+
"client_id": "some_client_id",
73+
"client_secret": "some_client_secret",
74+
"refresh_token": "some_refresh_token"
75+
},
76+
"start_date": "2021-07-01T00:00:00+00:00",
77+
"end_date": "2021-07-10T00:00:00+00:00",
78+
"is_sandbox": False
79+
}
80+
81+
82+
@pytest.fixture()
83+
def error_while_refreshing_access_token():
84+
"""
85+
Error raised when using incorrect access token
86+
"""
87+
return "Error while refreshing access token: 'access_token'"
88+
89+
90+
@pytest.fixture()
91+
def authenticator_instance(prod_config):
92+
return PayPalOauth2Authenticator(prod_config)
93+
94+
95+
@pytest.fixture()
96+
def new_format_authenticator_instance(new_prod_config):
97+
return PayPalOauth2Authenticator(new_prod_config)
98+
99+
100+
@pytest.fixture()
101+
def source_instance():
102+
return SourcePaypalTransaction()
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#
2+
# Copyright (c) 2022 Airbyte, Inc., all rights reserved.
3+
#
4+
5+
from unittest.mock import MagicMock
6+
7+
from source_paypal_transaction.source import PayPalOauth2Authenticator, get_endpoint
8+
9+
10+
class TestAuthentication:
11+
12+
def test_init_token_authentication_init(self, authenticator_instance):
13+
assert isinstance(authenticator_instance, PayPalOauth2Authenticator)
14+
15+
def test_get_refresh_request_body(self, authenticator_instance):
16+
expected_body = {"grant_type": "client_credentials"}
17+
assert authenticator_instance.get_refresh_request_body() == expected_body
18+
19+
def test_oauth2_refresh_token_ok(self, requests_mock, authenticator_instance, api_endpoint):
20+
requests_mock.post(f"{api_endpoint}/v1/oauth2/token", json={"access_token": "test_access_token", "expires_in": 12345})
21+
result = authenticator_instance.refresh_access_token()
22+
assert result == ("test_access_token", 12345)
23+
24+
def test_oauth2_refresh_token_failed(self, requests_mock, authenticator_instance, api_endpoint, error_while_refreshing_access_token):
25+
requests_mock.post(f"{api_endpoint}/v1/oauth2/token", json={})
26+
try:
27+
authenticator_instance.refresh_access_token()
28+
except Exception as e:
29+
assert e.args[0] == error_while_refreshing_access_token
30+
31+
def test_new_oauth2_refresh_token_ok(self, requests_mock, new_format_authenticator_instance, api_endpoint):
32+
requests_mock.post(f"{api_endpoint}/v1/oauth2/token", json={"access_token": "test_access_token", "expires_in": 12345})
33+
result = new_format_authenticator_instance.refresh_access_token()
34+
assert result == ("test_access_token", 12345)
35+
36+
def test_streams_count(self, prod_config, source_instance):
37+
assert len(source_instance.streams(prod_config)) == 2
38+
39+
def test_check_connection_ok(self, requests_mock, prod_config, api_endpoint, transactions, source_instance):
40+
requests_mock.post(f"{api_endpoint}/v1/oauth2/token", json={"access_token": "test_access_token", "expires_in": 12345})
41+
url = f'{api_endpoint}/v1/reporting/transactions' + '?start_date=2021-07-01T00%3A00%3A00%2B00%3A00&end_date=2021-07-02T00%3A00%3A00%2B00%3A00&fields=all&page_size=500&page=1'
42+
requests_mock.get(url, json=transactions)
43+
assert source_instance.check_connection(logger=MagicMock(), config=prod_config) == (True, None)
44+
45+
def test_check_connection_error(self, requests_mock, prod_config, api_endpoint, source_instance):
46+
requests_mock.post(f"{api_endpoint}/v1/oauth2/token", json={"access_token": "test_access_token", "expires_in": 12345})
47+
url = f'{api_endpoint}/v1/reporting/transactions' + '?start_date=2021-07-01T00%3A00%3A00%2B00%3A00&end_date=2021-07-02T00%3A00%3A00%2B00%3A00&fields=all&page_size=500&page=1'
48+
requests_mock.get(url, status_code=400, json={})
49+
assert not source_instance.check_connection(logger=MagicMock(), config=prod_config)[0]
50+
51+
def test_get_prod_endpoint(self, prod_config, api_endpoint):
52+
assert get_endpoint(prod_config["is_sandbox"]) == api_endpoint
53+
54+
def test_get_sandbox_endpoint(self, sandbox_config, sandbox_api_endpoint):
55+
assert get_endpoint(sandbox_config["is_sandbox"]) == sandbox_api_endpoint

airbyte-integrations/connectors/source-paypal-transaction/unit_tests/unit_test.py

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,31 @@
22
# Copyright (c) 2022 Airbyte, Inc., all rights reserved.
33
#
44

5-
import json
6-
import pathlib
75
from datetime import datetime, timedelta
86

7+
from airbyte_cdk.models import SyncMode
98
from airbyte_cdk.sources.streams.http.auth import NoAuth
109
from dateutil.parser import isoparse
11-
from pytest import fixture, raises
10+
from pytest import raises
1211
from source_paypal_transaction.source import Balances, PaypalTransactionStream, Transactions
1312

1413

15-
@fixture(autouse=True)
16-
def time_sleep_mock(mocker):
17-
time_mock = mocker.patch("time.sleep", lambda x: None)
18-
yield time_mock
14+
def test_minimum_allowed_start_date():
15+
start_date = now() - timedelta(days=10 * 365)
16+
stream = Transactions(authenticator=NoAuth(), start_date=start_date)
17+
assert stream.start_date != start_date
1918

2019

21-
@fixture(autouse=True)
22-
def transactions(request):
23-
file = pathlib.Path(request.node.fspath.strpath)
24-
transaction = file.with_name("transaction.json")
25-
with transaction.open() as fp:
26-
return json.load(fp)
20+
def test_transactions_transform_function():
21+
start_date = now() - timedelta(days=10 * 365)
22+
stream = Transactions(authenticator=NoAuth(), start_date=start_date)
23+
transformer = stream.transformer
24+
input_data = {"transaction_amount": "123.45", "transaction_id": "111", "transaction_status": "done"}
25+
schema = stream.get_json_schema()
26+
schema['properties'] = {"transaction_amount": {"type": "number"}, "transaction_id": {"type": "integer"}, "transaction_status": {"type": "string"}}
27+
transformer.transform(input_data, schema)
28+
expected_data = {"transaction_amount": 123.45, "transaction_id": 111, "transaction_status": "done"}
29+
assert input_data == expected_data
2730

2831

2932
def test_get_field():
@@ -319,3 +322,27 @@ def test_unnest_field():
319322
PaypalTransactionStream.unnest_field(record, Transactions.nested_object, Transactions.cursor_field)
320323
# check the cursor now on the root level
321324
assert Transactions.cursor_field in record.keys()
325+
326+
327+
def test_get_last_refreshed_datetime(requests_mock, prod_config, api_endpoint):
328+
stream = Balances(authenticator=NoAuth(), **prod_config)
329+
requests_mock.post(f"{api_endpoint}/v1/oauth2/token", json={"access_token": "test_access_token", "expires_in": 12345})
330+
url = f'{api_endpoint}/v1/reporting/balances' + '?as_of_time=2021-07-01T00%3A00%3A00%2B00%3A00'
331+
requests_mock.get(url, json={})
332+
assert not stream.get_last_refreshed_datetime(SyncMode.full_refresh)
333+
334+
335+
def test_get_updated_state(transactions):
336+
start_date = "2021-06-01T10:00:00+00:00"
337+
stream = Transactions(
338+
authenticator=NoAuth(),
339+
start_date=isoparse(start_date),
340+
end_date=isoparse("2021-06-04T12:00:00+00:00"),
341+
)
342+
state = stream.get_updated_state(current_stream_state={}, latest_record={})
343+
assert state == {"date": start_date}
344+
345+
record = transactions[stream.data_field][0][stream.nested_object]
346+
expected_state = {"date": now().isoformat()}
347+
state = stream.get_updated_state(current_stream_state=expected_state, latest_record=record)
348+
assert state == expected_state

0 commit comments

Comments
 (0)