9
9
import unittest
10
10
import inspect
11
11
12
+ import mock
13
+
12
14
import ga4gh .frontend_exceptions as frontendExceptions
15
+ import ga4gh .frontend as frontend
16
+
17
+
18
+ class TestExceptionHandler (unittest .TestCase ):
19
+ """
20
+ Test that caught exceptions are handled correctly
21
+ """
22
+ class UnknownException (Exception ):
23
+ pass
24
+
25
+ class DummyFlask (object ):
26
+
27
+ def __call__ (self , * args ):
28
+ return TestExceptionHandler .DummyResponse ()
29
+
30
+ class DummyResponse (object ):
31
+ pass
32
+
33
+ def run (self , * args , ** kwargs ):
34
+ # patching is required because flask.jsonify throws an exception
35
+ # if not being called in a running app context
36
+ dummyFlask = self .DummyFlask ()
37
+ with mock .patch ('flask.jsonify' , dummyFlask ):
38
+ super (TestExceptionHandler , self ).run (* args , ** kwargs )
39
+
40
+ def testMappedException (self ):
41
+ for originalExceptionClass , mappedExceptionClass in \
42
+ frontendExceptions .exceptionMap .items ():
43
+ originalException = originalExceptionClass ()
44
+ mappedException = mappedExceptionClass ()
45
+ response = frontend .handleException (originalException )
46
+ self .assertEquals (response .status_code , mappedException .httpStatus )
47
+
48
+ def testFrontendException (self ):
49
+ exception = frontendExceptions .ObjectNotFoundException ()
50
+ response = frontend .handleException (exception )
51
+ self .assertEquals (response .status_code , 404 )
52
+
53
+ def testUnknownExceptionBecomesServerError (self ):
54
+ exception = self .UnknownException ()
55
+ response = frontend .handleException (exception )
56
+ self .assertEquals (response .status_code , 500 )
13
57
14
58
15
59
class TestFrontendExceptionConsistency (unittest .TestCase ):
@@ -18,24 +62,33 @@ class TestFrontendExceptionConsistency(unittest.TestCase):
18
62
- every frontend exception has a non-None error code
19
63
- except FrontendException, which does
20
64
- every frontend exception has a unique error code
65
+ - every value in exceptionMap
66
+ - is able to instantiate a new no-argument exception instance
67
+ - derives from the base frontend exception type
21
68
"""
22
69
23
70
def _getFrontendExceptionClasses (self ):
24
71
25
- def isClassAndExceptionSubclass (clazz ):
26
- return inspect .isclass (clazz ) and issubclass (clazz , Exception )
72
+ def isClassAndExceptionSubclass (class_ ):
73
+ return inspect .isclass (class_ ) and issubclass (class_ , Exception )
27
74
28
75
classes = inspect .getmembers (
29
76
frontendExceptions , isClassAndExceptionSubclass )
30
- return [clazz for _ , clazz in classes ]
77
+ return [class_ for _ , class_ in classes ]
31
78
32
79
def testCodeInvariants (self ):
33
80
codes = set ()
34
- for clazz in self ._getFrontendExceptionClasses ():
35
- instance = clazz ()
36
- assert instance .code not in codes
81
+ for class_ in self ._getFrontendExceptionClasses ():
82
+ instance = class_ ()
83
+ self . assertTrue ( instance .code not in codes )
37
84
codes .add (instance .code )
38
- if clazz == frontendExceptions .FrontendException :
39
- assert instance .code is None
85
+ if class_ == frontendExceptions .FrontendException :
86
+ self . assertIsNone ( instance .code )
40
87
else :
41
- assert instance .code is not None
88
+ self .assertIsNotNone (instance .code )
89
+
90
+ def testExceptionMap (self ):
91
+ for exceptionClass in frontendExceptions .exceptionMap .values ():
92
+ exception = exceptionClass ()
93
+ self .assertIsInstance (
94
+ exception , frontendExceptions .FrontendException )
0 commit comments