Coverage for graphqler / fuzzer / engine / materializers / maximal_payload_materializer.py: 95%
37 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
2"""Regular mutation materializer:
3Materializes a mutation that is ready to be sent off
4"""
6from .materializer import Materializer
7from .utils.materialization_utils import prettify_graphql_payload
8from .getter import Getter
9from graphqler.config import MAX_OUTPUT_SELECTOR_DEPTH, MAX_INPUT_DEPTH
10from graphqler.utils.api import API
11from graphqler.utils.objects_bucket import ObjectsBucket
14class MaximalPayloadMaterializer(Materializer):
15 def __init__(self, api: API, fail_on_hard_dependency_not_met: bool = True):
16 self.getters = Getter()
17 self.api = api
18 self.fail_on_hard_dependency_not_met = fail_on_hard_dependency_not_met
19 super().__init__(self.api, self.fail_on_hard_dependency_not_met, max_depth=MAX_OUTPUT_SELECTOR_DEPTH, getter=self.getters)
21 def get_payload(self, name: str, objects_bucket: ObjectsBucket, graphql_type: str) -> tuple[str, dict]:
22 """Materializes the mutation with parameters filled in
23 1. Make sure all dependencies are satisfied (hardDependsOn)
24 2. Fill in the inputs ()
26 Args:
27 name (str): The name of either the mutation or query
28 objects_bucket (dict): The bucket of objects that have already been created
29 graphql_type (str): The type of the graphql operation (Query or Mutation)
31 Returns:
32 tuple[str, dict]: The string of the payload, and the used objects list
33 """
34 self.used_objects = {} # Reset the used_objects list per run (from parent class)
35 if graphql_type == "Query":
36 return self._get_query_payload(name,
37 objects_bucket,
38 max_input_depth=MAX_INPUT_DEPTH,
39 max_output_depth=MAX_OUTPUT_SELECTOR_DEPTH,
40 minimal_materialization=False)
41 elif graphql_type == "Mutation":
42 return self._get_mutation_payload(name,
43 objects_bucket,
44 max_input_depth=MAX_INPUT_DEPTH,
45 max_output_depth=MAX_OUTPUT_SELECTOR_DEPTH,
46 minimal_materialization=False)
47 else:
48 raise ValueError("Invalid graphql_type provided")
50 def _get_query_payload(self,
51 query_name: str,
52 objects_bucket: ObjectsBucket,
53 max_input_depth: int = MAX_INPUT_DEPTH,
54 max_output_depth: int = MAX_OUTPUT_SELECTOR_DEPTH,
55 minimal_materialization: bool = False) -> tuple[str, dict]:
56 query_info = self.api.queries[query_name]
57 query_inputs = self.materialize_inputs(query_info, query_info["inputs"], objects_bucket, max_depth=max_input_depth)
58 query_output = self.materialize_output(query_info, query_info["output"], objects_bucket, max_depth=max_output_depth, minimal_materialization=minimal_materialization)
60 if query_inputs != "":
61 query_inputs = f"({query_inputs})"
63 payload = f"""
64 query {{
65 {query_name} {query_inputs}
66 {query_output}
67 }}
68 """
69 pretty_payload = prettify_graphql_payload(payload)
70 return pretty_payload, self.used_objects
72 def _get_mutation_payload(self,
73 mutation_name: str,
74 objects_bucket: ObjectsBucket,
75 max_input_depth: int = MAX_INPUT_DEPTH,
76 max_output_depth: int = MAX_OUTPUT_SELECTOR_DEPTH,
77 minimal_materialization: bool = False) -> tuple[str, dict]:
78 mutation_info = self.api.mutations[mutation_name]
79 mutation_inputs = self.materialize_inputs(mutation_info, mutation_info["inputs"], objects_bucket, max_depth=max_input_depth)
80 mutation_output = self.materialize_output(mutation_info, mutation_info["output"], objects_bucket, max_depth=max_output_depth, minimal_materialization=minimal_materialization)
82 if mutation_inputs.strip() == "":
83 mutation_payload = f"""
84 mutation {{
85 {mutation_name}
86 {mutation_output}
87 }}
88 """
89 else:
90 mutation_payload = f"""
91 mutation {{
92 {mutation_name} (
93 {mutation_inputs}
94 )
95 {mutation_output}
96 }}
97 """
98 pretty_payload = prettify_graphql_payload(mutation_payload)
99 return pretty_payload, self.used_objects