From d38d220aec276f91847c7179919f8d9a47ed0aa7 Mon Sep 17 00:00:00 2001 From: Alexey Ankip Date: Tue, 29 Jun 2021 13:10:35 +0300 Subject: [PATCH] [gql_dio_link] Add exta from context --- links/gql_dio_link/lib/src/dio_link.dart | 30 +++++++++ .../gql_dio_link/test/gql_dio_link_test.dart | 67 +++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/links/gql_dio_link/lib/src/dio_link.dart b/links/gql_dio_link/lib/src/dio_link.dart index f8c5c480..a7e6c985 100644 --- a/links/gql_dio_link/lib/src/dio_link.dart +++ b/links/gql_dio_link/lib/src/dio_link.dart @@ -39,6 +39,22 @@ class DioLinkResponseContext extends ContextEntry { ]; } +/// Dio link extra context +@immutable +class DioExtraContext extends ContextEntry { + /// Custom field that will be passed to Dio request options and response + final Map extra; + + const DioExtraContext({ + this.extra = const {}, + }); + + @override + List get fieldsForEquality => [ + extra, + ]; +} + extension _CastDioResponse on dio.Response { dio.Response castData() => dio.Response( data: data as T?, @@ -91,6 +107,7 @@ class DioLink extends Link { ...defaultHeaders, ..._getHttpLinkHeaders(request), }, + extra: _getRequestExtra(request), ); if (dioResponse.statusCode! >= 300 || @@ -130,6 +147,7 @@ class DioLink extends Link { Future>> _executeDioRequest({ required Map body, required Map headers, + required Map? extra, }) async { try { final res = await client.post( @@ -138,6 +156,7 @@ class DioLink extends Link { options: dio.Options( responseType: dio.ResponseType.json, headers: headers, + extra: extra, ), ); if (res.data is Map == false) { @@ -215,6 +234,17 @@ class DioLink extends Link { } } + Map? _getRequestExtra(Request request) { + try { + final DioExtraContext? extraContext = request.context.entry(); + return extraContext?.extra; + } catch (e) { + throw ContextReadException( + originalException: e, + ); + } + } + /// Closes the underlining Dio client void close({bool force = false}) { client.close(force: force); diff --git a/links/gql_dio_link/test/gql_dio_link_test.dart b/links/gql_dio_link/test/gql_dio_link_test.dart index bd24ad1a..b6b98c00 100644 --- a/links/gql_dio_link/test/gql_dio_link_test.dart +++ b/links/gql_dio_link/test/gql_dio_link_test.dart @@ -249,6 +249,73 @@ void main() { ).called(1); }); + test("adds extra from context", () async { + when( + client.post( + any, + data: anyNamed("data"), + options: anyNamed("options"), + ), + ).thenAnswer( + (invocation) { + final options = invocation.namedArguments.entries + .firstWhere((element) => element.key == Symbol("options")) + .value as dio.Options; + return Future.value( + dio.Response>( + data: { + "data": {}, + }, + statusCode: 200, + requestOptions: dio.RequestOptions( + path: path, + headers: options.headers, + extra: options.extra, + ), + ), + ); + }, + ); + + await execute( + Request( + operation: Operation( + document: parseString("query MyQuery {}"), + ), + variables: const {"i": 12}, + context: Context.fromList( + const [ + DioExtraContext( + extra: { + "foo": "bar", + }, + ), + ], + ), + ), + ).first; + + verify( + client.post( + any, + data: anyNamed("data"), + options: argThat( + predicate((dio.Options o) => o.extEqual(dio.Options( + responseType: dio.ResponseType.json, + headers: { + dio.Headers.contentTypeHeader: dio.Headers.jsonContentType, + dio.Headers.acceptHeader: "*/*", + }, + extra: { + "foo": "bar", + }, + ))), + named: "options", + ), + ), + ).called(1); + }); + test("adds default headers", () async { final client = MockDio(); final link = DioLink(