Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate graphql-transport-ws types to TypedDicts #3701

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Release type: minor

In this release, we migrated the `graphql-transport-ws` types from data classes to typed dicts.
Using typed dicts enabled us to precisely model `null` versus `undefined` values, which are common in that protocol.
As a result, we could remove custom conversion methods handling these cases and simplify the codebase.
59 changes: 26 additions & 33 deletions strawberry/channels/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,10 @@

from channels.testing.websocket import WebsocketCommunicator
from strawberry.subscriptions import GRAPHQL_TRANSPORT_WS_PROTOCOL, GRAPHQL_WS_PROTOCOL
from strawberry.subscriptions.protocols.graphql_transport_ws.types import (
ConnectionAckMessage,
ConnectionInitMessage,
ErrorMessage,
NextMessage,
SubscribeMessage,
SubscribeMessagePayload,
)
from strawberry.subscriptions.protocols.graphql_ws.types import (
ConnectionAckMessage as GraphQLWSConnectionAckMessage,
)
from strawberry.subscriptions.protocols.graphql_ws.types import (
ConnectionInitMessage as GraphQLWSConnectionInitMessage,
)
from strawberry.subscriptions.protocols.graphql_ws.types import (
StartMessage as GraphQLWSStartMessage,
from strawberry.subscriptions.protocols.graphql_transport_ws import (

Check warning on line 20 in strawberry/channels/testing.py

View check run for this annotation

Codecov / codecov/patch

strawberry/channels/testing.py#L20

Added line #L20 was not covered by tests
types as transport_ws_types,
)
from strawberry.subscriptions.protocols.graphql_ws import types as ws_types

Check warning on line 23 in strawberry/channels/testing.py

View check run for this annotation

Codecov / codecov/patch

strawberry/channels/testing.py#L23

Added line #L23 was not covered by tests
from strawberry.types import ExecutionResult

if TYPE_CHECKING:
Expand Down Expand Up @@ -109,19 +96,21 @@
if self.protocol == GRAPHQL_TRANSPORT_WS_PROTOCOL:
assert res == (True, GRAPHQL_TRANSPORT_WS_PROTOCOL)
await self.send_json_to(
ConnectionInitMessage(payload=self.connection_params).as_dict()
transport_ws_types.ConnectionInitMessage(
{"type": "connection_init", "payload": self.connection_params}
)
DoctorJohn marked this conversation as resolved.
Show resolved Hide resolved
)
graphql_transport_ws_response = await self.receive_json_from()
assert graphql_transport_ws_response == ConnectionAckMessage().as_dict()
transport_ws_connection_ack_message: transport_ws_types.ConnectionAckMessage = await self.receive_json_from()
assert transport_ws_connection_ack_message == {"type": "connection_ack"}

Check warning on line 104 in strawberry/channels/testing.py

View check run for this annotation

Codecov / codecov/patch

strawberry/channels/testing.py#L103-L104

Added lines #L103 - L104 were not covered by tests
else:
assert res == (True, GRAPHQL_WS_PROTOCOL)
await self.send_json_to(
GraphQLWSConnectionInitMessage({"type": "connection_init"})
ws_types.ConnectionInitMessage({"type": "connection_init"})
)
graphql_ws_response: GraphQLWSConnectionAckMessage = (
ws_connection_ack_message: ws_types.ConnectionAckMessage = (

Check warning on line 110 in strawberry/channels/testing.py

View check run for this annotation

Codecov / codecov/patch

strawberry/channels/testing.py#L110

Added line #L110 was not covered by tests
await self.receive_json_from()
)
assert graphql_ws_response["type"] == "connection_ack"
assert ws_connection_ack_message["type"] == "connection_ack"

Check warning on line 113 in strawberry/channels/testing.py

View check run for this annotation

Codecov / codecov/patch

strawberry/channels/testing.py#L113

Added line #L113 was not covered by tests

# Actual `ExecutionResult`` objects are not available client-side, since they
# get transformed into `FormattedExecutionResult` on the wire, but we attempt
Expand All @@ -133,13 +122,16 @@

if self.protocol == GRAPHQL_TRANSPORT_WS_PROTOCOL:
await self.send_json_to(
SubscribeMessage(
id=id_,
payload=SubscribeMessagePayload(query=query, variables=variables),
).as_dict()
transport_ws_types.SubscribeMessage(
{
"id": id_,
"type": "subscribe",
"payload": {"query": query, "variables": variables},
}
)
)
else:
start_message: GraphQLWSStartMessage = {
start_message: ws_types.StartMessage = {

Check warning on line 134 in strawberry/channels/testing.py

View check run for this annotation

Codecov / codecov/patch

strawberry/channels/testing.py#L134

Added line #L134 was not covered by tests
"type": "start",
"id": id_,
"payload": {
Expand All @@ -153,17 +145,18 @@
await self.send_json_to(start_message)

while True:
response = await self.receive_json_from(timeout=5)
message_type = response["type"]
if message_type == NextMessage.type:
payload = NextMessage(**response).payload
message: transport_ws_types.Message = await self.receive_json_from(

Check warning on line 148 in strawberry/channels/testing.py

View check run for this annotation

Codecov / codecov/patch

strawberry/channels/testing.py#L148

Added line #L148 was not covered by tests
timeout=5
)
if message["type"] == "next":
payload = message["payload"]

Check warning on line 152 in strawberry/channels/testing.py

View check run for this annotation

Codecov / codecov/patch

strawberry/channels/testing.py#L152

Added line #L152 was not covered by tests
ret = ExecutionResult(payload.get("data"), None)
if "errors" in payload:
ret.errors = self.process_errors(payload.get("errors") or [])
ret.extensions = payload.get("extensions", None)
yield ret
elif message_type == ErrorMessage.type:
error_payload = ErrorMessage(**response).payload
elif message["type"] == "error":
error_payload = message["payload"]

Check warning on line 159 in strawberry/channels/testing.py

View check run for this annotation

Codecov / codecov/patch

strawberry/channels/testing.py#L159

Added line #L159 was not covered by tests
yield ExecutionResult(
data=None, errors=self.process_errors(error_payload)
)
Expand Down
Loading
Loading