Skip to content

Commit b2a0088

Browse files
umaannamalaiTimPansino
authored andcommitted
Add testing for GraphQL Mutation Types (#281)
*  Add testing for graphql mutations. *  Add version check in test_basic. *  Modifying response assertion statements for version compatibility.
1 parent 1e43d4f commit b2a0088

File tree

3 files changed

+90
-20
lines changed

3 files changed

+90
-20
lines changed

newrelic/api/graphql_trace.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ def __repr__(self):
3636
return '<%s %s>' % (self.__class__.__name__, dict())
3737

3838
def finalize_data(self, *args, **kwargs):
39-
self._add_agent_attribute("graphql.operation.type", self.operation_type)
40-
self._add_agent_attribute("graphql.operation.name", self.operation_name)
41-
self._add_agent_attribute("graphql.operation.deepestPath", self.deepest_path)
39+
self._add_agent_attribute("graphql.operation.type", self.operation_type or "<unknown>")
40+
self._add_agent_attribute("graphql.operation.name", self.operation_name or "<anonymous>")
41+
self._add_agent_attribute("graphql.operation.deepestPath", self.deepest_path or "<unknown>")
4242

4343
return super(GraphQLOperationTrace, self).finalize_data(*args, **kwargs)
4444

tests/framework_graphql/_target_application.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,19 @@
3131
{"name": "Portland Public Library", "book": [{"name": "E", "author": "F"}]},
3232
]
3333

34+
storage = []
35+
3436

3537
def resolve_library(parent, info, index):
3638
return libraries[index]
3739

40+
def resolve_storage_add(parent, info, string):
41+
storage.append(string)
42+
return string
43+
44+
def resolve_storage(parent, info):
45+
return storage
46+
3847

3948
Book = GraphQLObjectType(
4049
"Book",
@@ -52,6 +61,8 @@ def resolve_library(parent, info, index):
5261
},
5362
)
5463

64+
Storage = GraphQLList(GraphQLString)
65+
5566

5667
def resolve_hello(root, info):
5768
return "Hello!"
@@ -68,6 +79,15 @@ def resolve_error(root, info):
6879
resolver=resolve_library,
6980
args={"index": GraphQLArgument(GraphQLNonNull(GraphQLInt))},
7081
)
82+
storage_field = GraphQLField(
83+
Storage,
84+
resolver=resolve_storage,
85+
)
86+
storage_add_field = GraphQLField(
87+
Storage,
88+
resolver=resolve_storage_add,
89+
args={"string": GraphQLArgument(GraphQLNonNull(GraphQLString))},
90+
)
7191
error_field = GraphQLField(GraphQLString, resolver=resolve_error)
7292
error_non_null_field = GraphQLField(
7393
GraphQLNonNull(GraphQLString), resolver=resolve_error
@@ -79,6 +99,15 @@ def resolve_error(root, info):
7999
resolve=resolve_library,
80100
args={"index": GraphQLArgument(GraphQLNonNull(GraphQLInt))},
81101
)
102+
storage_field = GraphQLField(
103+
Storage,
104+
resolve=resolve_storage,
105+
)
106+
storage_add_field = GraphQLField(
107+
GraphQLString,
108+
resolve=resolve_storage_add,
109+
args={"string": GraphQLArgument(GraphQLNonNull(GraphQLString))},
110+
)
82111
error_field = GraphQLField(GraphQLString, resolve=resolve_error)
83112
error_non_null_field = GraphQLField(
84113
GraphQLNonNull(GraphQLString), resolve=resolve_error
@@ -88,10 +117,18 @@ def resolve_error(root, info):
88117
name="Query",
89118
fields={
90119
"hello": hello_field,
120+
"storage": storage_field,
91121
"error": error_field,
92122
"error_non_null": error_non_null_field,
93123
"library": library_field,
94124
},
95125
)
96126

97-
_target_application = GraphQLSchema(query=query)
127+
mutation = GraphQLObjectType(
128+
name="Mutation",
129+
fields={
130+
"storage_add": storage_add_field,
131+
},
132+
)
133+
134+
_target_application = GraphQLSchema(query=query, mutation=mutation)

tests/framework_graphql/test_application.py

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import pytest
16+
import sys
1617
from testing_support.fixtures import validate_transaction_metrics, validate_transaction_errors, dt_enabled
1718
from testing_support.validators.validate_span_events import validate_span_events
1819

