From 6a6365756b3003532aa6d4f2e91684148c150a55 Mon Sep 17 00:00:00 2001 From: Kevin Harwood Date: Mon, 30 Aug 2021 08:36:27 -0500 Subject: [PATCH] Fixed crash caused by Facebook Beta Shopify Connector (#119) - Facebook's beta connector introduced a null receipt in the transaction object from Shopify - This patch handles the null case for a receipt in a transaction, preventing a crash --- tap_shopify/streams/transactions.py | 47 ++++++++++--------- .../test_transaction_canonicalize.py | 6 +++ 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/tap_shopify/streams/transactions.py b/tap_shopify/streams/transactions.py index c6b56665..6316e5bb 100644 --- a/tap_shopify/streams/transactions.py +++ b/tap_shopify/streams/transactions.py @@ -23,29 +23,34 @@ # their values are not equal def canonicalize(transaction_dict, field_name): field_name_upper = field_name.capitalize() - value_lower = transaction_dict.get('receipt', {}).get(field_name) - value_upper = transaction_dict.get('receipt', {}).get(field_name_upper) - if value_lower and value_upper: - if value_lower == value_upper: - LOGGER.info(( - "Transaction (id=%d) contains a receipt " - "that has `%s` and `%s` keys with the same " - "value. Removing the `%s` key."), + # Not all Shopify transactions have receipts. Facebook has been shown + # to push a null receipt through the transaction + receipt = transaction_dict.get('receipt', {}) + if receipt: + value_lower = receipt.get(field_name) + value_upper = receipt.get(field_name_upper) + if value_lower and value_upper: + if value_lower == value_upper: + LOGGER.info(( + "Transaction (id=%d) contains a receipt " + "that has `%s` and `%s` keys with the same " + "value. Removing the `%s` key."), + transaction_dict['id'], + field_name, + field_name_upper, + field_name_upper) + transaction_dict['receipt'].pop(field_name_upper) + else: + raise ValueError(( + "Found Transaction (id={}) with a receipt that has " + "`{}` and `{}` keys with the different " + "values. Contact Shopify/PayPal support.").format( transaction_dict['id'], - field_name, field_name_upper, - field_name_upper) - transaction_dict['receipt'].pop(field_name_upper) - else: - raise ValueError(( - "Found Transaction (id={}) with a receipt that has " - "`{}` and `{}` keys with the different " - "values. Contact Shopify/PayPal support.").format( - transaction_dict['id'], - field_name_upper, - field_name)) - elif value_upper: - transaction_dict["receipt"][field_name] = transaction_dict['receipt'].pop(field_name_upper) + field_name)) + elif value_upper: + # pylint: disable=line-too-long + transaction_dict["receipt"][field_name] = transaction_dict['receipt'].pop(field_name_upper) class Transactions(Stream): diff --git a/tests/unittests/test_transaction_canonicalize.py b/tests/unittests/test_transaction_canonicalize.py index fe1168a2..fb1ab5d3 100644 --- a/tests/unittests/test_transaction_canonicalize.py +++ b/tests/unittests/test_transaction_canonicalize.py @@ -22,6 +22,12 @@ def test_lowercases_if_capital_only_exists(self): canonicalize(record, "foo") self.assertEqual(record, expected_record) + def test_null_receipt_record(self): + record = {"receipt": None} + expected_record = {"receipt": None} + canonicalize(record, "foo") + self.assertEqual(record, expected_record) + def test_removes_uppercase_if_both_exist_and_are_equal(self): record = {"receipt": {"Foo": "bar", "foo": "bar"}, "id": 2} expected_record = {"receipt": {"foo": "bar"}, "id": 2}