From d216fe5f82e2978af34d93a62afa3e2bf55868d4 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 19 Sep 2026 17:17:02 +0000 Subject: [PATCH 1/2] feat: add partner settings methods Co-authored-by: myles.foster --- test/unit/testPartner.py | 56 +++++++++++++++++++++++++++++++++ trolley/gateway.py | 2 ++ trolley/partner_gateway.py | 64 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 test/unit/testPartner.py create mode 100644 trolley/partner_gateway.py diff --git a/test/unit/testPartner.py b/test/unit/testPartner.py new file mode 100644 index 0000000..8ee1d10 --- /dev/null +++ b/test/unit/testPartner.py @@ -0,0 +1,56 @@ +import unittest +from unittest.mock import MagicMock, patch + +from trolley.configuration import Configuration + + +class TestPartnerGateway(unittest.TestCase): + + @patch('trolley.partner_gateway.trolley.configuration.Configuration.client') + def test_dedicated_partner_methods_call_expected_endpoints(self, client_factory): + client = MagicMock() + client_factory.return_value = client + partner = Configuration.gateway('access', 'secret').partner + body = {'enabled': True} + + partner.get_fees() + partner.update_fees(body) + partner.list_payout_methods() + partner.get_payout_method('bank-transfer') + partner.update_payout_method('bank-transfer', body) + partner.get_processing_settings() + partner.update_processing_settings(body) + partner.get_white_label_dns_records() + partner.verify_white_label_dns_records() + partner.delete_white_label_email() + partner.update_white_label_icon(body) + partner.get_white_label_settings() + partner.update_white_label_settings(body) + partner.get_widget_configuration() + partner.update_widget_configuration(body) + + self.assertEqual([ + unittest.mock.call('/v1/fees'), + unittest.mock.call('/v1/payout-methods'), + unittest.mock.call('/v1/payout-methods/bank-transfer'), + unittest.mock.call('/v1/processing-settings'), + unittest.mock.call('/v1/white-label/dns-records'), + unittest.mock.call('/v1/white-label'), + unittest.mock.call('/v1/iframe/config'), + ], client.get.call_args_list) + self.assertEqual([ + unittest.mock.call('/v1/fees', body), + unittest.mock.call('/v1/payout-methods/bank-transfer', body), + unittest.mock.call('/v1/processing-settings', body), + unittest.mock.call('/v1/white-label/icon', body), + unittest.mock.call('/v1/white-label', body), + ], client.patch.call_args_list) + self.assertEqual([ + unittest.mock.call('/v1/white-label/dns-records/verify', {}), + unittest.mock.call('/v1/iframe/config', body), + ], client.post.call_args_list) + client.delete.assert_called_once_with('/v1/white-label/email') + + +if __name__ == '__main__': + unittest.main() diff --git a/trolley/gateway.py b/trolley/gateway.py index e55bb38..ceb69ea 100644 --- a/trolley/gateway.py +++ b/trolley/gateway.py @@ -8,6 +8,7 @@ from trolley.invoice_line_gateway import InvoiceLineGateway from trolley.invoice_payment_gateway import InvoicePaymentGateway from trolley.verification_gateway import VerificationGateway +from trolley.partner_gateway import PartnerGateway import trolley.configuration @@ -35,6 +36,7 @@ def __init__(self, config=None, **kwargs): self.invoice_payment = InvoicePaymentGateway(self, config) self.verification = VerificationGateway(self, config) self.trust = self.verification + self.partner = PartnerGateway(self, config) def request(self, method, endpoint, body=None): return trolley.configuration.Configuration.client(self.config).request(method, endpoint, body) \ No newline at end of file diff --git a/trolley/partner_gateway.py b/trolley/partner_gateway.py new file mode 100644 index 0000000..19d4112 --- /dev/null +++ b/trolley/partner_gateway.py @@ -0,0 +1,64 @@ +from urllib.parse import quote + +import trolley.configuration + + +class PartnerGateway(object): + """Trolley partner settings processor.""" + + def __init__(self, gateway, config): + self.gateway = gateway + self.config = gateway.config + + def _client(self): + return trolley.configuration.Configuration.client(self.config) + + def get_fees(self): + return self._client().get('/v1/fees') + + def update_fees(self, body): + return self._client().patch('/v1/fees', body) + + def list_payout_methods(self): + return self._client().get('/v1/payout-methods') + + def get_payout_method(self, payout_method): + return self._client().get( + '/v1/payout-methods/{}'.format(quote(payout_method, safe='')) + ) + + def update_payout_method(self, payout_method, body): + return self._client().patch( + '/v1/payout-methods/{}'.format(quote(payout_method, safe='')), + body + ) + + def get_processing_settings(self): + return self._client().get('/v1/processing-settings') + + def update_processing_settings(self, body): + return self._client().patch('/v1/processing-settings', body) + + def get_white_label_dns_records(self): + return self._client().get('/v1/white-label/dns-records') + + def verify_white_label_dns_records(self): + return self._client().post('/v1/white-label/dns-records/verify', {}) + + def delete_white_label_email(self): + return self._client().delete('/v1/white-label/email') + + def update_white_label_icon(self, body): + return self._client().patch('/v1/white-label/icon', body) + + def get_white_label_settings(self): + return self._client().get('/v1/white-label') + + def update_white_label_settings(self, body): + return self._client().patch('/v1/white-label', body) + + def get_widget_configuration(self): + return self._client().get('/v1/iframe/config') + + def update_widget_configuration(self, body=None): + return self._client().post('/v1/iframe/config', body or {}) From ab62a9f116214a148737a30cf4ddb5b76ecff6c8 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 19 Sep 2026 17:20:10 +0000 Subject: [PATCH 2/2] feat: filter partner fees by currency Co-authored-by: myles.foster --- test/unit/testPartner.py | 2 ++ trolley/partner_gateway.py | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/test/unit/testPartner.py b/test/unit/testPartner.py index 8ee1d10..85203ee 100644 --- a/test/unit/testPartner.py +++ b/test/unit/testPartner.py @@ -14,6 +14,7 @@ def test_dedicated_partner_methods_call_expected_endpoints(self, client_factory) body = {'enabled': True} partner.get_fees() + partner.get_fees('USD') partner.update_fees(body) partner.list_payout_methods() partner.get_payout_method('bank-transfer') @@ -31,6 +32,7 @@ def test_dedicated_partner_methods_call_expected_endpoints(self, client_factory) self.assertEqual([ unittest.mock.call('/v1/fees'), + unittest.mock.call('/v1/fees?currency=USD'), unittest.mock.call('/v1/payout-methods'), unittest.mock.call('/v1/payout-methods/bank-transfer'), unittest.mock.call('/v1/processing-settings'), diff --git a/trolley/partner_gateway.py b/trolley/partner_gateway.py index 19d4112..6d1a8ca 100644 --- a/trolley/partner_gateway.py +++ b/trolley/partner_gateway.py @@ -13,8 +13,11 @@ def __init__(self, gateway, config): def _client(self): return trolley.configuration.Configuration.client(self.config) - def get_fees(self): - return self._client().get('/v1/fees') + def get_fees(self, currency=None): + endpoint = '/v1/fees' + if currency: + endpoint += '?currency={}'.format(quote(currency, safe='')) + return self._client().get(endpoint) def update_fees(self, body): return self._client().patch('/v1/fees', body)