`toJson()` should always return a `<String, dynamic>`, not something else, especially not `String`
MODIFY
packages/graphql/lib/src/websocket/messages.dart
packages/graphql/lib/src/websocket/messages.dart
@@ -33,7 +33,7 @@ class MessageTypes {
}
abstract class JsonSerializable {
- dynamic toJson();
+ Map<String, dynamic> toJson();
@override
String toString() => toJson().toString();
@@ -55,7 +55,7 @@ class InitOperation extends GraphQLSocketMessage {
final dynamic payload;
@override
- dynamic toJson() {
+ Map<String, dynamic> toJson() {
final Map<String, dynamic> jsonMap = <String, dynamic>{};
jsonMap['type'] = type;
@@ -74,7 +74,7 @@ class LegacyInitOperation extends InitOperation {
LegacyInitOperation(dynamic payload) : super(payload);
@override
- dynamic toJson() {
+ Map<String, dynamic> toJson() {
final Map<String, dynamic> jsonMap = <String, dynamic>{};
jsonMap['type'] = type;
@@ -82,7 +82,7 @@ class LegacyInitOperation extends InitOperation {
jsonMap['payload'] = json.encode(payload);
}
- return json.encode(jsonMap);
+ return jsonMap;
}
}
@@ -95,7 +95,7 @@ class SubscriptionRequest extends JsonSerializable {
final Operation operation;
@override
- dynamic toJson() => <String, dynamic>{
+ Map<String, dynamic> toJson() => <String, dynamic>{
'operationName': operation.operationName,
'query': operation.document,
'variables': operation.variables,
@@ -114,7 +114,7 @@ class StartOperation extends GraphQLSocketMessage {
final SubscriptionRequest payload;
@override
- dynamic toJson() => <String, dynamic>{
+ Map<String, dynamic> toJson() => <String, dynamic>{
'type': type,
'id': id,
'payload': payload,
@@ -129,7 +129,7 @@ class StopOperation extends GraphQLSocketMessage {
final String id;
@override
- dynamic toJson() => <String, dynamic>{
+ Map<String, dynamic> toJson() => <String, dynamic>{
'type': type,
'id': id,
};
@@ -141,7 +141,7 @@ class ConnectionAck extends GraphQLSocketMessage {
ConnectionAck() : super(MessageTypes.GQL_CONNECTION_ACK);
@override
- dynamic toJson() => <String, dynamic>{
+ Map<String, dynamic> toJson() => <String, dynamic>{
'type': type,
};
}
@@ -154,7 +154,7 @@ class ConnectionError extends GraphQLSocketMessage {
final dynamic payload;
@override
- dynamic toJson() => <String, dynamic>{
+ Map<String, dynamic> toJson() => <String, dynamic>{
'type': type,
'payload': payload,
};
@@ -165,7 +165,7 @@ class ConnectionKeepAlive extends GraphQLSocketMessage {
ConnectionKeepAlive() : super(MessageTypes.GQL_CONNECTION_KEEP_ALIVE);
@override
- dynamic toJson() => <String, dynamic>{
+ Map<String, dynamic> toJson() => <String, dynamic>{
'type': type,
};
}
@@ -182,7 +182,7 @@ class SubscriptionData extends GraphQLSocketMessage {
final dynamic errors;
@override
- dynamic toJson() => <String, dynamic>{
+ Map<String, dynamic> toJson() => <String, dynamic>{
'type': type,
'data': data,
'errors': errors,
@@ -198,7 +198,7 @@ class SubscriptionError extends GraphQLSocketMessage {
final dynamic payload;
@override
- dynamic toJson() => <String, dynamic>{
+ Map<String, dynamic> toJson() => <String, dynamic>{
'type': type,
'id': id,
'payload': payload,
@@ -213,7 +213,7 @@ class SubscriptionComplete extends GraphQLSocketMessage {
final String id;
@override
- dynamic toJson() => <String, dynamic>{
+ Map<String, dynamic> toJson() => <String, dynamic>{
'type': type,
'id': id,
};
@@ -228,7 +228,7 @@ class UnknownData extends GraphQLSocketMessage {
final dynamic payload;
@override
- dynamic toJson() => <String, dynamic>{
+ Map<String, dynamic> toJson() => <String, dynamic>{
'type': type,
'payload': payload,
};

ADD
packages/graphql/test/websocket_test.dart
+import 'package:test/test.dart';
+import 'package:graphql/src/websocket/messages.dart'
+ show
+ // ignore: deprecated_member_use_from_same_package
+ LegacyInitOperation,
+ InitOperation;
+
+void main() {
+ group('LegacyInitOperation', () {
+ test('null payload', () {
+ // ignore: deprecated_member_use_from_same_package
+ final operation = LegacyInitOperation(null);
+ expect(operation.toJson(), {'type': 'connection_init'});
+ });
+ test('simple payload', () {
+ // ignore: deprecated_member_use_from_same_package
+ final operation = LegacyInitOperation(42);
+ expect(operation.toJson(), {'type': 'connection_init', 'payload': '42'});
+ });
+ test('complex payload', () {
+ // ignore: deprecated_member_use_from_same_package
+ final operation = LegacyInitOperation({
+ 'value': 42,
+ 'nested': {
+ 'number': [3, 7],
+ 'string': ['foo', 'bar']
+ }
+ });
+ expect(operation.toJson(), {
+ 'type': 'connection_init',
+ 'payload':
+ '{"value":42,"nested":{"number":[3,7],"string":["foo","bar"]}}'
+ });
+ });
+ });
+ group('InitOperation', () {
+ test('null payload', () {
+ // ignore: deprecated_member_use_from_same_package
+ final operation = InitOperation(null);
+ expect(operation.toJson(), {'type': 'connection_init'});
+ });
+ test('simple payload', () {
+ // ignore: deprecated_member_use_from_same_package
+ final operation = InitOperation(42);
+ expect(operation.toJson(), {'type': 'connection_init', 'payload': 42});
+ });
+ test('complex payload', () {
+ // ignore: deprecated_member_use_from_same_package
+ final operation = InitOperation({
+ 'value': 42,
+ 'nested': {
+ 'number': [3, 7],
+ 'string': ['foo', 'bar']
+ }
+ });
+ expect(operation.toJson(), {
+ 'type': 'connection_init',
+ 'payload': {
+ 'value': 42,
+ 'nested': {
+ 'number': [3, 7],
+ 'string': ['foo', 'bar']
+ }
+ }
+ });
+ });
+ });
+}

`toJson()` should always return a `<String, dynamic>`, not something else, especially not `String`