From cce2ae2919107577b425b11882a512335c35936a Mon Sep 17 00:00:00 2001 From: Rafael Cabral Date: Wed, 26 Mar 2025 18:17:11 -0300 Subject: [PATCH 1/3] update card acquiring integration logs --- starkbank/merchantcard/log/__log.py | 11 +-- .../__merchantinstallment.py | 6 +- starkbank/merchantinstallment/log/__log.py | 11 +-- starkbank/merchantpurchase/log/__log.py | 11 +-- starkbank/merchantsession/log/__log.py | 11 +-- tests/sdk/test_merchant_installment_log.py | 88 ++++++++++++++---- tests/utils/card.py | 61 +++++++++++++ tests/utils/merchantPurchase.py | 91 ++++++++++++------- tests/utils/merchantSession.py | 49 +++++----- tests/utils/pooling.py | 28 ++++++ 10 files changed, 267 insertions(+), 100 deletions(-) create mode 100644 tests/utils/pooling.py diff --git a/starkbank/merchantcard/log/__log.py b/starkbank/merchantcard/log/__log.py index a0993c7b..68975830 100644 --- a/starkbank/merchantcard/log/__log.py +++ b/starkbank/merchantcard/log/__log.py @@ -26,20 +26,19 @@ def get(id, user=None): return rest.get_id(resource=_resource, id=id, user=user) -def query(limit=None, status=None, tags=None, ids=None, after=None, before=None, user=None): +def query(limit=None, card_ids=None, after=None, before=None, user=None, types=None): return rest.get_stream( resource=_resource, limit=limit, after=check_date(after), before=check_date(before), - status=status, - tags=tags, - ids=ids, + card_ids=card_ids, user=user, + types=types, ) -def page(cursor=None, limit=None, after=None, before=None, types=None, ids=None, user=None): +def page(cursor=None, limit=None, card_ids=None, after=None, before=None, user=None, types=None): return rest.get_page( resource=_resource, cursor=cursor, @@ -47,7 +46,7 @@ def page(cursor=None, limit=None, after=None, before=None, types=None, ids=None, after=check_date(after), before=check_date(before), types=types, - ids=ids, + card_ids=card_ids, user=user, ) diff --git a/starkbank/merchantinstallment/__merchantinstallment.py b/starkbank/merchantinstallment/__merchantinstallment.py index 83c2bf66..8af224ba 100644 --- a/starkbank/merchantinstallment/__merchantinstallment.py +++ b/starkbank/merchantinstallment/__merchantinstallment.py @@ -32,7 +32,7 @@ def get(id, user=None): return rest.get_id(resource=_resource, id=id, user=user) -def query(limit=None, after=None, before=None, status=None, tags=None, ids=None, user=None): +def query(limit=None, after=None, before=None, status=None, tags=None, ids=None, user=None, purchase_ids=None): return rest.get_stream( resource=_resource, limit=limit, @@ -42,10 +42,11 @@ def query(limit=None, after=None, before=None, status=None, tags=None, ids=None, tags=tags, ids=ids, user=user, + purchase_ids=purchase_ids, ) -def page(cursor=None, limit=None, after=None, before=None, status=None, tags=None, ids=None, user=None): +def page(cursor=None, limit=None, after=None, before=None, status=None, tags=None, ids=None, user=None, purchase_ids=None): return rest.get_page( resource=_resource, cursor=cursor, @@ -56,5 +57,6 @@ def page(cursor=None, limit=None, after=None, before=None, status=None, tags=Non tags=tags, ids=ids, user=user, + purchase_ids=purchase_ids, ) diff --git a/starkbank/merchantinstallment/log/__log.py b/starkbank/merchantinstallment/log/__log.py index b1fbfcc9..2db81c50 100644 --- a/starkbank/merchantinstallment/log/__log.py +++ b/starkbank/merchantinstallment/log/__log.py @@ -26,20 +26,19 @@ def get(id, user=None): return rest.get_id(resource=_resource, id=id, user=user) -def query(limit=None, status=None, tags=None, ids=None, after=None, before=None, user=None): +def query(limit=None, after=None, before=None, types=None, user=None, installment_ids=None): return rest.get_stream( resource=_resource, limit=limit, after=check_date(after), before=check_date(before), - status=status, - tags=tags, - ids=ids, + types=types, user=user, + installment_ids=installment_ids, ) -def page(cursor=None, limit=None, after=None, before=None, types=None, ids=None, user=None): +def page(cursor=None, limit=None, after=None, before=None, types=None, user=None, installment_ids=None): return rest.get_page( resource=_resource, cursor=cursor, @@ -47,7 +46,7 @@ def page(cursor=None, limit=None, after=None, before=None, types=None, ids=None, after=check_date(after), before=check_date(before), types=types, - ids=ids, user=user, + installment_ids=installment_ids, ) diff --git a/starkbank/merchantpurchase/log/__log.py b/starkbank/merchantpurchase/log/__log.py index b19bd90f..3ddcc4dd 100644 --- a/starkbank/merchantpurchase/log/__log.py +++ b/starkbank/merchantpurchase/log/__log.py @@ -26,19 +26,18 @@ def get(id, user=None): return rest.get_id(resource=_resource, id=id, user=user) -def query(limit=None, status=None, tags=None, ids=None, after=None, before=None, user=None): +def query(limit=None, after=None, before=None, types=None, user=None, purchase_ids=None): return rest.get_stream( resource=_resource, limit=limit, after=check_date(after), before=check_date(before), - status=status, - tags=tags, - ids=ids, + types=types, user=user, + purchase_ids=purchase_ids, ) -def page(cursor=None, limit=None, after=None, before=None, types=None, ids=None, user=None): +def page(cursor=None, limit=None, after=None, before=None, types=None, user=None, purchase_ids=None): return rest.get_page( resource=_resource, cursor=cursor, @@ -46,7 +45,7 @@ def page(cursor=None, limit=None, after=None, before=None, types=None, ids=None, after=check_date(after), before=check_date(before), types=types, - ids=ids, user=user, + purchase_ids=purchase_ids, ) diff --git a/starkbank/merchantsession/log/__log.py b/starkbank/merchantsession/log/__log.py index 3a7ee030..e14bb0b9 100644 --- a/starkbank/merchantsession/log/__log.py +++ b/starkbank/merchantsession/log/__log.py @@ -25,20 +25,19 @@ def get(id, user=None): return rest.get_id(resource=_resource, id=id, user=user) -def query(limit=None, status=None, tags=None, ids=None, after=None, before=None, user=None): +def query(limit=None, after=None, before=None, types=None, session_ids=None, user=None): return rest.get_stream( resource=_resource, limit=limit, after=check_date(after), before=check_date(before), - status=status, - tags=tags, - ids=ids, + types=types, + session_ids=session_ids, user=user, ) -def page(cursor=None, limit=None, after=None, before=None, types=None, ids=None, user=None): +def page(cursor=None, limit=None, after=None, before=None, types=None, session_ids=None, user=None): return rest.get_page( resource=_resource, cursor=cursor, @@ -46,7 +45,7 @@ def page(cursor=None, limit=None, after=None, before=None, types=None, ids=None, after=check_date(after), before=check_date(before), types=types, - ids=ids, + session_ids=session_ids, user=user, ) diff --git a/tests/sdk/test_merchant_installment_log.py b/tests/sdk/test_merchant_installment_log.py index fd6f2649..3130a1fb 100644 --- a/tests/sdk/test_merchant_installment_log.py +++ b/tests/sdk/test_merchant_installment_log.py @@ -1,5 +1,11 @@ +import datetime import starkbank from unittest import TestCase, main +from tests.utils.pooling import wait_for_query +from tests.utils.merchantSession import generate_example_merchant_session +from tests.utils.merchantPurchase import generate_example_merchant_purchase + + from tests.utils.user import exampleProject @@ -8,38 +14,80 @@ class TestMerchantInstallmentQueryLog(TestCase): - def test_success(self): - merchant_installment_logs = starkbank.merchantinstallment.log.query(limit=3) - for log in merchant_installment_logs: - print(log) - self.assertIsInstance(log.id, str) + def setUp(self): + self.merchant_installment_ids = [] + self.before_date = datetime.date.today() + self.after_date = self.before_date - datetime.timedelta(days=2) + merchant_tags = ["test_merchat_installment_query_log"] + merchant_session = generate_example_merchant_session( + tags=merchant_tags, challenge_mode="disabled" + ) + self.merchant_purchase = generate_example_merchant_purchase( + merchant_session=merchant_session + ) + merchant_installments = wait_for_query( + starkbank.merchantinstallment.query, + purchase_ids=[self.merchant_purchase.id], + ) + for merchant_installment in merchant_installments: + self.merchant_installment_ids.append(merchant_installment.id) -class TestMerchantInstallmentGetLog(TestCase): + def test_query_log(self): + merchant_installment_logs = starkbank.merchantinstallment.log.query( + installment_ids=self.merchant_installment_ids, + limit=1, + after=self.after_date, + before=self.before_date, + ) + for log in merchant_installment_logs: + self.assertEqual(log.installment.purchase_id, self.merchant_purchase.id) - def test_success(self): + def test_get_log_by_id(self): merchant_installment_logs = starkbank.merchantinstallment.log.query(limit=3) for log in merchant_installment_logs: - print(log.id) - log = starkbank.merchantinstallment.log.get(log.id) - self.assertIsInstance(log.id, str) - - -class TestMerchantInstallmentPageLog(TestCase): + merchant_installment_log = starkbank.merchantinstallment.log.get(log.id) + self.assertEqual(log.id, merchant_installment_log.id) - def test_success(self): - ids = [] + def test_page_with_filters(self): cursor = None - for _ in range(2): - page, cursor = starkbank.merchantinstallment.log.page(limit=5, cursor=cursor) + limit = 2 + while True: + ids = [] + page, cursor = starkbank.merchantinstallment.log.page( + limit=limit, + cursor=cursor, + after=self.after_date, + before=self.before_date, + installment_ids=self.merchant_installment_ids, + ) for entity in page: self.assertNotIn(entity.id, ids) + self.assertIn(entity.installment.purchase_id, self.merchant_purchase.id) ids.append(entity.id) + + self.assertEqual(len(ids), limit) + if cursor is None: break - self.assertEqual(len(ids), 10) + def test_query_by_type(self): + type = "created" + merchant_installment_logs = starkbank.merchantinstallment.log.query( + types=[type], + limit=1, + after=self.after_date, + before=self.before_date, + ) + for log in merchant_installment_logs: + self.assertEqual(log.type, type) + + def test_page_filter_by_type(self): + type = "created" + page, _ = starkbank.merchantinstallment.log.page(types=[type]) + for entity in page: + self.assertEqual(entity.type, type) -if __name__ == '__main__': - main() +if __name__ == "__main__": + main() diff --git a/tests/utils/card.py b/tests/utils/card.py index fc68fc6c..525e5b48 100644 --- a/tests/utils/card.py +++ b/tests/utils/card.py @@ -1,3 +1,4 @@ +from random import choice from starkbank import CorporateCard @@ -9,3 +10,63 @@ def generateExampleCardJson(holder): example_card.holder_id = holder.id return example_card + + +debitCards = [ + { + "expiration": "2035-01", + "card_number": "5277696455399733", + "card_security_code": "123", + }, + { + "expiration": "2035-01", + "card_number": "2223000148400010", + "card_security_code": "123", + }, + { + "expiration": "2035-01", + "card_number": "4761120000000148", + "card_security_code": "123", + }, + { + "expiration": "2035-01", + "card_number": "4824810010000006", + "card_security_code": "123", + }, + { + "expiration": "2035-01", + "card_number": "5204970000000007", + "card_security_code": "123", + }, +] + +creditCards = [ + { + "expiration": "2035-01", + "card_number": "5448280000000007", + "card_security_code": "123", + }, + { + "expiration": "2035-01", + "card_number": "4235647728025682", + "card_security_code": "123", + }, + { + "expiration": "2035-01", + "card_number": "6062825624254001", + "card_security_code": "123", + }, + { + "expiration": "2035-01", + "card_number": "36490101441625", + "card_security_code": "123", + }, +] + + +def randomCreditCard(): + return choice(creditCards) + + +def randomDebitCard(): + return choice(debitCards) diff --git a/tests/utils/merchantPurchase.py b/tests/utils/merchantPurchase.py index 7af6dfa7..341bb70f 100644 --- a/tests/utils/merchantPurchase.py +++ b/tests/utils/merchantPurchase.py @@ -2,6 +2,39 @@ import starkbank from copy import deepcopy from starkbank import MerchantPurchase +from tests.utils.card import randomCreditCard + + +def generate_example_merchant_purchase(merchant_session): + credit_card = randomCreditCard() + merchant_purchase = starkbank.merchantsession.purchase( + uuid=merchant_session.uuid, + purchase=starkbank.merchantsession.Purchase( + amount=5500, + holder_name="Rhaenyra Targaryen", + holder_email="rhaenyra.targaryen@gmail.com", + holder_phone="11223344556", + funding_type="credit", + billing_country_code="BRA", + billing_city="Sao Paulo", + billing_state_code="SP", + billing_street_line_1="Rua Casterly Rock, 2000", + billing_street_line_2="1 andar", + billing_zip_code="01450-000", + metadata={ + "userAgent": "Mozilla", + "userIp": "255.255.255.255", + "language": "pt-BR", + "timezoneOffset": 3, + "extraData": "extraData", + }, + card_expiration=credit_card["expiration"], + card_number=credit_card["card_number"], + card_security_code=credit_card["card_security_code"], + installment_count=2, + ), + ) + return merchant_purchase def json_to_merchant_purchase(json_data): @@ -22,7 +55,7 @@ def json_to_merchant_purchase(json_data): billing_street_line_2=json_data.get("billingStreetLine2"), billing_zip_code=json_data.get("billingZipCode"), metadata=json_data.get("metadata"), - card_id=json_data.get("cardId") + card_id=json_data.get("cardId"), ) @@ -47,8 +80,8 @@ def json_to_merchant_purchase(json_data): "userIp": "255.255.255.255", "language": "pt-BR", "timezoneOffset": 3, - "extraData": "extraData" - } + "extraData": "extraData", + }, } merchant_purchase = json_to_merchant_purchase(json_data) @@ -56,38 +89,32 @@ def json_to_merchant_purchase(json_data): def generate_example_merchant_purchase_json(card_id): merchant_purchase_json = { - "amount": 10000, - "installmentCount": 5, - "cardId": card_id, - "fundingType": "credit", - "challengeMode": "disabled", - "billingCity": "Sao Paulo", - "billingCountryCode": "BRA", - "billingStateCode": "SP", - "billingStreetLine1": "Rua do Holder Name, 123", - "billingStreetLine2": "1 andar", - "billingZipCode": "11111-111", - "holderEmail": "holdeName@email.com", - "holderPhone": "11111111111", - "metadata": { - "userAgent": "userAgent", - "userIp": "255.255.255.255", - "language": "pt-BR", - "timezoneOffset": 3, - "extraData": "extraData" - }, - "tags": [ - "teste" - ] - } + "amount": 10000, + "installmentCount": 5, + "cardId": card_id, + "fundingType": "credit", + "challengeMode": "disabled", + "billingCity": "Sao Paulo", + "billingCountryCode": "BRA", + "billingStateCode": "SP", + "billingStreetLine1": "Rua do Holder Name, 123", + "billingStreetLine2": "1 andar", + "billingZipCode": "11111-111", + "holderEmail": "holdeName@email.com", + "holderPhone": "11111111111", + "metadata": { + "userAgent": "userAgent", + "userIp": "255.255.255.255", + "language": "pt-BR", + "timezoneOffset": 3, + "extraData": "extraData", + }, + "tags": ["teste"], + } return deepcopy(json_to_merchant_purchase(merchant_purchase_json)) def generate_example_merchant_purchase_patch(): - merchant_purchase_json = { - "status": "reversed", - "amount": 0 - } + merchant_purchase_json = {"status": "reversed", "amount": 0} return deepcopy(merchant_purchase_json) - diff --git a/tests/utils/merchantSession.py b/tests/utils/merchantSession.py index 1f9b3fe6..2e756aa1 100644 --- a/tests/utils/merchantSession.py +++ b/tests/utils/merchantSession.py @@ -1,6 +1,26 @@ # coding: utf-8 +import starkbank from copy import deepcopy from starkbank import MerchantSession +from starkbank.merchantsession import AllowedInstallment + + +def generate_example_merchant_session(tags, challenge_mode): + allowed_installments = [ + AllowedInstallment(total_amount=5000, count=1), + AllowedInstallment(total_amount=5500, count=2), + ] + merchant_session = starkbank.merchantsession.create( + MerchantSession( + allowed_funding_types=["debit", "credit"], + allowed_installments=allowed_installments, + expiration=3600, + challenge_mode=challenge_mode, + tags=tags, + ) + ) + + return merchant_session def json_to_merchant_session(json_data): @@ -15,29 +35,15 @@ def json_to_merchant_session(json_data): def generate_example_merchant_session_json(challengeMode): merchant_session_json = { - "allowedFundingTypes": [ - "debit", - "credit" - ], + "allowedFundingTypes": ["debit", "credit"], "allowedInstallments": [ - { - "totalAmount": 0, - "count": 1 - }, - { - "totalAmount": 120, - "count": 2 - }, - { - "totalAmount": 180, - "count": 12 - } + {"totalAmount": 0, "count": 1}, + {"totalAmount": 120, "count": 2}, + {"totalAmount": 180, "count": 12}, ], "expiration": 3600, "challengeMode": challengeMode, - "tags": [ - "yourTags" - ] + "tags": ["yourTags"], } return deepcopy(json_to_merchant_session(merchant_session_json)) @@ -77,8 +83,7 @@ def generate_example_merchant_session_purchase_challenge_mode_enabled_json(): "userIp": "255.255.255.255", "language": "pt-BR", "timezoneOffset": 3, - "extraData": "extraData" - } + "extraData": "extraData", + }, } return deepcopy(merchant_session_purchase_json) - diff --git a/tests/utils/pooling.py b/tests/utils/pooling.py new file mode 100644 index 00000000..c5e170d7 --- /dev/null +++ b/tests/utils/pooling.py @@ -0,0 +1,28 @@ +import time + +def wait_for_query(query_func, max_wait_time=10, wait_interval=0.5, *args, **kwargs): + """ + Waits until the query function (query_func) returns a valid result or until the maximum wait time is reached. + + :param query_func: The query function to be executed (e.g., starkbank.merchantinstallment.query) + :param max_wait_time: Maximum time to wait in seconds (default is 10 seconds) + :param wait_interval: Time interval between query attempts in seconds (default is 0.5 seconds) + :param args: Positional arguments to be passed to the query function + :param kwargs: Keyword arguments to be passed to the query function + :return: The result of the query function if successful within the maximum wait time + :raises TimeoutError: If the maximum wait time is exceeded without a valid result + """ + start_time = time.time() + + while True: + result = query_func(*args, **kwargs) + + result_list = list(result) + + if result_list: + return result_list + + if time.time() - start_time > max_wait_time: + raise TimeoutError("Query did not return a result within the expected time.") + + time.sleep(wait_interval) From 8590211e3db866821521a9f16e5ca5bedb0725b9 Mon Sep 17 00:00:00 2001 From: Rafael Cabral Date: Thu, 27 Mar 2025 20:06:31 -0300 Subject: [PATCH 2/3] update changelog.md --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4f7f417..eca02e65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,15 @@ Given a version number MAJOR.MINOR.PATCH, increment: ## [Unreleased] +### Added +- Support for filtering by `card_ids` and `types` in `query` and `page` functions for `merchantcard/log`. +- Support for filtering by `purchase_ids` in `query` and `page` functions for `merchantinstallment`. +- Support for filtering by `installment_ids` and `types` in `query` and `page` functions for `merchantinstallment/log`. +- Support for filtering by `purchase_ids` and `types` in `query` and `page` functions for `merchantpurchase/log`. +- Support for filtering by `session_ids` and `types` in `query` and `page` functions for `merchantsession/log`. + +### Changed +- Removed filters for `status`, `tags`, and `ids` from `query` and `page` functions in `merchantcard/log`, `merchantinstallment`, `merchantinstallment/log`, `merchantpurchase/log`, and `merchantsession/log`. ## [2.28.0] - 2025-03-02 ### Added From 29f82e7afa77365c6307782f3b67792bfb8de5a6 Mon Sep 17 00:00:00 2001 From: Rafael Cabral Date: Mon, 31 Mar 2025 18:43:56 -0300 Subject: [PATCH 3/3] update changelog.md --- CHANGELOG.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eca02e65..2406e8b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,14 +14,14 @@ Given a version number MAJOR.MINOR.PATCH, increment: ## [Unreleased] ### Added -- Support for filtering by `card_ids` and `types` in `query` and `page` functions for `merchantcard/log`. -- Support for filtering by `purchase_ids` in `query` and `page` functions for `merchantinstallment`. -- Support for filtering by `installment_ids` and `types` in `query` and `page` functions for `merchantinstallment/log`. -- Support for filtering by `purchase_ids` and `types` in `query` and `page` functions for `merchantpurchase/log`. -- Support for filtering by `session_ids` and `types` in `query` and `page` functions for `merchantsession/log`. +- support for filtering by 'card_ids' and 'types' in 'query' and 'page' functions for 'MerchantCardLog' +- support for filtering by 'purchase_ids' in 'query' and 'page' functions for 'MerchantInstallment' +- support for filtering by 'installment_ids' and 'types' in 'query' and 'page' functions for 'MerchantInstallmentLog' +- support for filtering by 'purchase_ids' and 'types' in 'query' and 'page' functions for 'MerchantPurchaseLog' +- support for filtering by 'session_ids' and 'types' in 'query' and 'page' functions for 'MerchantSessionLog' -### Changed -- Removed filters for `status`, `tags`, and `ids` from `query` and `page` functions in `merchantcard/log`, `merchantinstallment`, `merchantinstallment/log`, `merchantpurchase/log`, and `merchantsession/log`. +### Removed +- filters for 'status', 'tags' and 'ids' from 'query' and 'page' functions in 'MerchantCardLog', 'MerchantInstallment', 'MerchantInstallmentLog', 'MerchantPurchaseLog' and 'MerchantSessionLog' ## [2.28.0] - 2025-03-02 ### Added