Coverage for rfpy/auth/errors.py: 100%

32 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-24 10:52 +0000

1from enum import Enum 

2import re 

3 

4 

5class ErrorType(Enum): 

6 AUTH = "Authorization Failed" 

7 PROJECT_STATUS = "Invalid Project Status" 

8 ISSUE_STATUS = "Invalid Issue Status" 

9 

10 

11class ValidationErrors(object): 

12 """Captures accumulated validation logic errors""" 

13 

14 def __init__(self, action): 

15 self.action = action 

16 self.errors = [] 

17 

18 @property 

19 def p_action(self): 

20 """ 

21 Prettified action string name 

22 

23 Action text converted to space separated title case 

24 e.g. thisAndThat -> This And That 

25 """ 

26 return re.sub(r"([A-Z])", r" \1", self.action).title() 

27 

28 @property 

29 def has_errors(self): 

30 return len(self.errors) > 0 

31 

32 def add(self, error_type, error_message): 

33 self.errors.append((error_type, error_message)) 

34 

35 def auth_failure(self, error_message): 

36 self.add(ErrorType.AUTH, error_message) 

37 

38 def invalid_issue_status(self, status): 

39 msg = f"Action {self.p_action} not permitted at Issue status {status}" 

40 self.add(ErrorType.ISSUE_STATUS, msg) 

41 

42 def invalid_project_status(self, status): 

43 msg = f"Action {self.p_action} not permitted at Project status {status}" 

44 self.add(ErrorType.PROJECT_STATUS, msg) 

45 

46 def __iter__(self): 

47 return iter(self.errors) 

48 

49 def __len__(self): 

50 return len(self.errors) 

51 

52 def as_dict(self): 

53 return [ 

54 dict(type=error_type.value, message=msg) for error_type, msg in self.errors 

55 ] 

56 

57 def __repr__(self): 

58 repr = "" 

59 for etype, emsg in self.errors: 

60 v = getattr(etype, "value", str(etype)) 

61 repr += f"{v}: {emsg} \n" 

62 return repr