Skip to content

Commit 7ccd353

Browse files
committed
refacto Request + tests
1 parent aaf6a6f commit 7ccd353

File tree

6 files changed

+242
-55
lines changed

6 files changed

+242
-55
lines changed

poetry.lock

Lines changed: 114 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ isort = "^5.6.4"
2525
pytest = "^6.2.1"
2626
flake8 = "^3.8.4"
2727
pre-commit = "^2.9.3"
28+
pytest-cov = "^2.10.1"
29+
mypy = "^0.790"
2830

2931
[build-system]
3032
requires = ["poetry-core>=1.0.0"]

redsys/client.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ class Client(object):
2424
def __init__(self, secret_key=None):
2525
self.secret_key = secret_key
2626

27-
def create_request(self):
28-
return Request()
29-
3027
@abstractmethod
3128
def create_response(
3229
self, signature, parameters, signature_version=DEFAULT_SIGNATURE_VERSION
@@ -70,9 +67,10 @@ def generate_signature(self, order, merchant_parameters):
7067

7168

7269
class RedirectClient(Client):
73-
def prepare_request(self, request):
70+
def prepare_request(self, parameters):
7471
"""Takes the merchant parameters and returns the necessary parameters
7572
to make the POST request to Redsys"""
73+
request = Request(parameters)
7674
merchant_parameters = self.encode_parameters(request.prepare_parameters())
7775
signature = self.generate_signature(request.order, merchant_parameters)
7876
return {

redsys/request.py

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import re
22
from decimal import Decimal
3+
from typing import Dict
34

45
from redsys.constants import CURRENCIES, LANGUAGES, TRANSACTIONS
56

@@ -61,26 +62,29 @@
6162
}
6263

6364

64-
class Request(object):
65+
class Request:
6566
"""
6667
Defines an atomic request with all the required parameters and sanitize
6768
their values according to the platform specifications
6869
"""
6970

7071
_parameters = {}
7172

72-
def __getattr__(self, item):
73+
def __init__(self, parameters: Dict[str, str]) -> None:
74+
for key in parameters.keys():
75+
if key in MERCHANT_PARAMETERS_MAP:
76+
check = getattr(self, "check_%s" % key, None)
77+
if check:
78+
check(parameters[key])
79+
self._parameters[key] = parameters[key]
80+
else:
81+
raise ValueError(f"Unknown parameter {key}")
82+
83+
def __getattr__(self, item: str) -> str:
7384
if item in MERCHANT_PARAMETERS_MAP:
7485
return self._parameters[item]
7586

76-
def __setattr__(self, key, value):
77-
if key in MERCHANT_PARAMETERS_MAP:
78-
check = getattr(self, "check_%s" % key, None)
79-
if check:
80-
check(value)
81-
self._parameters[key] = value
82-
83-
def prepare_parameters(self):
87+
def prepare_parameters(self) -> Dict[str, str]:
8488
parameters = {}
8589
for key, value in self._parameters.items():
8690
prepare = getattr(self, "prepare_%s" % key, None)
@@ -89,48 +93,60 @@ def prepare_parameters(self):
8993
)
9094
return parameters
9195

92-
def prepare_amount(self, value):
96+
@staticmethod
97+
def prepare_amount(value):
9398
return int(value * 100)
9499

95-
def prepare_sum_total(self, value):
100+
@staticmethod
101+
def prepare_sum_total(value):
96102
return int(value * 100)
97103

98-
def check_order(self, value):
104+
@staticmethod
105+
def check_order(value):
99106
if not re.match(r"[0-9]{4}[a-zA-Z0-9]{5}$", value):
100107
raise ValueError("order format is not valid.")
101108

102-
def check_transaction_type(self, value):
109+
@staticmethod
110+
def check_transaction_type(value):
103111
if value not in TRANSACTIONS:
104112
raise ValueError("transaction_type is not valid.")
105113

106-
def check_currency(self, value):
114+
@staticmethod
115+
def check_currency(value):
107116
if value not in CURRENCIES:
108117
raise ValueError("currency is not valid.")
109118

110-
def check_amount(self, value):
119+
@staticmethod
120+
def check_amount(value):
111121
if not isinstance(value, Decimal):
112122
raise TypeError("amount must be defined as decimal.Decimal.")
113123

114-
def check_sum_total(self, value):
124+
@staticmethod
125+
def check_sum_total(value):
115126
if type(value) is not Decimal:
116127
raise TypeError("sum_total must be defined as decimal.Decimal.")
117128

118-
def check_merchant_data(self, value):
129+
@staticmethod
130+
def check_merchant_data(value):
119131
if len(value) > 1024:
120132
raise ValueError("merchant_data is bigger than 1024 characters.")
121133

122-
def check_merchant_url(self, value):
134+
@staticmethod
135+
def check_merchant_url(value):
123136
if len(value) > 250:
124137
raise ValueError("merchant_url is bigger than 250 characters.")
125138

126-
def check_url_ok(self, value):
139+
@staticmethod
140+
def check_url_ok(value):
127141
if len(value) > 250:
128142
raise ValueError("url_ok is bigger than 250 characters.")
129143

130-
def check_url_ko(self, value):
144+
@staticmethod
145+
def check_url_ko(value):
131146
if len(value) > 250:
132147
raise ValueError("url_ko is bigger than 250 characters.")
133148

134-
def check_consumer_language(self, value):
149+
@staticmethod
150+
def check_consumer_language(value):
135151
if value not in LANGUAGES:
136152
raise ValueError("consumer_language is not valid.")

0 commit comments

Comments
 (0)