Skip to content

Commit

Permalink
Allow empty custom context in GraphQLView (graphql-python#106)
Browse files Browse the repository at this point in the history
* Allow empty custom context in GraphQLView

* chore: black

---------

Co-authored-by: Kien Dang <[email protected]>
  • Loading branch information
leonardwellthy and kiendang authored Apr 13, 2023
1 parent 8b9639e commit d76450a
Show file tree
Hide file tree
Showing 15 changed files with 110 additions and 5 deletions.
2 changes: 1 addition & 1 deletion graphql_server/aiohttp/graphqlview.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def get_root_value(self):
def get_context(self, request):
context = (
copy.copy(self.context)
if self.context and isinstance(self.context, MutableMapping)
if self.context is not None and isinstance(self.context, MutableMapping)
else {}
)
if isinstance(context, MutableMapping) and "request" not in context:
Expand Down
2 changes: 1 addition & 1 deletion graphql_server/flask/graphqlview.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def get_root_value(self):
def get_context(self):
context = (
copy.copy(self.context)
if self.context and isinstance(self.context, MutableMapping)
if self.context is not None and isinstance(self.context, MutableMapping)
else {}
)
if isinstance(context, MutableMapping) and "request" not in context:
Expand Down
2 changes: 1 addition & 1 deletion graphql_server/quart/graphqlview.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def get_root_value(self):
def get_context(self):
context = (
copy.copy(self.context)
if self.context and isinstance(self.context, MutableMapping)
if self.context is not None and isinstance(self.context, MutableMapping)
else {}
)
if isinstance(context, MutableMapping) and "request" not in context:
Expand Down
2 changes: 1 addition & 1 deletion graphql_server/sanic/graphqlview.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def get_root_value(self):
def get_context(self, request):
context = (
copy.copy(self.context)
if self.context and isinstance(self.context, MutableMapping)
if self.context is not None and isinstance(self.context, MutableMapping)
else {}
)
if isinstance(context, MutableMapping) and "request" not in context:
Expand Down
2 changes: 1 addition & 1 deletion graphql_server/webob/graphqlview.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def get_root_value(self):
def get_context(self, request):
context = (
copy.copy(self.context)
if self.context and isinstance(self.context, MutableMapping)
if self.context is not None and isinstance(self.context, MutableMapping)
else {}
)
if isinstance(context, MutableMapping) and "request" not in context:
Expand Down
3 changes: 3 additions & 0 deletions tests/aiohttp/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ def resolve_raises(*_):
GraphQLNonNull(GraphQLString),
resolve=lambda obj, info: info.context["request"],
),
"property": GraphQLField(
GraphQLString, resolve=lambda obj, info: info.context.property
),
},
),
resolve=lambda obj, info: info.context,
Expand Down
18 changes: 18 additions & 0 deletions tests/aiohttp/test_graphqlview.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,24 @@ async def test_context_remapped_if_not_mapping(app, client):
assert "Request" in _json["data"]["context"]["request"]


class CustomContext(dict):
property = "A custom property"


@pytest.mark.asyncio
@pytest.mark.parametrize("app", [create_app(context=CustomContext())])
async def test_allow_empty_custom_context(app, client):
response = await client.get(url_string(query="{context { property request }}"))

_json = await response.json()
assert response.status == 200
assert "data" in _json
assert "request" in _json["data"]["context"]
assert "property" in _json["data"]["context"]
assert "A custom property" == _json["data"]["context"]["property"]
assert "Request" in _json["data"]["context"]["request"]


@pytest.mark.asyncio
@pytest.mark.parametrize("app", [create_app(context={"request": "test"})])
async def test_request_not_replaced(app, client):
Expand Down
3 changes: 3 additions & 0 deletions tests/flask/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ def resolve_raises(*_):
GraphQLNonNull(GraphQLString),
resolve=lambda obj, info: info.context["request"],
),
"property": GraphQLField(
GraphQLString, resolve=lambda obj, info: info.context.property
),
},
),
resolve=lambda obj, info: info.context,
Expand Down
17 changes: 17 additions & 0 deletions tests/flask/test_graphqlview.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,23 @@ def test_context_remapped_if_not_mapping(app, client):
assert "Request" in res["data"]["context"]["request"]


class CustomContext(dict):
property = "A custom property"