@@ -49,11 +50,6 @@ def error_middleware(next, root, info, **args):
4950

5051
_runtime_error_name = callable_name(RuntimeError)
5152
_test_runtime_error = [(_runtime_error_name, "Runtime Error!")]
52-
_expected_attributes = {
53-
"graphql.operation.name": "MyQuery",
54-
"graphql.operation.type": "query",
55-
"graphql.operation.deepestPath": "hello"
56-
}
5753
_graphql_base_rollup_metrics = [
5854
("OtherTransaction/all", 1),
5955
("GraphQL/all", 1),
@@ -64,25 +60,61 @@ def error_middleware(next, root, info, **args):
6460

6561

6662
@dt_enabled
67-
def test_basic(app, graphql_run, is_graphql_2):
68-
_test_basic_metrics = [
69-
("OtherTransaction/Function/_target_application:resolve_hello", 1),
70-
("GraphQL/operation/GraphQL/query/MyQuery/hello", 1),
71-
#("Function/_target_application:resolve_hello", 1),
63+
def test_basic(app, graphql_run):
64+
_test_mutation_scoped_metrics = [
65+
("GraphQL/resolve/GraphQL/storage", 1),
66+
("GraphQL/resolve/GraphQL/storage_add", 1),
67+
("GraphQL/operation/GraphQL/query/<anonymous>/storage", 1),
68+
("GraphQL/operation/GraphQL/mutation/<anonymous>/storage_add", 1),
7269
]
73-
70+
_test_mutation_unscoped_metrics = [
71+
("OtherTransaction/all", 1),
72+
("GraphQL/all", 2),
73+
("GraphQL/GraphQL/all", 2),
74+
("GraphQL/allOther", 2),
75+
("GraphQL/GraphQL/allOther", 2),
76+
] + _test_mutation_scoped_metrics
77+
78+
_expected_mutation_operation_attributes = {
79+
"graphql.operation.type": "mutation",
80+
"graphql.operation.name": "<anonymous>",
81+
"graphql.operation.deepestPath": "storage_add",
82+
}
83+
_expected_mutation_resolver_attributes = {
84+
"graphql.field.name": "storage_add",
85+
"graphql.field.parentType": "Mutation",
86+
"graphql.field.path": "storage_add",
87+
}
88+
_expected_query_operation_attributes = {
89+
"graphql.operation.type": "query",
90+
"graphql.operation.name": "<anonymous>",
91+
"graphql.operation.deepestPath": "storage",
92+
}
93+
_expected_query_resolver_attributes = {
94+
"graphql.field.name": "storage",
95+
"graphql.field.parentType": "Query",
96+
"graphql.field.path": "storage",
97+
}
7498
@validate_transaction_metrics(
75-
"_target_application:resolve_hello",
76-
rollup_metrics=_test_basic_metrics + _graphql_base_rollup_metrics,
99+
"_target_application:resolve_storage",
100+
scoped_metrics=_test_mutation_scoped_metrics,
101+
rollup_metrics=_test_mutation_unscoped_metrics,
77102
background_task=True,
78103
)
79-
@validate_span_events(exact_agents=_expected_attributes)
104+
@validate_span_events(exact_agents=_expected_mutation_operation_attributes)
105+
@validate_span_events(exact_agents=_expected_mutation_resolver_attributes)
106+
@validate_span_events(exact_agents=_expected_query_operation_attributes)
107+
@validate_span_events(exact_agents=_expected_query_resolver_attributes)
80108
@background_task()
81109
def _test():
82-
response = graphql_run(app, "query MyQuery{ hello }")
110+
response = graphql_run(app, 'mutation { storage_add(string: "abc") }')
111+
assert not response.errors
112+
response = graphql_run(app, "query { storage }")
83113
assert not response.errors
84-
assert "Hello!" in str(response.data)
85114

115+
# These are separate assertions because pypy stores 'abc' as a unicode string while other Python versions do not
116+
assert "storage" in str(response.data)
117+
assert "abc" in str(response.data)
86118
_test()
87119

88120

@@ -193,3 +225,4 @@ def _test():
193225
assert "Hello!" in str(response.data)
194226

195227
_test()
228+

0 commit comments

Comments
 (0)