Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions omise/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def iteritems(d, **kw):
'Balance',
'BankAccount',
'Card',
'Chain',
'Charge',
'Collection',
'Customer',
Expand Down Expand Up @@ -65,6 +66,7 @@ def _get_class_for(type):
'balance': Balance,
'bank_account': BankAccount,
'card': Card,
'chain': Chain,
'charge': Charge,
'customer': Customer,
'dispute': Dispute,
Expand Down Expand Up @@ -538,6 +540,82 @@ def destroyed(self):
return self._attributes.get('deleted', False)


class Chain(_MainResource, Base):
"""API class representing chain details.

This API class is used for retrieving and revoking chains. Chains represent
sub-merchant accounts which have authorized another account to create
charges and perform other actions on their behalf.

Basic usage::

>>> import omise
>>> omise.api_secret = 'skey_test_4xs8breq3htbkj03d2x'
>>> chain = omise.Chain.retrieve('acch_test_5lals6ot3vlz6lsnfhn')
<Chain id='acch_test_5lals6ot3vlz6lsnfhn' at 0x7fd6689af450>
>>> chain.email
'john.doe@example.com'
"""

@classmethod
def _collection_path(cls):
return 'chains'

@classmethod
def _instance_path(cls, chain_id):
return ('chains', chain_id)

@classmethod
def retrieve(cls, chain_id=None):
"""Retrieve the sub-merchant chain details for the given
:param:`chain_id`. If :param:`chain_id` is not given, all sub-merchant
chains will be returned instead.

:param chain_id: (optional) a chain id to retrieve.
:type chain_id: str
:rtype: Chain
"""
if chain_id:
return _as_object(cls._request('get', cls._instance_path(chain_id)))
return _as_object(cls._request('get', cls._collection_path()))

@classmethod
def list(cls):
"""Return a list of sub-merchant chains belonging to your account.

:rtype: LazyCollection
"""
return LazyCollection(cls._collection_path())

def reload(self):
"""Reload the sub-merchant chain details.

:rtype: Chain
"""
return self._reload_data(
self._request('get',
self._instance_path(self._attributes['id'])))

def revoke(self):
"""Revoke the sub-merchant chain.

Basic usage::

>>> import omise
>>> omise.api_secret = 'skey_test_4xs8breq3htbkj03d2x'
>>> chain = omise.Chain.retrieve('acch_test_5lals6ot3vlz6lsnfhn')
>>> chain.revoke()
<Chain id='acch_test_5lals6ot3vlz6lsnfhn' at 0x7f9c60abdc90>
>>> chain.revoked
True

:rtype: Chain
"""

path = self._instance_path(self._attributes['id']) + ('revoke',)
return self._reload_data(self._request('post', path))


class Charge(_MainResource, Base):
"""API class representing a charge.

Expand Down
144 changes: 144 additions & 0 deletions omise/test/test_chain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import mock
import unittest

from .helper import _ResourceMixin


class ChainTest(_ResourceMixin, unittest.TestCase):

def _getTargetClass(self):
from .. import Chain
return Chain

def _getCollectionClass(self):
from .. import Collection
return Collection

def _makeOne(self):
return self._getTargetClass().from_data({
'object': 'chain',
'id': 'acch_test',
'livemode': False,
'location': '/chains/acch_test',
'revoked': False,
'email': 'john.doe@example.com',
'key': 'ckey_test',
'created': '2021-02-02T03:12:43Z'
})

@mock.patch('requests.get')
def test_retrieve(self, api_call):
class_ = self._getTargetClass()
self.mockResponse(api_call, """{
"object": "chain",
"id": "acch_test",
"livemode": false,
"location": "/chains/acch_test",
"revoked": false,
"email": "john.doe@example.com",
"key": "ckey_test",
"created": "2021-02-02T03:12:43Z"
}""")

chain = class_.retrieve('acch_test')
self.assertTrue(isinstance(chain, class_))
self.assertEqual(chain.id, 'acch_test')
self.assertEqual(chain.email, 'john.doe@example.com')
self.assertEqual(chain.key, 'ckey_test')
self.assertFalse(chain.revoked)
self.assertRequest(api_call, 'https://api.omise.co/chains/acch_test')

@mock.patch('requests.get')
def test_retrieve_no_args(self, api_call):
class_ = self._getTargetClass()
collection_class_ = self._getCollectionClass()
self.mockResponse(api_call, """{
"object": "list",
"data": [
{
"object": "chain",
"id": "acch_test_1",
"livemode": false,
"location": "/chains/acch_test_1",
"revoked": true,
"email": "jenny.doe@example.com",
"key": "",
"created_at": "2020-09-22T06:08:38Z"
},
{
"object": "chain",
"id": "acch_test_2",
"livemode": false,
"location": "/chains/acch_test_2",
"revoked": false,
"email": "john.doe@example.com",
"key": "ckey_test",
"created_at": "2021-02-02T03:12:43Z"
}
],
"limit": 20,
"offset": 0,
"total": 2,
"location": null,
"order": "chronological",
"from": "1970-01-01T00:00:00Z",
"to": "2021-02-02T03:16:57Z"
}""")

chains = class_.retrieve()
self.assertTrue(isinstance(chains, collection_class_))
self.assertTrue(isinstance(chains[0], class_))
self.assertTrue(chains[0].id, 'acch_test_1')
self.assertTrue(chains[0].email, 'jenny.doe@example.com')
self.assertTrue(chains[1].id, 'acch_test_2')
self.assertTrue(chains[1].email, 'john.doe@example.com')
self.assertRequest(api_call, 'https://api.omise.co/chains')

@mock.patch('requests.get')
def test_reload(self, api_call):
chain = self._makeOne()
class_ = self._getTargetClass()

self.assertTrue(isinstance(chain, class_))
self.assertEqual(chain.id, 'acch_test')
self.assertFalse(chain.revoked)

self.mockResponse(api_call, """{
"object": "chain",
"id": "acch_test",
"livemode": false,
"location": "/chains/acch_test",
"revoked": true,
"email": "john.doe@example.com",
"key": "ckey_test",
"created": "2021-02-02T03:12:43Z"
}""")

chain.reload()
self.assertEqual(chain.id, 'acch_test')
self.assertTrue(chain.revoked)
self.assertRequest(
api_call,
'https://api.omise.co/chains/acch_test'
)

@mock.patch('requests.post')
def test_revoke(self, api_call):
chain = self._makeOne()
class_ = self._getTargetClass()
self.mockResponse(api_call, """{
"object": "chain",
"id": "acch_test",
"livemode": false,
"revoked": true
}""")

self.assertTrue(isinstance(chain, class_))
self.assertEqual(chain.id, 'acch_test')

chain.revoke()
self.assertTrue(chain.revoked)
self.assertRequest(
api_call,
'https://api.omise.co/chains/acch_test/revoke'
)