@pytest.mark.parametrize("app", [create_app(context=CustomContext())])
def test_allow_empty_custom_context(app, client):
response = client.get(url_string(app, query="{context { property request }}"))

assert response.status_code == 200
res = response_json(response)
assert "data" in res
assert "request" in res["data"]["context"]
assert "property" in res["data"]["context"]
assert "A custom property" == res["data"]["context"]["property"]
assert "Request" in res["data"]["context"]["request"]


def test_post_multipart_data(app, client):
query = "mutation TestMutation { writeTest { test } }"
response = client.post(
Expand Down
3 changes: 3 additions & 0 deletions tests/quart/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ def resolve_raises(*_):
GraphQLNonNull(GraphQLString),
resolve=lambda obj, info: info.context["request"],
),
"property": GraphQLField(
GraphQLString, resolve=lambda obj, info: info.context.property
),
},
),
resolve=lambda obj, info: info.context,
Expand Down
19 changes: 19 additions & 0 deletions tests/quart/test_graphqlview.py
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,25 @@ async def test_context_remapped_if_not_mapping(app: Quart, client: TestClientPro
assert "Request" in res["data"]["context"]["request"]


class CustomContext(dict):
property = "A custom property"


@pytest.mark.asyncio
@pytest.mark.parametrize("app", [create_app(context=CustomContext())])
async def test_allow_empty_custom_context(app: Quart, client: TestClientProtocol):
response = await execute_client(app, client, query="{context { property request }}")

assert response.status_code == 200
result = await response.get_data(as_text=True)
res = response_json(result)
assert "data" in res
assert "request" in res["data"]["context"]
assert "property" in res["data"]["context"]
assert "A custom property" == res["data"]["context"]["property"]
assert "Request" in res["data"]["context"]["request"]


# @pytest.mark.asyncio
# async def test_post_multipart_data(app: Quart, client: TestClientProtocol):
# query = "mutation TestMutation { writeTest { test } }"
Expand Down
3 changes: 3 additions & 0 deletions tests/sanic/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ def resolve_raises(*_):
GraphQLNonNull(GraphQLString),
resolve=lambda obj, info: info.context["request"],
),
"property": GraphQLField(
GraphQLString, resolve=lambda obj, info: info.context.property
),
},
),
resolve=lambda obj, info: info.context,
Expand Down
19 changes: 19 additions & 0 deletions tests/sanic/test_graphqlview.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,25 @@ def test_passes_custom_context_into_context(app):
assert "Request" in res["data"]["context"]["request"]


class CustomContext(dict):
property = "A custom property"


@pytest.mark.parametrize("app", [create_app(context=CustomContext())])
def test_allow_empty_custom_context(app):
_, response = app.test_client.get(
uri=url_string(query="{context { property request }}")
)

assert response.status_code == 200
res = response_json(response)
assert "data" in res
assert "request" in res["data"]["context"]
assert "property" in res["data"]["context"]
assert "A custom property" == res["data"]["context"]["property"]
assert "Request" in res["data"]["context"]["request"]


@pytest.mark.parametrize("app", [create_app(context="CUSTOM CONTEXT")])
def test_context_remapped_if_not_mapping(app):
_, response = app.test_client.get(
Expand Down
3 changes: 3 additions & 0 deletions tests/webob/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ def resolve_raises(*_):
GraphQLNonNull(GraphQLString),
resolve=lambda obj, info: info.context["request"],
),
"property": GraphQLField(
GraphQLString, resolve=lambda obj, info: info.context.property
),
},
),
resolve=lambda obj, info: info.context,
Expand Down
17 changes: 17 additions & 0 deletions tests/webob/test_graphqlview.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,23 @@ def test_context_remapped_if_not_mapping(client, settings):
assert "request" in res["data"]["context"]["request"]


class CustomContext(dict):
property = "A custom property"


@pytest.mark.parametrize("settings", [dict(context=CustomContext())])
def test_allow_empty_custom_context(client, settings):
response = client.get(url_string(query="{context { property request }}"))

assert response.status_code == 200
res = response_json(response)
assert "data" in res
assert "request" in res["data"]["context"]
assert "property" in res["data"]["context"]
assert "A custom property" == res["data"]["context"]["property"]
assert "request" in res["data"]["context"]["request"]


def test_post_multipart_data(client):
query = "mutation TestMutation { writeTest { test } }"
data = (
Expand Down

0 comments on commit d76450a

Please sign in to comment.