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
« 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
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}
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
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
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 )
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 ))
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__()}>"
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__()}>"
73 # ----------------- Properties -----------------
74 @property
75 def result_enum(self) -> Optional[ResultEnum]:
76 """Gets the result enum"""
77 return self._result_enum
79 @result_enum.setter
80 def result_enum(self, result_enum):
81 """Sets result enum"""
82 self._result_enum = result_enum
84 @property
85 def payload(self) -> Optional[str] | Optional[list[str]] | dict:
86 """Gets the payload string"""
87 return self._payload
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"]
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"]
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"]
113 @property
114 def has_data(self) -> bool:
115 """Checks if the result has data"""
116 return self._data is not None
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 != {}
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
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
133 @property
134 def data(self) -> dict:
135 """Gets the data"""
136 if self._data is None:
137 return {}
138 return self._data
140 @data.setter
141 def data(self, data):
142 """Sets data"""
143 self._data = data
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
152 @status_code.setter
153 def status_code(self, status_code):
154 """Sets status code"""
155 self._status_code = status_code
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
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']
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
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
186 @property
187 def errors(self) -> list:
188 """Gets the errors"""
189 if self._errors is None:
190 return []
191 return self._errors
193 @errors.setter
194 def errors(self, errors):
195 """Sets errors"""
196 self._errors = errors
198 @payload.setter
199 def payload(self, payload):
200 """Sets payload string"""
201 self._payload = payload