Skip to content

Commit 06b0099

Browse files
committed
core logic
1 parent 5793310 commit 06b0099

File tree

4 files changed

+127
-0
lines changed

4 files changed

+127
-0
lines changed

django_application_logic/core.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import functools
2+
3+
from django_application_logic.exceptions import ServiceException
4+
5+
6+
class PermissionResult(object):
7+
8+
def __init__(self, success, error=None):
9+
self.success = success
10+
self.error = error
11+
12+
@property
13+
def errors(self):
14+
return self.error.errors if self.error else None
15+
16+
@property
17+
def error_code(self):
18+
return self.error.error_code if self.error else None
19+
20+
def __nonzero__(self):
21+
return self.success
22+
23+
def __eq__(self, other):
24+
if isinstance(other, (bool, PermissionResult)):
25+
return bool(self) == bool(other)
26+
return False
27+
28+
def __repr__(self):
29+
return u'<PermissionResult success={} error={}>'.format(self.success, self.error)
30+
31+
32+
def validator(validation_func):
33+
def decorator(f):
34+
@functools.wraps(f)
35+
def wrapper(*args, **kwargs):
36+
validate = kwargs.pop('validate', True)
37+
if validate:
38+
validation_func(raise_exception=True, *args, **kwargs)
39+
return f(*args, **kwargs)
40+
wrapper._validator = validation_func
41+
return wrapper
42+
return decorator
43+
44+
45+
def validation_func(f):
46+
@functools.wraps(f)
47+
def wrapper(*args, **kwargs):
48+
raise_exception = kwargs.pop('raise_exception', True)
49+
try:
50+
result = f(*args, **kwargs)
51+
return PermissionResult(True if result is None else bool(result), None)
52+
except ServiceException as e:
53+
if raise_exception:
54+
raise
55+
return PermissionResult(False, e)
56+
return wrapper

django_application_logic/errors.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from django_application_logic import exceptions
2+
from six import with_metaclass
3+
4+
errors_registry = type('Errors', (), {}) # we setattr here all found errors
5+
6+
7+
class ErrorBase(object):
8+
exception_class = None
9+
10+
def __init__(self, message):
11+
self.message = message
12+
13+
14+
class NotPermitted(ErrorBase):
15+
exception_class = exceptions.OperationNotPermittedException
16+
17+
18+
class InvalidOperation(ErrorBase):
19+
exception_class = exceptions.InvalidOperationException
20+
21+
22+
class ServicesErrorsMetaclass(type):
23+
def __init__(cls, name, bases, dict):
24+
super(ServicesErrorsMetaclass, cls).__init__(name, bases, dict)
25+
for attr_name, attr in dict.items():
26+
if isinstance(attr, ErrorBase):
27+
exception = attr.exception_class(attr.message, attr_name.lower(), cls)
28+
setattr(errors_registry, attr_name, exception)
29+
setattr(cls, attr_name, exception)
30+
31+
32+
class ServicesErrors(with_metaclass(ServicesErrorsMetaclass)):
33+
pass
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class ServiceException(Exception):
2+
def __init__(self, message=None, error_code=None, errors=None):
3+
super(ServiceException, self).__init__(message)
4+
self.errors = errors
5+
self.error_code = error_code
6+
7+
8+
class InvalidOperationException(ServiceException):
9+
pass
10+
11+
12+
class OperationNotPermittedException(ServiceException):
13+
pass

django_application_logic/tests.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from django_application_logic.exceptions import InvalidOperationException, OperationNotPermittedException
2+
3+
4+
class shouldRaiseErrorCode(object):
5+
def __init__(self, error):
6+
self.error = error
7+
8+
def __enter__(self):
9+
pass
10+
11+
def __exit__(self, exc_type, exc_val, exc_tb):
12+
if exc_type is None:
13+
raise AssertionError(u"Exception has not been raised")
14+
desired_exceptions = (InvalidOperationException, OperationNotPermittedException)
15+
if exc_type not in desired_exceptions:
16+
raise AssertionError(u"Raised {} exception type where {} was expected.\nMore info:\n{}".format(
17+
exc_type, desired_exceptions, exc_tb.format_exc()))
18+
if exc_val != self.error:
19+
raise AssertionError(u'Expected error code "{}", but received "{}"'.format(self.error, exc_val))
20+
return True
21+
22+
23+
class ApplicationLogicTestMixin(object):
24+
25+
shouldRaiseErrorCode = shouldRaiseErrorCode

0 commit comments

Comments
 (0)