Coverage for graphqler / fuzzer / engine / materializers / utils / materialization_utils.py: 82%

28 statements  

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

1"""Utilities used on the output portion of the payload""" 

2 

3import re 

4from graphql import parse, print_ast 

5 

6 

7def is_valid_object_materialization(materialized_str: str) -> bool: 

8 """Checks if the output is a valid object output 

9 Format: OBJECT_NAME(INPUT){OUTPUT} 

10 IE: - abc {} -> False 

11 - abc(filter:1) {} -> False 

12 - abc(filter: {def: 123}) {} -> False 

13 - abc(filter: {def: 123}) {def } -> True 

14 - abc {def} -> True 

15 - abc {, , ,} -> False 

16 

17 Args: 

18 output_str (str): The string that is supposed to be output 

19 

20 Returns: 

21 bool: Whether the output string is valid or not 

22 """ 

23 # Cleaned string 

24 materialized_str = materialized_str.replace(" ", "") 

25 materialized_str = remove_consecutive_characters(materialized_str, ",") 

26 materialized_str = materialized_str.strip(",") 

27 if "{}" in materialized_str or "{,}" in materialized_str: 

28 return False 

29 

30 # Parse the AST for validity of the payload 

31 try: 

32 dummy_payload = f"query STUFF{{{materialized_str}}}" 

33 parsed_obj = parse(dummy_payload) 

34 print_ast(parsed_obj).strip() 

35 return True 

36 except Exception: 

37 return False 

38 

39 

40def clean_output_selectors(output_selectors: str) -> str: 

41 """Cleans the output selectors by doing the following:L 

42 - Removing any extra commas 

43 - Removing Removing keys that don't have an object (ie. {stuff {}, otherstuff} -> {otherstuff}) 

44 

45 Args: 

46 output_selectors (str): _description_ 

47 

48 Returns: 

49 str: _description_ 

50 """ 

51 # Removing any extra commas 

52 while ",," in output_selectors: 

53 output_selectors = output_selectors.replace(",,", ",") 

54 

55 # Removing keys that don't have an object 

56 while "{}" in output_selectors: 

57 output_selectors = output_selectors.replace("{},", "") 

58 output_selectors = output_selectors.replace(",{}", "") 

59 

60 return output_selectors 

61 

62 

63def remove_consecutive_characters(s: str, char: str) -> str: 

64 """Removes consecutive occurrences of a specified character in a string, 

65 reducing them to a single occurrence of the character. 

66 

67 Args: 

68 s (str): The input string. 

69 char (str): The character to reduce consecutive occurrences of. 

70 

71 Returns: 

72 str: The modified string with consecutive characters reduced. 

73 """ 

74 return re.sub(f"{char}+", char, s) 

75 

76 

77def prettify_graphql_payload(payload: str) -> str: 

78 """Uses graphql-core to prettify the payload 

79 

80 Args: 

81 payload (str): The QUERY or MUTATION as a string 

82 

83 Returns: 

84 str: A string of the formatted graphql payload 

85 """ 

86 parsed_query = parse(payload) 

87 formatted_query = print_ast(parsed_query).strip() 

88 return formatted_query