-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Source Shopify: add unit tests (#17944)
- Loading branch information
1 parent
ef08d88
commit 384aabb
Showing
2 changed files
with
200 additions
and
0 deletions.
There are no files selected for viewing
52 changes: 52 additions & 0 deletions
52
airbyte-integrations/connectors/source-shopify/unit_tests/test_auth.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# | ||
# Copyright (c) 2022 Airbyte, Inc., all rights reserved. | ||
# | ||
|
||
|
||
import pytest | ||
from source_shopify.auth import NotImplementedAuth, ShopifyAuthenticator | ||
|
||
TEST_ACCESS_TOKEN = "test_access_token" | ||
TEST_API_PASSWORD = "test_api_password" | ||
|
||
|
||
@pytest.fixture | ||
def config_access_token(): | ||
return {"credentials": {"access_token": TEST_ACCESS_TOKEN, "auth_method": "access_token"}} | ||
|
||
|
||
@pytest.fixture | ||
def config_api_password(): | ||
return {"credentials": {"api_password": TEST_API_PASSWORD, "auth_method": "api_password"}} | ||
|
||
|
||
@pytest.fixture | ||
def config_not_implemented_auth_method(): | ||
return {"credentials": {"auth_method": "not_implemented_auth_method"}} | ||
|
||
|
||
@pytest.fixture | ||
def expected_auth_header_access_token(): | ||
return {"X-Shopify-Access-Token": TEST_ACCESS_TOKEN} | ||
|
||
|
||
@pytest.fixture | ||
def expected_auth_header_api_password(): | ||
return {"X-Shopify-Access-Token": TEST_API_PASSWORD} | ||
|
||
|
||
def test_shopify_authenticator_access_token(config_access_token, expected_auth_header_access_token): | ||
authenticator = ShopifyAuthenticator(config=config_access_token) | ||
assert authenticator.get_auth_header() == expected_auth_header_access_token | ||
|
||
|
||
def test_shopify_authenticator_api_password(config_api_password, expected_auth_header_api_password): | ||
authenticator = ShopifyAuthenticator(config=config_api_password) | ||
assert authenticator.get_auth_header() == expected_auth_header_api_password | ||
|
||
|
||
def test_raises_notimplemented_auth(config_not_implemented_auth_method): | ||
authenticator = ShopifyAuthenticator(config=(config_not_implemented_auth_method)) | ||
with pytest.raises(NotImplementedAuth) as not_implemented_exc: | ||
print(not_implemented_exc) | ||
authenticator.get_auth_header() |
148 changes: 148 additions & 0 deletions
148
airbyte-integrations/connectors/source-shopify/unit_tests/test_source.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
# | ||
# Copyright (c) 2022 Airbyte, Inc., all rights reserved. | ||
# | ||
|
||
|
||
from unittest.mock import MagicMock | ||
|
||
import pytest | ||
from source_shopify.auth import ShopifyAuthenticator | ||
from source_shopify.source import ( | ||
AbandonedCheckouts, | ||
Articles, | ||
Blogs, | ||
Collects, | ||
CustomCollections, | ||
Customers, | ||
DiscountCodes, | ||
DraftOrders, | ||
FulfillmentOrders, | ||
Fulfillments, | ||
InventoryLevels, | ||
Locations, | ||
MetafieldArticles, | ||
MetafieldBlogs, | ||
MetafieldCollections, | ||
MetafieldCustomers, | ||
MetafieldDraftOrders, | ||
MetafieldLocations, | ||
MetafieldOrders, | ||
MetafieldPages, | ||
MetafieldProducts, | ||
MetafieldProductVariants, | ||
MetafieldShops, | ||
MetafieldSmartCollections, | ||
OrderRefunds, | ||
OrderRisks, | ||
Orders, | ||
Pages, | ||
PriceRules, | ||
ProductImages, | ||
Products, | ||
ProductVariants, | ||
Shop, | ||
SourceShopify, | ||
TenderTransactions, | ||
Transactions, | ||
) | ||
|
||
|
||
@pytest.fixture | ||
def config(basic_config): | ||
basic_config["start_date"] = "2020-11-01" | ||
basic_config["authenticator"] = ShopifyAuthenticator(basic_config) | ||
return basic_config | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"stream,stream_slice,expected_path", | ||
[ | ||
(Articles, None, "articles.json"), | ||
(Blogs, None, "blogs.json"), | ||
(MetafieldBlogs, {"id": 123}, "blogs/123/metafields.json"), | ||
(MetafieldArticles, {"id": 123}, "articles/123/metafields.json"), | ||
(MetafieldCustomers, {"id": 123}, "customers/123/metafields.json"), | ||
(MetafieldOrders, {"id": 123}, "orders/123/metafields.json"), | ||
(MetafieldDraftOrders, {"id": 123}, "draft_orders/123/metafields.json"), | ||
(MetafieldProducts, {"id": 123}, "products/123/metafields.json"), | ||
(MetafieldProductVariants, {"variants": 123}, "variants/123/metafields.json"), | ||
(MetafieldSmartCollections, {"id": 123}, "smart_collections/123/metafields.json"), | ||
(MetafieldCollections, {"collection_id": 123}, "collections/123/metafields.json"), | ||
(MetafieldPages, {"id": 123}, "pages/123/metafields.json"), | ||
(MetafieldLocations, {"id": 123}, "locations/123/metafields.json"), | ||
(MetafieldShops, None, "metafields.json"), | ||
(ProductImages, {"product_id": 123}, "products/123/images.json"), | ||
(ProductVariants, {"product_id": 123}, "products/123/variants.json"), | ||
(Customers, None, "customers.json"), | ||
(Orders, None, "orders.json"), | ||
(DraftOrders, None, "draft_orders.json"), | ||
(Products, None, "products.json"), | ||
(AbandonedCheckouts, None, "checkouts.json"), | ||
(Collects, None, "collects.json"), | ||
(TenderTransactions, None, "tender_transactions.json"), | ||
(Pages, None, "pages.json"), | ||
(PriceRules, None, "price_rules.json"), | ||
(Locations, None, "locations.json"), | ||
(Shop, None, "shop.json"), | ||
(CustomCollections, None, "custom_collections.json"), | ||
], | ||
) | ||
def test_customers_path(stream, stream_slice, expected_path, config): | ||
stream = stream(config) | ||
if stream_slice: | ||
result = stream.path(stream_slice) | ||
else: | ||
result = stream.path() | ||
assert result == expected_path | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"stream,stream_slice,expected_path", | ||
[ | ||
(OrderRefunds, {"order_id": 12345}, "orders/12345/refunds.json"), | ||
(OrderRisks, {"order_id": 12345}, "orders/12345/risks.json"), | ||
(Transactions, {"order_id": 12345}, "orders/12345/transactions.json"), | ||
(DiscountCodes, {"price_rule_id": 12345}, "price_rules/12345/discount_codes.json"), | ||
(InventoryLevels, {"location_id": 12345}, "locations/12345/inventory_levels.json"), | ||
(FulfillmentOrders, {"order_id": 12345}, "orders/12345/fulfillment_orders.json"), | ||
(Fulfillments, {"order_id": 12345}, "orders/12345/fulfillments.json"), | ||
], | ||
) | ||
def test_customers_path_with_stream_slice_param(stream, stream_slice, expected_path, config): | ||
stream = stream(config) | ||
assert stream.path(stream_slice) == expected_path | ||
|
||
|
||
def test_check_connection(config, mocker): | ||
mocker.patch("source_shopify.source.Shop.read_records", return_value=[{"id": 1}]) | ||
source = SourceShopify() | ||
logger_mock = MagicMock() | ||
assert source.check_connection(logger_mock, config) == (True, None) | ||
|
||
|
||
def test_read_records(config, mocker): | ||
records = [{"created_at": "2022-10-10T06:21:53-07:00", "orders": {"updated_at": "2022-10-10T06:21:53-07:00"}}] | ||
stream_slice = records[0] | ||
stream = OrderRefunds(config) | ||
mocker.patch("source_shopify.source.IncrementalShopifyStream.read_records", return_value=records) | ||
assert next(stream.read_records(stream_slice=stream_slice)) == records[0] | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"stream, expected", | ||
[ | ||
(OrderRefunds, {"limit": 250}), | ||
(Orders, {"limit": 250, "status": "any", "order": "updated_at asc", "updated_at_min": "2020-11-01"}), | ||
(AbandonedCheckouts, {"limit": 250, "status": "any", "order": "updated_at asc", "updated_at_min": "2020-11-01"}), | ||
], | ||
) | ||
def test_request_params(config, stream, expected): | ||
assert stream(config).request_params() == expected | ||
|
||
|
||
def test_get_updated_state(config): | ||
current_stream_state = {"created_at": ""} | ||
latest_record = {"created_at": "2022-10-10T06:21:53-07:00"} | ||
updated_state = {"created_at": "2022-10-10T06:21:53-07:00", "orders": None} | ||
stream = OrderRefunds(config) | ||
assert stream.get_updated_state(current_stream_state=current_stream_state, latest_record=latest_record) == updated_state |