Coverage for graphqler / fuzzer / engine / types / result.py: 80%

114 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-20 10:09 -0400

1from enum import Enum 

2from graphqler import config 

3from typing import Optional 

4 

5 

6class ResultEnum(Enum): 

7 EXTERNAL_FAILURE = {"type": "external_failure", "reason": "Failure happened outside of the fuzzer", "success": False} 

8 INTERNAL_FAILURE = {"type": "internal_failure", "reason": "Failure happened inside the fuzzer", "success": False} 

9 GENERAL_SUCCESS = {"type": "general_success", "reason": "General success", "success": True} 

10 HAS_DATA_SUCCESS = {"type": "has_data_success", "reason": "Success and has data", "success": True} 

11 NO_DATA_SUCCESS = {"type": "no_data_success", "reason": "Success and has no data", "success": config.NO_DATA_COUNT_AS_SUCCESS} 

12 

13 

14class Result: 

15 def __init__(self, 

16 result_enum: Optional[ResultEnum] = None, 

17 payload: Optional[str] | Optional[list[str]] | dict = None, 

18 errors: Optional[list] = None, 

19 data: Optional[dict] = None, 

20 status_code: Optional[int] = None, 

21 graphql_response: Optional[dict] = None, 

22 raw_response_text: Optional[str] = None): 

23 """Initializes the result object""" 

24 self._result_enum = result_enum 

25 self._payload = payload 

26 self._errors = errors 

27 self._data = data 

28 self._status_code = status_code 

29 self._graphql_response = graphql_response 

30 self._raw_response_text = raw_response_text 

31 

32 def __eq__(self, other: object) -> bool: 

33 """ 

34 Implement equality comparison for Result objects. 

35 Two Results are considered equal if they have the same content. 

36 """ 

37 if not isinstance(other, Result): 

38 return NotImplemented 

39 

40 return ( 

41 self._result_enum == other._result_enum 

42 and self._payload == other._payload 

43 and self._errors == other._errors 

44 and self._data == other._data 

45 and self._status_code == other._status_code 

46 and self._graphql_response == other._graphql_response 

47 and self._raw_response_text == other._raw_response_text 

48 ) 

49 

50 def __hash__(self) -> int: 

51 """ 

52 Implement hashing for Result objects. 

53 This allows Result objects to be used in sets and as dictionary keys. 

54 """ 

55 return hash(( 

56 self._result_enum, 

57 str(self._payload), 

58 str(self._errors), 

59 str(self._data), 

60 self._status_code, 

61 str(self._graphql_response), 

62 self._raw_response_text 

63 )) 

64 

65 def __str__(self) -> str: 

66 """Returns a string representation of the result""" 

67 return f"Result<{self._result_enum} | {self._status_code} | {self.__hash__()}>" 

68 

69 def __repr__(self) -> str: 

70 """Returns a string representation of the result""" 

71 return f"Result<{self._result_enum} | {self._status_code} | {self.__hash__()}>" 

72 

73 # ----------------- Properties ----------------- 

74 @property 

75 def result_enum(self) -> Optional[ResultEnum]: 

76 """Gets the result enum""" 

77 return self._result_enum 

78 

79 @result_enum.setter 

80 def result_enum(self, result_enum): 

81 """Sets result enum""" 

82 self._result_enum = result_enum 

83 

84 @property 

85 def payload(self) -> Optional[str] | Optional[list[str]] | dict: 

86 """Gets the payload string""" 

87 return self._payload 

88 

89 @property 

90 def success(self) -> bool: 

91 """Dynamically retrieves success status""" 

92 if self._result_enum is None: 

93 return False 

94 if self._result_enum == ResultEnum.NO_DATA_SUCCESS: 

95 # Access config dynamically for NO_DATA_SUCCESS success status 

96 return config.NO_DATA_COUNT_AS_SUCCESS # Replace with actual config 

97 return self._result_enum.value["success"] 

98 

99 @property 

100 def type(self) -> str: 

101 """Gets the type of the result""" 

102 if self._result_enum is None: 

103 return "unknown" 

104 return self._result_enum.value["type"] 

105 

106 @property 

107 def reason(self) -> str: 

108 """Gets the reason of the result""" 

109 if self._result_enum is None: 

110 return "unknown" 

111 return self._result_enum.value["reason"] 

112 

113 @property 

114 def has_data(self) -> bool: 

115 """Checks if the result has data""" 

116 return self._data is not None 

117 

118 @property 

119 def has_non_empty_data(self) -> bool: 

120 """Checks if the result has non-empty data""" 

121 return self.has_data and self._data != {} 

122 

123 @property 

124 def has_errors(self) -> bool: 

125 """Checks if the result has errors""" 

126 return self._errors is not None and len(self._errors) > 0 

127 

128 @property 

129 def has_status_code(self) -> bool: 

130 """Checks if the result has a status code""" 

131 return self._status_code is not None 

132 

133 @property 

134 def data(self) -> dict: 

135 """Gets the data""" 

136 if self._data is None: 

137 return {} 

138 return self._data 

139 

140 @data.setter 

141 def data(self, data): 

142 """Sets data""" 

143 self._data = data 

144 

145 @property 

146 def status_code(self) -> int: 

147 """Gets the status code""" 

148 if self._status_code is None: 

149 return 0 

150 return self._status_code 

151 

152 @status_code.setter 

153 def status_code(self, status_code): 

154 """Sets status code""" 

155 self._status_code = status_code 

156 

157 @property 

158 def graphql_response(self) -> dict: 

159 """Gets the graphql response""" 

160 if self._graphql_response is None: 

161 return {} 

162 return self._graphql_response 

163 

164 @graphql_response.setter 

165 def graphql_response(self, graphql_response): 

166 """Sets graphql response""" 

167 self._graphql_response = graphql_response 

168 if graphql_response is not None: 

169 if 'errors' in graphql_response: 

170 self._errors = graphql_response['errors'] 

171 if 'data' in graphql_response: 

172 self._data = graphql_response['data'] 

173 

174 @property 

175 def raw_response_text(self) -> str: 

176 """Gets the raw response text""" 

177 if self._raw_response_text is None: 

178 return '' 

179 return self._raw_response_text 

180 

181 @raw_response_text.setter 

182 def raw_response_text(self, raw_response_text): 

183 """Sets raw response text""" 

184 self._raw_response_text = raw_response_text 

185 

186 @property 

187 def errors(self) -> list: 

188 """Gets the errors""" 

189 if self._errors is None: 

190 return [] 

191 return self._errors 

192 

193 @errors.setter 

194 def errors(self, errors): 

195 """Sets errors""" 

196 self._errors = errors 

197 

198 @payload.setter 

199 def payload(self, payload): 

200 """Sets payload string""" 

201 self._payload = payload