Skip to content
This repository has been archived by the owner on Sep 15, 2023. It is now read-only.

Commit

Permalink
InvoiceTransaction (#10)
Browse files Browse the repository at this point in the history
* inicia transação!

https://docs.python.org/3/library/dataclasses.html

* adiciona complexidade de objetos nesteados

* adiciona testes

* altera o BaseImopayObj para utilizar coisas mais mágicas de datacalss

* altera testes

* faz algumas refatorações e testes
  • Loading branch information
rodrigondec authored Sep 1, 2020
1 parent ac762d4 commit 4f2e5e1
Show file tree
Hide file tree
Showing 16 changed files with 335 additions and 16 deletions.
9 changes: 6 additions & 3 deletions imopay_wrapper/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,20 @@ def __init__(self, *args, **kwargs):

@classmethod
def get_fields(cls):
return cls.__dict__.get("__annotations__", {})
return cls.__dataclass_fields__

def to_dict(self):
data = {}
for field_name, field_type in self.get_fields().items():
for field_name, field in self.get_fields().items():
value = getattr(self, field_name)

if self.is_empty_value(value):
continue

data[field_name] = field_type(value)
if isinstance(value, BaseImopayObj):
data[field_name] = value.to_dict()
else:
data[field_name] = field.type(value)
return data

@classmethod
Expand Down
72 changes: 72 additions & 0 deletions imopay_wrapper/models/transaction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from typing import List
from dataclasses import dataclass, field

from .base import BaseImopayObj


@dataclass
class BaseTransaction(BaseImopayObj):
payer: str
receiver: str
reference_id: str
amount: int
description: str


@dataclass
class Configuration(BaseImopayObj):
value: str
type: str
charge_type: str
days: str


@dataclass
class InvoiceConfigurations(BaseImopayObj):
fine: Configuration
interest: Configuration
discounts: List[Configuration] = field(default=list)

def __post_init__(self):
if isinstance(self.fine, dict):
self.fine = Configuration.from_dict(self.fine)
if isinstance(self.interest, dict):
self.interest = Configuration.from_dict(self.interest)
if self.discounts:
for i, discount in enumerate(self.discounts):
if isinstance(discount, dict):
self.discounts[i] = Configuration.from_dict(discount)

def to_dict(self):
"""
Por causa do typehint 'List' o to_dict original não funciona!
Ao invés de solucionar isso, mais fácil sobreescrever o método
no momento.
"""
data = {
"fine": self.fine.to_dict(),
"interest": self.interest.to_dict(),
"discounts": [discount.to_dict() for discount in self.discounts],
}
return data


@dataclass
class Invoice(BaseImopayObj):
expiration_date: str
limit_date: str
configurations: InvoiceConfigurations = field(default_factory=dict)

def __post_init__(self):
if isinstance(self.configurations, dict):
self.configurations = InvoiceConfigurations.from_dict(self.configurations)


@dataclass
class InvoiceTransaction(BaseTransaction):
payment_method: Invoice

def __post_init__(self):
if isinstance(self.payment_method, dict):
self.payment_method = Invoice(**self.payment_method)
2 changes: 2 additions & 0 deletions imopay_wrapper/wrapper/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from .address import AddressWrapper
from .company import CompanyWrapper
from .person import PersonWrapper
from .transaction import TransactionWrapper


class ImopayWrapper:
def __init__(self, *args, **kwargs):
self.address = AddressWrapper(*args, **kwargs)
self.company = CompanyWrapper(*args, **kwargs)
self.person = PersonWrapper(*args, **kwargs)
self.transaction = TransactionWrapper(*args, **kwargs)
4 changes: 2 additions & 2 deletions imopay_wrapper/wrapper/address.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from .base import BaseImopayWrapper
from .base import BaseImopayWrapper, CreateMixin, UpdateMixin, RetrieveMixin
from ..models.address import Address


class AddressWrapper(BaseImopayWrapper):
class AddressWrapper(BaseImopayWrapper, CreateMixin, UpdateMixin, RetrieveMixin):
"""
Wrapper para os métodos de address
"""
Expand Down
10 changes: 8 additions & 2 deletions imopay_wrapper/wrapper/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,23 +220,29 @@ def _auth(self):
return f"Api-Key {self.__imopay_api_key}"

@property
def model(self):
def action(self):
raise NotImplementedError()

@property
def action(self):
def model(self):
raise NotImplementedError()


class CreateMixin:
def create(self, data: dict):
instance = self.model(**data)
url = self._construct_url(action=self.action)
return self._post(url, instance.to_dict())


class UpdateMixin:
def update(self, identifier: str, data: dict):
instance = self.model.from_dict(data)
url = self._construct_url(action=self.action, identifier=identifier)
return self._patch(url, instance.to_dict())


class RetrieveMixin:
def retrieve(self, identifier: str):
url = self._construct_url(action=self.action, identifier=identifier)
return self._get(url)
4 changes: 2 additions & 2 deletions imopay_wrapper/wrapper/company.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from .base import BaseImopayWrapper
from .base import BaseImopayWrapper, CreateMixin, UpdateMixin, RetrieveMixin
from ..models.company import Company


class CompanyWrapper(BaseImopayWrapper):
class CompanyWrapper(BaseImopayWrapper, CreateMixin, UpdateMixin, RetrieveMixin):
"""
Wrapper para os métodos de company
"""
Expand Down
4 changes: 2 additions & 2 deletions imopay_wrapper/wrapper/person.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from .base import BaseImopayWrapper
from .base import BaseImopayWrapper, CreateMixin, UpdateMixin, RetrieveMixin
from ..models.person import Person


class PersonWrapper(BaseImopayWrapper):
class PersonWrapper(BaseImopayWrapper, CreateMixin, UpdateMixin, RetrieveMixin):
"""
Wrapper para os métodos de person
"""
Expand Down
17 changes: 17 additions & 0 deletions imopay_wrapper/wrapper/transaction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from .base import BaseImopayWrapper, RetrieveMixin
from ..models.transaction import InvoiceTransaction


class TransactionWrapper(BaseImopayWrapper, RetrieveMixin):
"""
Wrapper para os métodos de transaction
"""

@property
def action(self):
return "transactions"

def create_invoice(self, data: dict):
instance = InvoiceTransaction(**data)
url = self._construct_url(action=self.action, subaction="create_invoice")
return self._post(url, instance.to_dict())
Empty file.
14 changes: 14 additions & 0 deletions tests/models/transaction/test_configuration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from unittest import TestCase

from imopay_wrapper.models.transaction import Configuration


class ConfigurationTestCase(TestCase):
def test_1(self):
t = Configuration.from_dict(
{"value": 1, "type": "foo", "charge_type": "foo", "days": 0}
)
self.assertEqual(t.value, 1)
self.assertEqual(t.type, "foo")
self.assertEqual(t.charge_type, "foo")
self.assertEqual(t.days, 0)
31 changes: 31 additions & 0 deletions tests/models/transaction/test_invoice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from unittest import TestCase

from imopay_wrapper.models.transaction import Invoice


class InvoiceTestCase(TestCase):
def test_1(self):
t = Invoice.from_dict(
{
"configurations": {
"fine": {
"value": 1,
"type": "foo",
"charge_type": "foo",
"days": 0,
},
"interest": {
"value": 1,
"type": "foo",
"charge_type": "foo",
"days": 0,
},
"discounts": [
{"value": 1, "type": "foo", "charge_type": "foo", "days": 0}
],
}
}
)
self.assertEqual(t.configurations.fine.value, 1)
self.assertEqual(t.configurations.interest.value, 1)
self.assertEqual(t.configurations.discounts[0].value, 1)
21 changes: 21 additions & 0 deletions tests/models/transaction/test_invoice_configurations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from unittest import TestCase

from imopay_wrapper.models.transaction import InvoiceConfigurations, Configuration


class InvoiceConfigurationsTestCase(TestCase):
def test_1(self):
t = InvoiceConfigurations.from_dict(
{
"fine": Configuration.from_dict(
{"value": 1, "type": "foo", "charge_type": "foo", "days": 0}
)
}
)
self.assertEqual(t.fine.value, 1)

def test_2(self):
t = InvoiceConfigurations.from_dict(
{"fine": {"value": 1, "type": "foo", "charge_type": "foo", "days": 0}}
)
self.assertEqual(t.fine.value, 1)
46 changes: 46 additions & 0 deletions tests/models/transaction/test_invoice_tranction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from unittest import TestCase

from imopay_wrapper.models.transaction import InvoiceTransaction, BaseTransaction


class InvoiceTransactionTestCase(TestCase):
def test_0(self):
expected = set(BaseTransaction.get_fields().keys())

result = set(InvoiceTransaction.get_fields().keys())

for item in expected:
with self.subTest(item):
self.assertIn(item, result)

def test_1(self):
t = InvoiceTransaction.from_dict({})
self.assertEqual(t.payer, None)

def test_2(self):
t = InvoiceTransaction.from_dict(
{
"payment_method": {
"expiration_date": "1",
"limit_date": "2",
"configurations": {
"fine": {
"value": 1,
"type": "foo",
"charge_type": "foo",
"days": 0,
},
"interest": {
"value": 1,
"type": "foo",
"charge_type": "foo",
"days": 0,
},
"discounts": [
{"value": 1, "type": "foo", "charge_type": "foo", "days": 0}
],
},
}
}
)
self.assertEqual(t.payment_method.configurations.fine.value, 1)
9 changes: 9 additions & 0 deletions tests/models/transaction/test_transaction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from unittest import TestCase

from imopay_wrapper.models.transaction import BaseTransaction


class BaseTransactionTestCase(TestCase):
def test_(self):
t = BaseTransaction.from_dict({})
self.assertEqual(t.payer, None)
21 changes: 16 additions & 5 deletions tests/wrapper/test_base_imopay.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
from unittest import TestCase
from unittest.mock import patch, PropertyMock

from imopay_wrapper.wrapper.base import BaseImopayWrapper
from imopay_wrapper.wrapper.base import (
BaseImopayWrapper,
CreateMixin,
UpdateMixin,
RetrieveMixin,
)


class BaseImopayWrapperTestCase(TestCase):
def setUp(self):
self.client = BaseImopayWrapper()
self.client = type(
"A",
(
BaseImopayWrapper,
CreateMixin,
UpdateMixin,
RetrieveMixin,
),
{},
)()

def test_model(self):
with self.assertRaises(NotImplementedError):
Expand All @@ -17,7 +31,6 @@ def test_action(self):
self.client.action()

def test_create(self):

with patch(
"imopay_wrapper.wrapper.base.BaseImopayWrapper.model",
new_callable=PropertyMock,
Expand All @@ -39,7 +52,6 @@ def test_create(self):
)

def test_update(self):

with patch(
"imopay_wrapper.wrapper.base.BaseImopayWrapper.model",
new_callable=PropertyMock,
Expand All @@ -63,7 +75,6 @@ def test_update(self):
)

def test_retrieve(self):

with patch(
"imopay_wrapper.wrapper.base.BaseImopayWrapper.model",
new_callable=PropertyMock,
Expand Down
Loading

0 comments on commit 4f2e5e1

Please sign in to comment.